리버싱 기초 -어셈블리 명령어와 함수 호출 구조

악성코드 및 포렌식|2021. 3. 5. 21:28

위의 그림은

 

어셈블리로 c언어의 plus 처럼 만든것이다

 

esp는 스택 이라고 까먹지말고

[esp+8] 과 [esp+4 ]는  스택 영역에서

데이터를  8바이트와 4바이트를 꺼내옵니다

근데 a와 b라는 데이터를 꺼내오는것입니다

그리고 

a와b를

edx와 ebx로 (다목적 ,더미값 특정한 목적이없는 레지스터)에 데이터를 임시로 저장하고

 

add edx, ebx 는

 

edx에 ebx를 더해라고 생각한다 뒤에있는것을 앞에 더한다.

 

ebx에 4를 넣고 edx에 3을 넣는다고했을때

 

add edx, ebx의 각각의값은

 

ebx = 4로 변하지가 않는 대신에

edx = 3+4로 7이됩니다 

 

 

오른쪽에있는것을 왼쪽에 저장한다고 생각하기 근데 add가되면 앞에는 edx=7 뒤에 ebx=4

 

 

그리고

 

mov eax, edx는

 

아까 3+4 한게 7인데

오른쪽에 있는것을 왼쪽에저장하는 것인데

mov 니까 edx->eax 옮겨적어서

eax도 7이된다

 

eax는

리턴값을 저장한다 즉 결과값을 저장한다.

 

 

 

=======================================

 

 

 

push

스택에 데이터를 넣는다 

 

 

POP

스택안에있는 데이터를 꺼낸다

 

 

 

데이터를 넣고 빼고

 

 

PUSHAD 는

 

모든레지스터에있는 값을 몽땅넣겟다

 

 

 

 

POPAD는

 

스택에있는 모든레지스터를 모두꺼내겠다~

 

 

 

위의 그림의 A와 D가 AD여서

모든레지스터를 포함!

 

 

 

mov는

 

source를 가져옴 옮긴다생각하기

mov a, b처럼

b의데이터를 a로 옮겨라~~~

 

 

 

 

 

LEA는

 

b가 가르키고 있는 데이터를 가져와라~~~ 포인터개념!!!!

 

 

 

ADD 

 

더하기

 

 

 

 

SUB

 

SUB 3, 4는

3에서 4를 빼라!! 해서 -1이된다

 

 

 

 

INT는

 

인터럽트명령

CPU보고 잠깐정지해라!!!

 

 

 

 

 

 

CALL

 

함수를 호출하는 의미!

메모리를 호출시키는 의미

앞에서 Plus란 함수를 봤는데 -> 메모리주소에위치해있다

 

메모리주소를 0x401000라고할떄

call 0x401000 처럼 호출하면된다.

 

컴파일할때는 symbolic 이사라진다 즉 plus가 보이지가않는데

이떄는 메모리주소로 나옵니다

 

call 0x401000

 

 

만약 존재하면 plus 가 보인다

call plus

 

call 0x401000

call plus 

 

이렇게 예시를 들게되면

0x401000로 점프해라 

 

Plus 라는 함수로 점프해라! 라고 생각하면됩니다

함수 호출과 관련된 명령어가 call~!

 

 

 

 

 

 

INC, DEC(i++, i--)

 

위의 그림은

inc EAX 

dec EAX라고 생각하자

 

EAX에있는 데이터를 5라고 가정할때 ++ 를하면 한번더해줘라 

즉 6이된다

하지만 

EAX에있는 데이터를 6이됬는데 -- 를하면 한번 빼줘라

즉 다시 5가 된다

 

 

 

 

 

 

AND, OR, XOR

 

의미는 bit 연산

 

 

x<8 (and 또는 or ) -1<x

 

and 는 두가지가 모두 참일때!

1 and 1 은 참이다

1 and -2 은 뒤에가 잘못됬으니 거짓

 

or 은 

0 or -2 -> 참

둘중 하나만 참이면 참

 

 

 

 

 

NOP

 

no operation의 약자이다

실행하지 않는 다는 뜻이다.

