mmap()호출은 fd가 가리키는 객체를 파일에서 offset바이트 지점을 기준으로 len 바이트만큼 메모리에 매핑하도록 커널에 요청한다.
addr을 넘길 경우, 메모리에서 해당 시작 주소를 선호한다고 커널에게 알린다. 접근 권한은 prot에 지정하고, 추가적인 동작 방식은 flag에 지정한다.
#include <sys/mman.h>
void * mmap(void * addr, size_t len, int prot, int flags, int fd, off_t offset);
* return 값 : 맵핑이 시작하는 실제 메모리 주소
void* : void 포인터 = 범용 포인터. 자료형이 정해지지 않았기 때문에 어떤 자료형으로 된 포인터든 모두 저장할 수 있음. 즉, 직접 자료형을 변환해주지 않아도 암시적으로 자료형이 변환되는 방식임.
addr : 커널에게 파일을 어디에 맵피하면 좋을지 제안(보통 0사용)
len : 맵핑시킬 메모리 영역의 길이
prot : 맵핑에 원하는 메모리 보호 정책(PROT_READ,PROT_WRITE,PROT_EXEC,PROT_NONE)
flags : 맵핑 유형과 동작 구성 요소
(MAP_FIXED,MAP_SHARED,MAP_PRIVATE)
offset : 맵핑할 때 len의 시작점을 지정
mmap(0,0x4000,7,MAP_PRIVATE|MAP_ANONYMOUS, -1 ,0)
여기서
addr : 0
len : 0x4000
prot : 7
flags : MAP_PRIVATE|MAP_ANONYMOUS
fd : -1
offset : 0
rdtsc함수는 시간 측정 하는 함수.
printf("dest addrest : %p\n", dest)
를 넣고 돌려본다.
fast함수에서 어셈블리 쪽이 중요함.
16바이트씩 정렬되어 있어야 한다는게 포인트
<<이 부분 좀 더 자세히 서칭
아무튼 16바이트씩 정렬되어야 한다는 점을 기억하고
dest 주소를 보면, 16으로 나누어 떨어지지 않는 구간이 존재한다.
처음에 범위의 최솟값으로 넣었을 경우(8,16,32...)
64를 넣었을 때 16으로 나누어 떨어지지 않는 주소가 생겨,
다음 구간에서 fast함수를 실행할 수 없다.
그래서 experiment 5에서 멈추는것
64 주소 부분을 16으로 나누면 0.5가 나오는데, 8바이트가 부족하다는 말이다. 따라서 8바이트를 더해주면 된다.
64대신 72를 넣으면 성공한다.
같은 방식으로 쭉..
64부분부터 계속해서 8을 더해서 넣어주면 플래그를 획득할 수 있다.
애매한 부분은 movntps와 movdqa명령어..정확히 어떤 부분에서 세폴이 뜨는건지 잘 모르겠다.
메인함수 실행되는 구간을 보면,
이전 실험에서 부족한 값을 전달(버퍼사이즈)하면
지금 실험에서 dest address가 16으로 나누어떨어지지 않도록 설정된다.
이건 왜그런가
dest = malloc(size)니까
내가 입력해주는 사이즈만큼 동적할당하는 건 맞음.
movntps와 movdqa가 16바이트 바운더리(경계)를 기준으로 하기 때문인가? ㅇㅇ
movdqa : Move Aligned Double Quadword
MOVDQA dest src : Aligned double quadword를 src에서 dest로 이동한다.
Moves a double quadword from the source operand (second operand) to the destination operand (first operand). This instruction can be used to move a double quadword to and from an XMM register and a 128-bit memory location, or between two XMM registers. When the source or destination operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.
마지막 문장, srcdest가 memory operand이면, 반드시 16바이트 경계에 aligned되어야 한다. = 반드시 16바이트 단위로 쪼개져야(정렬되어야) 한다.
movntps : Move Aligned Four Packed Single-FP Non Temporal
Moves the packed single-precision floating-point values in the source operand (second operand) to the destination operand (first operand) using a non-temporal hint to prevent caching of the data during the write to memory. The source operand is an XMM register, YMM register or ZMM register, which is assumed to contain packed single-precision, floating-pointing. The destination operand is a 128-bit, 256-bit or 512-bit memory location. The memory operand must be aligned on a 16-byte (128-bit version), 32-byte (VEX.256 encoded version) or 64-byte (EVEX.512 encoded version) boundary otherwise a general-protection exception (#GP) will be generated.
마찬가지로, memory operand는 반드시 16바이트 바운더리로 aligned되어야 한다. = 16바이트 단위로 쪼개져야 한다.
https://www.felixcloutier.com/x86/movntps
http://www.jaist.ac.jp/iscenter-new/mpc/altix/altixdata/opt/intel/vtune/doc/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh/vc183.htm
flag : 1_w4nn4_br34K_th3_m3m0ry_4lignm3nt
'System Hacking' 카테고리의 다른 글
[pwnable.kr] blukat (0) | 2020.01.09 |
---|---|
[pwnable.kr] asm (0) | 2020.01.09 |
[pwnable.kr] uaf (0) | 2020.01.09 |
[pwnable.kr] cmd2 (0) | 2020.01.09 |
[pwnable.kr] cmd1 (0) | 2020.01.09 |