Pwnable

Assembly Handray

건 Geon 2021. 8. 24. 22:16

i fu로 출력한 바이너리의 함수목록

대충보니 main에서 func 함수를 호출하는구조일듯

main함수의 어셈블리코드

main함수의 0x80484bd에 bp를 걸고 임의로 66을 입력하고 ni를 2번 진행한결과 scanf함수가 완전히 정리되고 리턴값(입력값)66이 EAX에 들어감.

그리고 바로 push eax 하고 fun 함수를 호출하는데

Push ebp

mov ebp, esp 함수프롤로그를 수행하고

mov DWORD PTR [ebp-0x4], 0x1 -> int i = 1 로 변수를 선언해줌

그리고 점프하는걸로보아 반복문을 수행하는 for(int i = 1 정도로 예상할 수 있음

for문의 시작

그리고 한줄더 명령어를 실행했을때의 상태이다. jmp 명령어를통해 func+46 지점으로 이동하고
func+46에서는 cmp DWORD PTR [ebp-0x4], 0x9
jle 0x804847a 를 수행하는걸로보아

DWORD PTR [ebp-0x4] = 1 과 9를 비교해서 작거나 같으면 점프하는것을 알 수 있다 즉

for(int i = 1; i <= 9; 까지 확인.

printf함수 매개변수 전달 과정 

그다음으로 진행했더니
push eax

push DWORD PTR [ebp-0x4]

push DOWRD PTR [ebp+0x8]

push 0x8048560

call printf
를 확인할 수 있다.

push한 4개가 바로 printf함수의 매개변수로 들어간다는것을 알 수 있다.

각 주소의 값을 확인해보면

eax = 0x43 = 67

ebp-0x4 = 1

ebp+0x8 = 0x43 = 67

0x8048560 = "%d * %d = %d\n"

이라는것을 확인할 수 있다. 즉

printf("%d * %d = %d\n", 67, 1, 67) ---> 출력할 문자열, scanf함수 입력값(67), for문의 i값(1), 둘을 곱한값

for문 첫 출력

call printf 에서 ni한결과 예상대로 67 * 1 = 64이 출력됨을 확인. 문자열끝에 \n이 붙어 다음출력은 아랫줄에 붙을것으로 예상할 수 있다.

printf함수가 종료된 후 분기문

printf 함수가 종료되고나서 add esp,0x10 으로 스택을 정리했고
add DWORD PTR[ebp-0x4] 에 있는 1값을 1 증가시켜주는것을 확인함 으로써
for(int i = 1; i <= 9; i++){

printf("%d * %d = %d\n", num, i, num*i)

}

이런형태의 for문이라는 것을 알 수 있다.

그다음 cmp jle 이후에는 예상대로

for문의 2번째 출력 확인

이렇게 출력되는것을 확인하였다.

for문의 마지막까지 진행한 결과

for문의 마지막 분기문

이렇게 i = 0xa = 10이 되었고 cmp와 jle에서 점프를 하지않고 nop leave ret 으로 func 함수가 종료됨을 알 수 있다.

func 종료 직후

func 함수가 종료된 후 main+39인 0x80484c9로 돌아온 상태로 add esp,0x4로 스택을 정리하고(매개변수 num) eax에 0을 넣고 함수가 종료되는것으로 보아 다음코드는 return 0; 인 것을 알 수 있다.

#include<stdio.h>
void function(int num){
    for(int i = 1; i <= 9; i++){
        printf("%d * %d = %d\n", num, i, num*i);
    }
}
int main(){
    int num;
    scanf("%d", &num);
    function(num);
    return 0;
}