NOP을 만나면 cpu는 아무것도 하지않고 다음단계로 넘어가게됩니다

 

 

 

 

CMP

 

compare

비교하는 명령어 

죽 cmp eax, 5 는

eax와 5를 비교해라~~

 

 

 

 

CMP , JMP

 

이것과 비교해서 맞다면 ~~~로 점프해라~~~~~

를 이용해서

CMP 와 JMP는 같이 많이등장을한다

 

 

 

=============================================================

 

 

 

 

 

스택 프레임!

 

 

 

중간에 main함수가있으면 중간에 main함수를 호출한다

main함수도 하나의스택을 가집니다

 

 

 

 

 

 

근데

plus라는 함수를 만약 main함수 안에있을때

실행을하게되면 다른별도의 공간에 스택을 새로 만드는게 아니라

 

스택을 잠깐 닫아놓고 plus 라는 함수의 스택을 위로올립니다.

 

이것을 하나의 스택 프레임 이라고 합니다

 

스택프레임!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

다른함수가 또실행되면 저기위에 또 스택을 닫아놓고 다시 위로 올린다!

 

 

 

 

 

 

 

========================================

 

 

 

함수 프롤로그와 에필로그가 존재하는데

 

 

 

함수 프롤로그는

스택을 만들어주는 역할!!!!

 

 

함수 에필로그는

함수를 삭제하는 역할

 

 

 

함수 프롤로그는 메인함수가 있다고 가정했을때

main을 가르키는 ebp가 제일 하단을 가르키고

esp가 가장윗부분을 가르킵니다

 

 

위그림은 

 

어떤함수를 호출했다고 가정했을때

스택을 새로만들어야하는데

ebp가 필요하고 esp는 바꿔줄필요가없다.

그이유는 esp는 스택이 생성될때 그자리에 생성됬지때문이다.  

(main 함수의 스택이있었을때

제일 윗부분 가르키는게 esp이기때문에

그자리에 push를 호출하기위한 스택이 생성되기때문에 esp(main함수에 제일끝부분의)자리에 스택이생성되서 )

 

 

만약 main을 가르키던 ebp에

스택이 생성된 젤하단의 값을 넣게되면

밑에 main을 가르키던 ebp가 사라진다

그래서

 

 

 

 

스택이 생성되자마자 

 

 

push ebp 

 

스택 생성된 곳에 ebp를 삽입

 

 

 

mov ebp , esp 

 

esp값을 ebp 에 저장

아까 위에서 push ebp 즉 스택생성된 곳에 ebp를 삽입했는데

esp가 거기위치의 값이므로

esp의 값을 ebp로 옮기고나서

 

 

sub esp, 50h

 

sub는 줄이다라는 뜻이므로

sub esp 50h 는

50h 만큼 esp 를 줄이는 것인데

값을 줄이면 위치가올라간다

 

 

 

               

 

근데 위치가 올라가면

esp자리에있던 새로생긴 스택에 제일 밑에부분에 esp값을받아

ebp가 존재해지게되고

우리가 esp의 값을 50h만큼 줄이게되면 esp가 맨위로올라가니까

 

ebp와 esp사이의 빈공간이 발생하게되고 그사이에는

 

push함수가 들어올수있는것이다. 

 

 

 

 

 

결론

 

main함수위에 새로만들어진 push함수를 위한 스택을 만들기위해 ebp를 삽입 ->

esp의 값을-> ebp로 -> esp의 값을 -> -50h해서  push 함수를위한 공간을 만든다

 

 

 

 

===========================================================

 

 

 

 

 

 

 

 

인자를 0x37 0x38 0x39 인자를 3개 전달하려고하는데

 

plus (3, 4) 는 7로 전달을합니다

근데이거는 스택으로 전달을 한다고생각하면됩니다

main함수가있고

만약

main함수가 plus함수를 호출한다하면

하기 직전에

3과4를 저장해둡니다

 

 

 

plus (3, 4)은

 

push 4

push 3

call plus

라고 생각하면됩니다.

 

 

 

 

 

 

 

 

 

 

 

 

댓글()