Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Основы Reverse Engineering

1,167 views

Published on

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Основы Reverse Engineering

  1. 1. Как выглядят функции?
  2. 2. void myfunc (void) { } myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret C++ ASM
  3. 3. void myfunc (void) { } void myfunc2 (void) { myfunc(); } myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret C++ ASM
  4. 4. Как распол a гаются Локальные переменные?
  5. 5. void myfunc (void) { int a=0x10; } myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov esp, ebp pop ebp ret C++ ASM
  6. 6. Что есть стековый фрейм?
  7. 7. Стековый фрейм myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret 0x00000000 0xFFFFFFFF ESP
  8. 8. Стековый фрейм myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret EBP (func2) 0x00000000 0xFFFFFFFF ESP
  9. 9. Стековый фрейм myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret 0x00000000 0xFFFFFFFF EBP (func2) ESP EBP
  10. 10. Стековый фрейм Return addr 0x00000000 0xFFFFFFFF myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret EBP (func2) ESP EBP
  11. 11. Стековый фрейм Return addr EBP (func) 0x00000000 0xFFFFFFFF myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret EBP (func2) ESP EBP
  12. 12. Стековый фрейм Return addr 0x00000000 0xFFFFFFFF myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret EBP (func) EBP (func2) ESP EBP
  13. 13. Стековый фрейм Return addr 0x00000000 0xFFFFFFFF myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret EBP (func) EBP (func2) ESP EBP
  14. 14. Стековый фрейм Return addr 0x00000000 0xFFFFFFFF myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret EBP (func2) ESP EBP
  15. 15. Стековый фрейм 0x00000000 0xFFFFFFFF myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret EBP (func2) ESP EBP
  16. 16. Стековый фрейм 0x00000000 0xFFFFFFFF myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret EBP (func2) ESP EBP
  17. 17. Стековый фрейм 0x00000000 0xFFFFFFFF myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp call myfunc mov esp, ebp pop ebp ret ESP
  18. 18. Как возвращается значение из функции?
  19. 19. int myfunc (void) { int a=0x10; return a; } myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] pop ebp ret C++ ASM
  20. 20. Стековый фрейм myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] mov esp, ebp pop ebp ret EBP v1.0 0x00000000 0xFFFFFFFF ESP EBP
  21. 21. Стековый фрейм myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] mov esp, ebp pop ebp ret EBP v1.0 0x00000000 0xFFFFFFFF ESP EBP
  22. 22. Стековый фрейм myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] mov esp, ebp pop ebp ret EBP v1.0 0x00000000 0xFFFFFFFF 0 x00000010 ESP EBP
  23. 23. Как передаются аргументы в функции?
  24. 24. int myfunc ( int b ) { int a=0x10; return a+b; } int myfunc2 (void) { myfunc(8); } myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] mov edx, [ebp+8] add eax, edx mov esp, ebp pop ebp ret myfunc2: push ebp mov ebp, esp push 8 call myfunc mov esp, ebp pop ebp ret C++ ASM
  25. 25. Стековый фрейм myfunc2: push ebp mov ebp, esp push 8 call myfunc mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF ESP EBP
  26. 26. Стековый фрейм myfunc2: push ebp mov ebp, esp push 8 call myfunc mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF 0x00000008 ESP EBP
  27. 27. Стековый фрейм myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] mov edx, [ebp+8] add eax, edx mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF 0x00000008 Return addr ESP EBP
  28. 28. Стековый фрейм myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] mov edx, [ebp+8] add eax, edx mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF 0x00000008 Return addr EBP v2.0 ESP EBP
  29. 29. Стековый фрейм myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] mov edx, [ebp+8] add eax, edx mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF 0x00000008 Return addr EBP v2.0 ESP EBP
  30. 30. Стековый фрейм myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] mov edx, [ebp+8] add eax, edx mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF 0x00000008 Return addr EBP v2.0 ESP EBP
  31. 31. Стековый фрейм myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] mov edx, [ebp+8] add eax, edx mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF 0x00000008 Return addr EBP v2.0 0x00000010 ESP EBP
  32. 32. Стековый фрейм myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] mov edx, [ebp+8] add eax, edx mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF 0x00000008 Return addr EBP v2.0 0x00000010 ESP EBP
  33. 33. Стековый фрейм myfunc: push ebp mov ebp, esp sub esp, 4 mov [ebp-4],0x10 mov eax, [ebp-4] mov edx, [ebp+8] add eax, edx mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF 0x00000008 Return addr EBP v2.0 0x00000010 ESP EBP
  34. 34. Как влияют конвенции вызова?
  35. 35. void __cdecl PrintFileDataC (char * Name, unsigned int Size) { printf("Name %s, Size %d", Name, Size); } push ebp mov ebp, esp mov eax, [ebp+arg_4] push eax mov ecx, [ebp+arg_0] push ecx push offset aNameSSizeD ; "Name %s, Size %d" call ds:__imp__printf mov esp, ebp pop ebp retn C++ ASM int _tmain(int argc, _TCHAR* argv[]) { PrintFileDataC("Hz",0); } push ebp mov ebp, esp push 0 push offset aHz ; "Hz" call PrintFileDataC(char*,uint) add esp, 8
  36. 36. void __stdcall PrintFileDataStd (char * Name, unsigned int Size) { printf("Name %s, Size %d", Name, Size); } push ebp mov ebp, esp mov eax, [ebp+arg_4] push eax mov ecx, [ebp+arg_0] push ecx push offset aNameSSizeD ; "Name %s, Size %d" call ds:__imp__printf mov esp, ebp pop ebp retn 8 C++ ASM int _tmain(int argc, _TCHAR* argv[]) { PrintFileDataStd("Hz",0); } push ebp mov ebp, esp push 0 push offset aHz ; "Hz" call PrintFileDataC(char*,uint)
  37. 37. void __fastcall PrintFileDataStd (char * Name, unsigned int Size) { printf("Name %s, Size %d", Name, Size); } push ebp mov ebp, esp mov [ebp+var_14], edx mov [ebp+var_8], ecx mov esi, esp mov eax, [ebp+var_14] push eax mov ecx, [ebp+var_8] push ecx push offset aNameSSizeD ; "Name %s, Size %d" call ds:__imp__printf mov esp, ebp pop ebp retn C++ ASM int _tmain(int argc, _TCHAR* argv[]) { PrintFileDataFast("Hz",0); } push ebp mov ebp, esp xor edx, edx mov ecx, offset aHz ; "Hz" call PrintFileDataFast(char*,uint)
  38. 38. Как выглядит работа со структурами?
  39. 39. typedef struct _WIN32_FIND_DATAW { DWORD dwFileAttributes; //0 FILETIME ftCreationTime; //4 FILETIME ftLastAccessTime; //C FILETIME ftLastWriteTime; //14 DWORD nFileSizeHigh; //1C DWORD nFileSizeLow; // 20 DWORD dwReserved0; //24 DWORD dwReserved1; //28 WCHAR cFileName[ MAX_PATH ]; // 2C WCHAR cAlternateFileName[ 14 ]; } WIN32_FIND_DATAW; WIN32_FIND_DATA * pData= new WIN32_FIND_DATA; FindFirstFile(L"*.*",pData); wprintf( L"Name %s, Size %d", pData->cFileName , pData->nFileSizeLow ); mov eax , [esi+20h] push eax add esi, 2Ch push esi push offset aNameSSizeD ; "Name %s, Size %d" call ds:__imp__wprintf C++ ASM push 250h call operator new(uint) add esp, 4 mov esi, eax push esi ; lpFindFileData push offset FileName ; "*.*" call ds:FindFirstFileW(x,x)
  40. 40. Как выглядят структуры в стеке?
  41. 41. void myfunc () { int a=0x10; int b=0x20; } myfunc: push ebp mov ebp, esp sub esp, 8 mov [ebp-4], 0x10 mov [ebp-8], 0x20 C++ ASM void myfunc2 () { struct MyStruct { int a; int b; } StructC; StructC.a=0x10; StructC.b=0x20; } ? myfunc2: push ebp mov ebp, esp sub esp, 8 mov [ebp-4], 0x10 mov [ebp-8], 0x20
  42. 42. Как выравнивается структура в памяти
  43. 43. struct { char a; char b; char c; short d; } TestStr={2,4,8,16}; struct { char a; unsigned b; char c; short d; } TestStr={2,4,8,16}; struc_2 struc ; (sizeof=0xC) 00000000 a db ? 00000001 db ? 00000002 db ? 00000003 db ? 00000004 b dd ? 00000008 c db ? 00000009 db ? 0000000A d dw ? 0000000C struc_2 ends struc_1 struc ; (sizeof=0x6) 00000000 a db ? 00000001 b db ? 00000002 c db ? 00000003 db ? 00000004 d dw ? 00000006 struc_1 ends
  44. 44. А что со стандартными конструкциями?
  45. 45. int ReturnMax(int a, int b) { if (a>b) return a; else return b; } mov eax, [ebp+arg_0] cmp eax, [ebp+arg_4] jle short loc_4122DD mov eax, [ebp+arg_0] jmp short loc_4122E0 loc_4122DD: mov eax, [ebp+arg_4] loc_4122E0: ... ret C++ ASM
  46. 46. char * DoSwitch(int MyNumber) { char * result; switch (MyNumber) { case 1: result="one"; break; case 2: result="two"; break; case 3: case 4: case 5: result="many"; break; default: result="don't know"; } return result; } mov ecx, [ebp+arg_0] sub ecx, 1 cmp ecx, 4 ja short loc_4132F7 jmp ds: off_413308 [ecx*4] loc_4132DC: mov [ebp+var_8], offset aOne jmp short loc_4132FE loc_4132E5: mov [ebp+var_8], offset aTwo jmp short loc_4132FE loc_4132EE : mov [ebp+var_8], offset aMany jmp short loc_4132FE loc_4132F7: mov [ebp+var_8], offset aDonTKnow loc_4132FE: mov eax, [ebp+var_8] off_413308 dd offset loc_4132DC dd offset loc_4132E5 dd offset loc_4132EE dd offset loc_4132EE dd offset loc_4132EE C++ ASM
  47. 47. Как не сойти с ума от ассемблера?
  48. 48. Кристина Цифуэнтэс ( Cristina Cifuentes ) Sun Research Laboratories 1991 г Декомпилятор DCC Код Я не сумашедшая, просто улыбаюсь. Пролог Эпилог Ветвление Присвоение Вызов функции
  49. 49. int main (int argc, void ** argv) { if (argc == 3) { int result=0; int MyInt=0; int MyHex=0; sscanf(argv[1], “%i”,&MyInt); sscanf(argv[2], “%i”,&MyInt); result=(MyInt*MyHex) ^ 0x30; } else printf(“not enough argumentsn”); return 0; } Пролог
  50. 50. int main (int argc, void ** argv) { if (argc == 3) { int result=0; int MyInt=0; int MyHex=0; sscanf(argv[1], “%i”,&MyInt); sscanf(argv[2], “%i”,&MyInt); result=(MyInt*MyHex) ^ 0x30; } else printf(“not enough argumentsn”); return 0; } Присвоение
  51. 51. int main (int argc, void ** argv) { if (argc == 3) { int result=0; int MyInt=0; int MyHex=0; sscanf(argv[1], “%i”,&MyInt); sscanf(argv[2], “%i”,&MyInt); result=(MyInt*MyHex) ^ 0x30; } else printf(“not enough argumentsn”); return 0; } Ветвление
  52. 52. int main (int argc, void ** argv) { if (argc == 3) { int result=0; int MyInt=0; int MyHex=0; sscanf(argv[1], “%i”,&MyInt); sscanf(argv[2], “%i”,&MyInt); result=(MyInt*MyHex) ^ 0x30; } else printf(“not enough argumentsn”); return 0; } Вызов функции
  53. 53. int main (int argc, void ** argv) { if (argc == 3) { int result=0; int MyInt=0; int MyHex=0; sscanf(argv[1], “%i”,&MyInt); sscanf(argv[2], “%i”,&MyInt); result=(MyInt*MyHex) ^ 0x30; } else printf(“not enough argumentsn”); return 0; } Эпилог
  54. 54. Пролог push ebp mov ebp, esp Вызов функции mov esp, ebp pop ebp ret Эпилог Присвоение mov eax, [ebp-4] mov edx, [ebp+8] add eax, edx push 0 push offset aHello call PrintFileDataC add esp, 8 Ветвление cmp eax, [ebp+arg_4] jle short loc_4122DD

×