본문 바로가기
HACKING/SYSTEM

어셈블리 핸드레이 1

by pharmerci 2021. 9. 7.
728x90

2주차 숙제로 핸드레이를 직접 해보는 숙제를 내주셨다.

 

 

 

 

먼저 gdb-peda를 실행하여 어떤 함수가 있는지 i fu 명령어로 살펴보았다.

 

func함수와 main함수가 있어요!!

 

하나씩 어떤 함수인지 살펴보자.

 

 

 

 

 

 

일단 메인함수를 어셈블리어로 확인해보자.

 

push ebp

mov ebp,esp

 

여기는 함수의 프롤로그 부분인 듯 하고

 

mov DWORD PTR [ebp-0x4], 0x0

여기 부분은 ebp-0x4의 데이터 4바이트를 참조하여 여기에 0을 넣어라! 이런 뜻인 것 같다.

 

lea eax, [ebp-0x4]

이거는 ebp-0x4에 저장된 주소를 eax에 저장하라는 의미이다.

 

그러고 나서 eax 그니까 여기서 값은 0이고..? 이걸 push하고 %d를 push한 것은

 

내 생각에는 scanf("%d", eax변수); 이런 것을 만들어 주기 위함이라고 생각한다.

그러니까 main+22 에서 scanf 함수를 불러오는 것이지!

 

그러고 func함수를 부르기 전에 eax를 push하는 것은

 

func(eax변수);

이걸 하기 위함일 듯 하다.

 

그러고 나서는 스택을 정리하고 함수를 끝내는 것 같다.

 

 

이제 func 함수에서 어떠한 일이 벌어지는지 알아보아야 한다.

 

 

 

 

 

pd 명령어를 이용하여 func 함수를 알아보자

 

마찬가지로

push ebp

mov ebp,esp

 

함수의 프롤로그 부분이고

 

mov DWORD PTR [ebp-0x4], 0x1

ebp-0x4 여기 데이터 4바이트를 참조하여 여기에 1을 넣어라 이런 뜻이다.

 

그리고 jmp func+46을 보면, 반복문이 있구나 하고 판단할 수 있다.

 

func+46을 살펴보니 cmp DWORD PTR [ebp-0x4], 0x9

 

두 값을 비교하라는 뜻이다.

 

그 다음에 jle func+15 이렇게 나와있다.

jle는 앞에 두 수를 비교한 것에서 앞의 수가 작거나 같으면 func+15로 가라는 뜻이다.

 

그러니까 우리는 for(i=1; i<=9; 이런식으로 진행되는구나! 라는 것을 알 수 있다.

 

 

 

그러면 func+15로 넘어가서,

 

mov eax, DWORD PTR [ebp+0x8]

이거는 ebp+0x8에 있는 값을 eax에 넣으라는 의미이고

 

imul eax, DWORD PTR [ebp-0x4]

이거는 두 수를 곱하라는 의미이다. eax는 아까 메인 함수에서 인자로 넘겨준 값이고

뒷쪽에 있는 값은 처음에는 1을 의미한다. 반복문이 진행됨에 따라 어떨 지는 모르겠으나!?

 

그리고 eax, DWORD PTR [ebp-0x4], DWORD PTR [ebp+0x8]를 하나씩 push 하는데

이 값은 인자로 전달받은 값 * 반복문에서 있는 수(1~9)한 값, 반복문의 수(1~9), 인자로 전달받은 값

 

이런 구성인 듯 하다.

 

그리고 마지막에 있는 push값은

 

 

 

 

 

 

브레이크 포인트를 걸고 한 명령어를 실행한 결과 %d * %d = %d\n의 틀임을 알 수 있다.

 

저것을 프린트 하는 것이다!!

 

그리고 func+42에서 반복문 돌려주는 값을 1씩 증가해주고 다시 비교를 통해 반복문이 반복된다.

 

 

 

 

그러니까 어셈블리어 함수를 분석해보면 

 

메인함수에서 입력 받기 - func함수에서 반복문 돌려서 입력받은 수를 1부터 9까지 곱한 수를 출력하기

 

이런 함수일 듯하다.

 

 

 

 

 

 

실행해보니 예상이 맞음!!

 

 

 

 

 

그래서 저렇게 c언어로 된 코드를 작성했고

 

 

 

 

 

컴파일을 하고(컴파일 안하고 엥 왜 안돼.. 이러고 있었음ㅜㅜ) 실행하면 원하는대로 잘 실행된다.

 

 


#include <stdio.h>

void func(int a){
for(int i=1;i<10;i++){
printf("%d * %d = %d\n",a,i,a*i);
}
}

int main(){

int a = 0;
scanf("%d",&a);

func(a);

}

 

정확한 정답의 소스코드는 이와 같은데,

 

내 코드와 가장 큰 차이는 printf 단계에서 바로 곱셈을 해준다는 점이다.

 

 

 

생각해보니 따로 곱셈에 대한 공간을 마련해주지 않았으니 변수를 따로 마련할 수 없기 때문에 저렇게 바로 곱셈을 프린트 할 때 해주어야 하는 것이었다..!!!!!!!!!

 

728x90