Как выглядят функции?
void myfunc (void) { } myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret C++ ASM
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
Как распол a гаются  Локальные переменные?
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
Что есть стековый фрейм?
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Как возвращается  значение из функции?
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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Как передаются  аргументы в функции?
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
Стековый фрейм myfunc2: push ebp mov ebp, esp push 8 call myfunc mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF ESP EBP
Стековый фрейм myfunc2: push ebp mov ebp, esp push 8 call myfunc mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF 0x00000008 ESP EBP
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Стековый фрейм 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
Как влияют конвенции  вызова?
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
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)
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)
Как выглядит работа  со структурами?
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)
Как выглядят структуры  в стеке?
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
Как выравнивается  структура в памяти
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
А что со стандартными конструкциями?
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
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
Как не сойти с ума  от ассемблера?
Кристина Цифуэнтэс  ( Cristina Cifuentes ) Sun Research Laboratories 1991  г Декомпилятор  DCC  Код Я не сумашедшая, просто улыбаюсь. Пролог Эпилог Ветвление Присвоение Вызов функции
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 arguments\n”); return 0; } Пролог
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 arguments\n”); return 0; } Присвоение
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 arguments\n”); return 0; } Ветвление
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 arguments\n”); return 0; } Вызов функции
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 arguments\n”); return 0; } Эпилог
Пролог 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

Основы Reverse Engineering

  • 1.
  • 2.
    void myfunc (void){ } myfunc: push ebp mov ebp, esp mov esp, ebp pop ebp ret C++ ASM
  • 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.
    Как распол aгаются Локальные переменные?
  • 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.
  • 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.
    Стековый фрейм 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.
    Стековый фрейм 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.
    Стековый фрейм Returnaddr 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.
    Стековый фрейм Returnaddr 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.
    Стековый фрейм Returnaddr 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.
    Стековый фрейм Returnaddr 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.
    Стековый фрейм Returnaddr 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.
    Стековый фрейм 0x000000000xFFFFFFFF 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.
    Стековый фрейм 0x000000000xFFFFFFFF 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.
    Стековый фрейм 0x000000000xFFFFFFFF 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.
    Как возвращается значение из функции?
  • 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.
    Стековый фрейм 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.
    Стековый фрейм 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.
    Стековый фрейм 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.
    Как передаются аргументы в функции?
  • 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.
    Стековый фрейм myfunc2:push ebp mov ebp, esp push 8 call myfunc mov esp, ebp pop ebp ret EBP v1.0 0xFFFFFFFF ESP EBP
  • 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.
    Стековый фрейм 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.
    Стековый фрейм 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.
    Стековый фрейм 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.
    Стековый фрейм 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.
    Стековый фрейм 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.
    Стековый фрейм 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.
    Стековый фрейм 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.
  • 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.
    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.
    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.
    Как выглядит работа со структурами?
  • 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.
  • 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.
    Как выравнивается структура в памяти
  • 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.
    А что состандартными конструкциями?
  • 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.
    char * DoSwitch(intMyNumber) { 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.
    Как не сойтис ума от ассемблера?
  • 48.
    Кристина Цифуэнтэс ( Cristina Cifuentes ) Sun Research Laboratories 1991 г Декомпилятор DCC Код Я не сумашедшая, просто улыбаюсь. Пролог Эпилог Ветвление Присвоение Вызов функции
  • 49.
    int main (intargc, 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 arguments\n”); return 0; } Пролог
  • 50.
    int main (intargc, 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 arguments\n”); return 0; } Присвоение
  • 51.
    int main (intargc, 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 arguments\n”); return 0; } Ветвление
  • 52.
    int main (intargc, 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 arguments\n”); return 0; } Вызов функции
  • 53.
    int main (intargc, 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 arguments\n”); return 0; } Эпилог
  • 54.
    Пролог push ebpmov 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