본문 바로가기

Let's Study/Hacking Technique

Assembly-> C Handray(1)

시스템해킹, 리버싱을 시작하기에 앞서, 어셈을 C로 바꾸고 C를 어셈으로 바꿀 수 있는 능력은 정말 중요하다고 생각합니다.


리버싱이든 시스템이든 우리는 어셈블리어를 무조건 마주치고 분석해야하는 입장이기 때문입니다.

(물론 안드로이드 리버싱을 할 때에는 달빅코드로 되어있어서 어셈블리어와는 약간 다른 개념이지만요.)


문제를 많이 풀어보는 것도 좋은데 전 그전에 C언어로 어떤 코드든 컴파일해서 그걸 디버거로 역분석하여 


핸드레이로 다시 복원하는 연습을 하셨으면 좋겠다고 생각합니다. 짧게는 한달, 많게는 두달까지요. 이 기준은 여러분이 적당하다고 느낄때까지 입니다. 복원하는 연습을 꾸준히 하다보면 어셈블리어코드가 자연스레 눈에 들어오는데, 그정도면 성공입니다.


예를 들어서, 


간단한 코드가 있는데 gdb로 열어보면



이런식으로 열립니다. 

mov DWORD PTR [esp+0x18], 0xa

mov DWORD PTR [esp+0x1c], 0x14

에서 mov a, b는 a = b와 같은 의미로 해석하시면 됩니다.


그렇게되면 [esp + 0x18]  = 10, [esp + 0x1c] = 20 이 되는데, 편의상 esp + 0x18은 v1, esp + 0x1c는 v2라고 정의합니다.


int v1 = 10;

int v2 = 20;


그리고나선, mov eax, DWORD PTR [esp + 0x1c] 를 연산하는데, 이것은 eax = v2;  가 될 것이고

*어셈블리어에서 eax, ebx, ecx, edx는 일단 값을 넣었다 뺐다 하는 변수 정도로만 알아두시면 됩니다.


mov DWORD PTR [esp+0x4], eax,  이것은 뒤에 나올 add함수의 두번째 인자로 eax(v2)를 넣겠다는 것을 의미합니다.

add(??, v2);


마찬가지로

mov eax, DWORD PTR [esp + 0x18]

eax = v1;

mov DWORD PTR [esp], eax

add(v1, v2);


이 밑에는 mov DWORD PTR [esp + 0x4], eax가 있는데 보통 함수가 실행되고 나면 그 함수의 리턴값은 eax에 들어갑니다. 그러므로 여기서 말하는 eax는 add함수가 됩니다. 그리고 esp + 0x4는 printf함수의 두번째 인자가 되겠죠?


printf("", add(v1, v2));


mov DWORD PTR [esp], 0x8048500

이것은 0x8048500의 주소에 들어있는 값을 printf의 첫번째 인자에 넣습니다.


x/s 0x8048500 명령어를 이용하여 어떤 값이 들어있는지 확인해보면, %d\n 입니다.

printf("%d\n", add(v1, v2));



이런식으로 handray를 차근차근 진행하는 건데, 이것은 기본적인 핸드레이고 더 나아가 구조체와 포인터, 함수포인터를 이용한 바이너리를 역분석하여 핸드레이를 하는게 좋을 것 같습니다.





핸드레이를 할 시에 알아야 할 기본적인 사항을 몇가지 적어봅니다. 

제 기준으로 적은 것이므로 다른 생각이 있으신 분은 저에게 말씀해주세요.



*ebp + 8 이상의 값은 함수의 인자를 나타냅니다.

예를 들어, int main(int argc, char *argv[])는 argc = ebp + 0x8, argv[1] = ebp + 0xc, 이렇게 4바이트씩 증가합니다.


*그리고 ebp - 0x8, esp + 0x8 이상의 값은 지역변수입니다. 숫자가 높을수록 가장 먼저 선언된 변수입니다.

*ds:0xXXXXXXXX, ds가 붙은건 전역변수입니다.


*mov x, y는 간단하게 x = y로 생각하시면 편하고 lea x, [y]는 mov x, y와 같다고 보시면 됩니다. ([]는 포인터와 비슷합니다.)


*인자 앞에 BYTE, WORD, DWORD가 붙은건 각각 1, 2, 4 byte를 의미합니다.


*call x는 x라는 함수로 넘어가겠다는 뜻인데 call 위에 보시면 [esp], [esp + 0x4], [esp + 0x8] ...가 보일 겁니다.

이건 각각 함수의 첫번째, 두번째, 세번째 인자를 뜻합니다.


*함수프롤로그 밑에 sub x가 있다는 것은 x만큼 지역변수나 함수를 선언했다는 의미입니다.


*for문의 전형적인 문장

인자를 초기화하고 (mov ebp - 0x8, 0x0)

인자를 비교하며 (cmp ebp - 0x8, 0x9)

명령어를 쭉 실행하다가 코드의 끝부분에서 인자에 대한 연산을 수행합니다. (add ebp - 0x8, 0x1)