2017. 11. 3. 19:56ㆍSystemHacking/Assembly
gdb 명령어 관련 http://itsaessak.tistory.com/78
#include <stdio.h> char *passwoprd = "th3p4ssw0rd"; int main(){ // 1036byte char buffer[1024]; // ebp- 1024 char *p; // ebp-1028 char *q; // ebp-1032 int length; // ebp-1036 printf("Input password: "); // char *fgets( char *s, int size, FILE *stream); fgets(buffer,1024,stdin); if ( length > 0 && buffer[length-1] == '\n' ){ buffer[length-1] = 0 ; } while ( *p != 0 && *q != 0 && *p = *q ){ p++; q++; } if ( *p == 0 && *q == 0 ){ printf("Congratulations! You got it!\n"); }else { printf("Oops! wrong pasword! :-p\n"); } return 0; }
|
# gdb (gdb) file password1 (gdb) set disassembly-flavor intel (gdb) disas main Dump of assembler code for function main: 0x8048460 <main>: push %ebp 0x8048461 <main+1>: mov %ebp,%esp 0x8048463 <main+3>: sub %esp,0x40c ; 지역변수 1036byte 할당 0x8048469 <main+9>: push 0x80485b0 0x804846e <main+14>: call 0x8048398 <printf> ; printf( 0x80485b0 ) 0x8048473 <main+19>: add %esp,4 => b *0x8048469 x/s 0x80485b0 "Input Password" 0x8048476 <main+22>: mov %eax,%ds:0x80496f0 0x804847b <main+27>: push %eax 0x804847c <main+28>: push 0x400 0x8048481 <main+33>: lea %eax,[%ebp-1024] 0x8048487 <main+39>: push %eax 0x8048488 <main+40>: call 0x8048368 <fgets> ; fgets(buffer,1024,stdin) 0x804848d <main+45>: add %esp,12 0x8048490 <main+48>: lea %eax,[%ebp-1024] 0x8048496 <main+54>: push %eax 0x8048497 <main+55>: call 0x8048378 <strlen> ; length = strlen(buffer) 0x804849c <main+60>: add %esp,4 0x804849f <main+63>: mov DWORD PTR [%ebp-1036],%eax ; %eax에 length 0x80484a5 <main+69>: cmp DWORD PTR [%ebp-1036],0 0x80484ac <main+76>: jle 0x80484d2 <main+114> 0x80484ae <main+78>: mov %eax,DWORD PTR [%ebp-1036] 0x80484b4 <main+84>: dec %eax ; len = len - 1 0x80484b5 <main+85>: lea %edx,[%ebp-1024] ; buffer 0x80484bb <main+91>: cmp BYTE PTR [%eax+%edx],0xa ; 뉴라인체크 0x80484bf <main+95>: jne 0x80484d2 <main+114> 0x80484c1 <main+97>: mov %eax,DWORD PTR [%ebp-1036] 0x80484c7 <main+103>: dec %eax 0x80484c8 <main+104>: lea %edx,[%ebp-1024] 0x80484ce <main+110>: mov BYTE PTR [%eax+%edx],0x0 ; 뉴라인 제거 0x80484d2 <main+114>: lea %ecx,[%ebp-1024] ; buffer시작주소 0x80484d8 <main+120>: mov DWORD PTR [%ebp-1028],%ecx ; *p = buffer 0x80484de <main+126>: mov DWORD PTR [%ebp-1032],0x8049608 ; *q = 주소 => 무슨 주소인지 확인 (gdb) b *0x80484de Breakpoint 1 at 0x80484de (gdb) run Starting program: /root/password1 'Input password: abcd Breakpoint 1, 0x80484de in main () (gdb) x/s 0x8049608 0x8049608 <password>: "th3p4ssw0rd" 0x80484e8 <main+136>: mov %eax,DWORD PTR [%ebp-1028] ; $eax = *p 0x80484ee <main+142>: cmp BYTE PTR [%eax],0x0 ; *p 와 0 비교 0x80484f1 <main+145>: je 0x8048512 <main+178> ; *p값이 0이라면 점프 0x80484f3 <main+147>: mov %eax,DWORD PTR [%ebp-1032] ; 0이 아니라면 비밀번호의 주소를 $eax register에 저장 0x80484f9 <main+153>: cmp BYTE PTR [%eax],0x0 ; 패스워드주소의 마지막+1 부분이라면 0x80484fc <main+156>: je 0x8048512 <main+178> ; 점프 0x80484fe <main+158>: mov %eax,DWORD PTR [%ebp-1028] ; *p 0x8048504 <main+164>: mov %edx,DWORD PTR [%ebp-1032] ; *q 0x804850a <main+170>: mov %al,BYTE PTR [%eax] ; buffer의 한글자를 가져온다 0x804850c <main+172>: cmp %al,BYTE PTR [%edx] ; 패스워드와 비교 0x804850e <main+174>: je 0x8048514 <main+180> ; 같으면 점프 0x8048510 <main+176>: jmp 0x8048512 <main+178> 0x8048512 <main+178>: jmp 0x8048522 <main+194> ; 다음 문자를 비교하기 위해 포인터를 이동시킨다 0x8048514 <main+180>: inc DWORD PTR [%ebp-1028] ; p++ 0x804851a <main+186>: inc DWORD PTR [%ebp-1032] ; q++ 0x8048520 <main+192>: jmp 0x80484e8 <main+136> 0x8048522 <main+194>: mov %eax,DWORD PTR [%ebp-1028] ; 포인터 p 가 0x8048528 <main+200>: cmp BYTE PTR [%eax],0x0 ; 입력한 문자열의 끝을 가리키고있는지 확인 0x804852b <main+203>: jne 0x8048547 <main+231> ; 끝이 아니면, 실패 문장 출력 0x804852d <main+205>: mov %eax,DWORD PTR [%ebp-1032] ; 포인터 q가 0x8048533 <main+211>: cmp BYTE PTR [%eax],0x0 ; 파일의 password 끝을 가리키고 있는지 확인 0x8048536 <main+214>: jne 0x8048547 <main+231> ; 끝이 아니면, 실패 문장 출력 0x8048538 <main+216>: push 0x80485c1 ; 성공 ! 0x804853d <main+221>: call 0x8048398 <printf> 0x8048542 <main+226>: add %esp,4 => (gdb) x/s 0x80485c1 0x80485c1 <_IO_stdin_used+21>: "Congratulations! You got it!\n" 0x8048545 <main+229>: jmp 0x8048554 <main+244> ; 실패 ! 0x8048547 <main+231>: push 0x80485df 0x804854c <main+236>: call 0x8048398 <printf> 0x8048551 <main+241>: add %esp,4 => (gdb) x/s 0x80485df 0x80485df <_IO_stdin_used+51>: "Oops! wrong password! :-P\n" 0x8048554 <main+244>: xor %eax,%eax 0x8048556 <main+246>: jmp 0x8048558 <main+248> 0x8048558 <main+248>: leave 0x8048559 <main+249>: ret |
[ 실행결과 ]
'SystemHacking > Assembly' 카테고리의 다른 글
[13] 어셈블리 cat구현 ( SystemCall ) (0) | 2017.11.01 |
---|---|
[12] 어셈블리 mkdir 구현 ( SystemCall ) (0) | 2017.10.31 |
[11] 어셈블리 argc, argv 이해하기 (0) | 2017.10.30 |
[10] 어셈블리 스택메모리를 이용한 변수 저장 및 사용 (0) | 2017.10.27 |
[9] 어셈블리 스택 메모리를 이용한 간단한 덧셈 ( leave, ret, call ) (0) | 2017.10.27 |