리버싱 기초 -함수 호출 규약

악성코드 및 포렌식|2021. 3. 6. 10:32

main함수에서 sum이라는 함수를 호출하게될때!!!!!!!

 

 

call을 하는 순간에 이곳으로 가게되고

 

push ebp            ebp 를 넣는다

mov ebp, esp       esp의 값을 ebp에 넣습니다 

push ecx             ecx를 넣는다

mov eax, [ebp+arg_0]    ebp로부터 0(그냥 의미)번째의 argment를 가져오고  (a를 가져오는것) eax에 옮기고

add eax,  [ebp+arg_4]   ebp로부터 4번째의 argment를 가져오고 (b를 가져오는것) eax와 더한다

 

결국 eax 는 7이된다 왜냐하면

 

 

a,b에 3,4를 넣게되면

실제로는 

ebp  8바이트 만큼 떨어진곳이 a

ebp  12바이트만큼 떨어진곳이  b

만약 ebp

arg_0 과 arg_4 로 나타나 있지만 실제로는 ebp 에서 +8바이트 , ebp에서 +12 바이트 인것이다

저위에 하나하나 마다 4바이트이기때문입니다.

 

 

mov [ebp+var_4], eax   eax 가 7이됬으므로 var_4번으로 옮기고

mov eax, [ebp+var_4]   var_4 에-> 다시 eax로 옮기는 작업을한다 똑같은걸 두번하네

 

 

똑같은 것을 두번하는 이유가 맨위 그림 c언어중간에 지역변수를 저장해서 그렇다

a+b가 지금 eax와 같은의미인데 eax-> ebp+var_4에 저장을하고 

ebp+var_4-> eax에 다시 저장을 하는데 리턴을 하기직전에 eax 에 7이라는 숫자를 저장하는것.

 

 

결론 main함수에서 sum함수를 호출하게될때

ebp를 넣고 esb의값을 ebp에 넣고 ecx를 넣고 a=3,b=4라고넣을때

ebp에서 8바이트 떨어진 a를 eax에 저장해서 3이라 되고

ebp에서 12바이트 떨어진 b를 아까 eax에 저장한 3이라는 값에 4를 더해 eax는 7이된다

그리고

eax=7 이니까 이값을 [ebp+var_4]라는 곳에 넣어두고 다시  

return하기전에 [ebp+var_4] 이곳에서 -> eax로 저장을하게된다

 

그리고 ebp를저장을 하는 이유가 다끝나고 main함수로 돌아가려면

이거를 저장했던것을 꺼내야되기때문에 여기로 ebp로 되돌리기 위해서 저장해놓고

새로운 스택프레임을 만들기위해서 ebp의 위치를 esp위치로 같은곳에 설정하게 됩니다.

 

 

 

 

 

 

함수에필로그는 main함수에서 sum함수를 불러왔다가

함수가 끝나면 다시 돌아가려면 그전에 우리가 개짓거리했던 스택은 필요가없으니까

 

mov esp, ebp                ebp의 값을 esp의 값으로 돌리면 다시 main함수 밑바닥으로 떨어짐!!!!!!

                            

처음에 맨위 프롤로그에서 push ebp 하고

mov ebp, esp를 해서 메인함수ebp 를 맨위로 올렸었는데

그과정을 거꾸로 한다고생각하면된다.

그래서 main 함수 밑바닥으로 값이 다시 esp에게 전달이 됬으니까 떨어진다. 

 

pop ebp           를 하면 스택데이터를 ebp에 넣는다

 

그래서 메인함수ebp는 다시 돌아오게된다. 

 

 

 

 

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

 

cdecl

 

 

 

 

 

여기서 add esp, 8 의 뜻은

esp는 언제든 변경이가능한 데이터

esp위에 있는 데이터는 쓰레기니까 esp를 내리면 그값들은 쓰레기가된다

현재 a=4바이트 b=4바이트니까  

 

그래서 8바이트만큼 더하게되면 esp의 값이 내려오게됩니다

그래서 마치없는 것처럼 만들수 있다.

 

 

call다음에 add esp, 8 이런식으로 나오면

cdecl이라는 거라고 생각하면된다.

 

그리고 push 문이 2개

4바이트 파라미터 두개의 파라미터 2와 1을 가져다가 사용하는 구나~

 

그리고 cdecl 을 사용해서 스택을 정리하는 구나~~~~라고 생각하면됩니다

 

 

 

 

 

 

 

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

 

 

stdcall

 

 

 

 

 

win32 API 에서 사용하는거

특별한 특징이 retn 8 이 붙는다.

그의미는

파라미터를 총8바이트만큼 사용했어~~라고 전달하는거

 

나리턴했어~~~라고하고 밑에있는 a,b 8바이트 데이터도 같이 삭제하는것

 

그래서  call 밑에 위에 했던것처럼 add esp, 8 같은

 

밑에 스택을 정리하는 것이 없다.

 

 

 

 

여기서 push 5

이것은 숫자5

push winexec.00e92100

이것은 주소고

그리고 주소인 00e92100  은  notepad.exe라고 써있는것입니다.

그래서 8바이트 (숫자5와,주소)

 

winExec에는 최종적으로는 notepad에대한 string이들어가고

sw_show를 나타내는 숫자 5가 들어갑니다

 

 

 

그리고 맨끝에 보면 

retn 8은

 

우리가 아까 str (notepad.exe에 대한것) 과 숫자 5 두개를 합치면 8바이트니까

이함수를 사용하기위해 호출했던 스택들 8바이트를 정리해달라~~

 

 

 

 

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

 

 

fastcall

 

 

 

 

 

 

메모리를 사용하지않는다

레지스터에 잠깐 저장해서 사용하는것입니다.

 

ecx와edx를 사용하는 것을볼수있고

 

call하기직전에 push하는 내용도 볼수가없고

edx와 ecx를 통해서 함수를 호출한다.

 

 

그래서 fastcall 규약 함수는

 

함수 호출전에 edx 와 ecx 레지스터에 값을 넣는 것을 볼때 짐작이 가능하다!!!!

 

 

 

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

 

 

thiscall

 

 

 

 

 

 

 

 

this 포인터를 ecx에 전달하는 특징을 가진다고 생각하면된다.

 

 

 

 

 

ecx 에 어떤 데이터를 담고있는것을 알수있다.

 

 

 

이렇게 데이터를 넘기는 것을 알수있다.

 

 

 

댓글()