54
Как выглядят функции?

Основы Reverse Engineering

Embed Size (px)

Citation preview

Page 1: Основы Reverse Engineering

Как выглядят функции?

Page 2: Основы Reverse Engineering

void myfunc (void){

}

myfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

C++ ASM

Page 3: Основы Reverse Engineering

void myfunc (void){

}

void myfunc2 (void){ myfunc();}

myfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

C++ ASM

Page 4: Основы Reverse Engineering

Как располaгаются Локальные переменные?

Page 5: Основы Reverse Engineering

void myfunc (void){ int a=0x10;}

myfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov esp, ebppop ebpret

C++ ASM

Page 6: Основы Reverse Engineering

Что есть стековый фрейм?

Page 7: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

ESP

0x00000000

0xFFFFFFFF

Page 8: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

ESP

EBP (func2)

0x00000000

0xFFFFFFFF

Page 9: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

ESPEBP

0x00000000

0xFFFFFFFF

EBP (func2)

Page 10: Основы Reverse Engineering

Стековый фрейм

ESP

EBP Return addr

0x00000000

0xFFFFFFFF

myfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

EBP (func2)

Page 11: Основы Reverse Engineering

Стековый фрейм

ESP

EBP Return addr

EBP (func)

0x00000000

0xFFFFFFFF

myfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

EBP (func2)

Page 12: Основы Reverse Engineering

Стековый фрейм

ESPEBP

Return addr

0x00000000

0xFFFFFFFF

myfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

EBP (func)

EBP (func2)

Page 13: Основы Reverse Engineering

Стековый фрейм

ESPEBP

Return addr

0x00000000

0xFFFFFFFF

myfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

EBP (func)

EBP (func2)

Page 14: Основы Reverse Engineering

Стековый фрейм

ESP

Return addr

0x00000000

0xFFFFFFFF

myfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

EBP

EBP (func2)

Page 15: Основы Reverse Engineering

Стековый фрейм

ESPEBP

0x00000000

0xFFFFFFFF

myfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

EBP (func2)

Page 16: Основы Reverse Engineering

Стековый фрейм

ESPEBP

0x00000000

0xFFFFFFFF

myfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

EBP (func2)

Page 17: Основы Reverse Engineering

Стековый фрейм

ESP

0x00000000

0xFFFFFFFF

myfunc:push ebpmov ebp, esp

mov esp, ebppop ebpret

myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret

Page 18: Основы Reverse Engineering

Как возвращается значение из функции?

Page 19: Основы Reverse Engineering

int myfunc (void){ int a=0x10; return a;}

myfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]pop ebpret

C++ ASM

Page 20: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov esp, ebppop ebpret

ESPEBP

EBP v1.0

0x00000000

0xFFFFFFFF

Page 21: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov esp, ebppop ebpret

ESP

EBP

EBP v1.0

0x00000000

0xFFFFFFFF

Page 22: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov esp, ebppop ebpret

ESP

EBP

EBP v1.0

0x00000000

0xFFFFFFFF

0x00000010

Page 23: Основы Reverse Engineering

Как передаются аргументы в функции?

Page 24: Основы Reverse Engineering

int myfunc (int b){ int a=0x10; return a+b;}

int myfunc2 (void){ myfunc(8);}

myfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov edx, [ebp+8]add eax, edxmov esp, ebppop ebpret

myfunc2:push ebpmov ebp, esppush 8call myfuncmov esp, ebppop ebpret

C++ ASM

Page 25: Основы Reverse Engineering

Стековый фреймmyfunc2:push ebpmov ebp, esppush 8call myfuncmov esp, ebppop ebpret ESPEBP

EBP v1.0

0xFFFFFFFF

Page 26: Основы Reverse Engineering

Стековый фреймmyfunc2:push ebpmov ebp, esppush 8call myfuncmov esp, ebppop ebpret

ESP

EBP

EBP v1.0

0xFFFFFFFF

0x00000008

Page 27: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov edx, [ebp+8]add eax, edxmov esp, ebppop ebpret

ESP

EBP

EBP v1.0

0xFFFFFFFF

0x00000008

Return addr

Page 28: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov edx, [ebp+8]add eax, edxmov esp, ebppop ebpret

ESP

EBP

EBP v1.0

0xFFFFFFFF

0x00000008

Return addr

EBP v2.0

Page 29: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov edx, [ebp+8]add eax, edxmov esp, ebppop ebpret

ESPEBP

EBP v1.0

0xFFFFFFFF

0x00000008

Return addr

EBP v2.0

Page 30: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov edx, [ebp+8]add eax, edxmov esp, ebppop ebpret

ESP

EBP

EBP v1.0

0xFFFFFFFF

0x00000008

Return addr

EBP v2.0

Page 31: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov edx, [ebp+8]add eax, edxmov esp, ebppop ebpret

ESP

EBP

EBP v1.0

0xFFFFFFFF

0x00000008

Return addr

EBP v2.0

0x00000010

Page 32: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov edx, [ebp+8]add eax, edxmov esp, ebppop ebpret

ESPEBP

EBP v1.0

0xFFFFFFFF

0x00000008

Return addr

EBP v2.0

0x00000010

Page 33: Основы Reverse Engineering

Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov edx, [ebp+8]add eax, edxmov esp, ebppop ebpret

ESP

EBP

EBP v1.0

0xFFFFFFFF

0x00000008

Return addr

EBP v2.0

0x00000010

Page 34: Основы Reverse Engineering

Как влияют конвенции вызова?

Page 35: Основы Reverse Engineering

void __cdecl PrintFileDataC(char * Name, unsigned int Size)

{ printf("Name %s, Size %d", Name, Size);}

push ebpmov ebp, espmov eax, [ebp+arg_4]push eaxmov ecx, [ebp+arg_0]push ecxpush offset aNameSSizeD ; "Name %s, Size %d"call ds:__imp__printfmov esp, ebppop ebpretn

C++ ASM

int _tmain(int argc, _TCHAR* argv[]){ PrintFileDataC("Hz",0);}

push ebpmov ebp, esppush 0push offset aHz ; "Hz"call PrintFileDataC(char*,uint)add esp, 8

Page 36: Основы Reverse Engineering

void __stdcall PrintFileDataStd(char * Name, unsigned int Size)

{ printf("Name %s, Size %d", Name, Size);}

push ebpmov ebp, espmov eax, [ebp+arg_4]push eaxmov ecx, [ebp+arg_0]push ecxpush offset aNameSSizeD ; "Name %s, Size %d"call ds:__imp__printfmov esp, ebppop ebpretn 8

C++ ASM

int _tmain(int argc, _TCHAR* argv[]){ PrintFileDataStd("Hz",0);}

push ebpmov ebp, esppush 0push offset aHz ; "Hz"call PrintFileDataC(char*,uint)

Page 37: Основы Reverse Engineering

void __fastcall PrintFileDataStd(char * Name, unsigned int Size)

{ printf("Name %s, Size %d", Name, Size);}

push ebpmov ebp, espmov [ebp+var_14], edxmov [ebp+var_8], ecxmov esi, espmov eax, [ebp+var_14]push eaxmov ecx, [ebp+var_8]push ecxpush offset aNameSSizeD ; "Name %s, Size %d"call ds:__imp__printfmov esp, ebppop ebpretn

C++ ASM

int _tmain(int argc, _TCHAR* argv[]){ PrintFileDataFast("Hz",0);}

push ebpmov ebp, espxor edx, edxmov ecx, offset aHz ; "Hz"call PrintFileDataFast(char*,uint)

Page 38: Основы Reverse Engineering

Как выглядит работа со структурами?

Page 39: Основы Reverse Engineering

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 eaxadd esi, 2Chpush esipush offset aNameSSizeD ; "Name %s, Size %d"call ds:__imp__wprintf

C++ ASM

push 250h call operator new(uint)add esp, 4mov esi, eax

push esi ; lpFindFileDatapush offset FileName ; "*.*"call ds:FindFirstFileW(x,x)

Page 40: Основы Reverse Engineering

Как выглядят структуры в стеке?

Page 41: Основы Reverse Engineering

void myfunc (){ int a=0x10; int b=0x20;}

myfunc:push ebpmov ebp, espsub esp, 8mov [ebp-4], 0x10mov [ebp-8], 0x20

C++ ASM

void myfunc2 (){ struct MyStruct { int a; int b; } StructC;

StructC.a=0x10; StructC.b=0x20;}

?myfunc2:push ebpmov ebp, espsub esp, 8mov [ebp-4], 0x10mov [ebp-8], 0x20

Page 42: Основы Reverse Engineering

Как выравнивается структура в памяти

Page 43: Основы Reverse Engineering

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

Page 44: Основы Reverse Engineering

А что со стандартнымиконструкциями?

Page 45: Основы Reverse Engineering

int ReturnMax(int a, int b){

if (a>b)return a;

elsereturn b;

}

mov eax, [ebp+arg_0]cmp eax, [ebp+arg_4]jle short loc_4122DDmov eax, [ebp+arg_0]jmp short loc_4122E0

loc_4122DD: mov eax, [ebp+arg_4]

loc_4122E0:...ret

C++ ASM

Page 46: Основы Reverse Engineering

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, 1cmp ecx, 4ja short loc_4132F7jmp ds:off_413308[ecx*4]

loc_4132DC:mov [ebp+var_8], offset aOnejmp short loc_4132FEloc_4132E5:mov [ebp+var_8], offset aTwojmp short loc_4132FEloc_4132EE: mov [ebp+var_8], offset aMany jmp short loc_4132FEloc_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

Page 47: Основы Reverse Engineering

Как не сойти с ума от ассемблера?

Page 48: Основы Reverse Engineering

Кристина Цифуэнтэс (Cristina Cifuentes)

Sun Research Laboratories

1991 г Декомпилятор DCC

Код

Пролог

Эпилог

Ветвление

Присвоение

Вызов функции

Я не сумашедшая,

просто улыбаюсь.

Page 49: Основы Reverse Engineering

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;}

Пролог

Page 50: Основы Reverse Engineering

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;}

Присвоение

Page 51: Основы Reverse Engineering

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;}

Ветвление

Page 52: Основы Reverse Engineering

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;}

Вызов функции

Page 53: Основы Reverse Engineering

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;}

Эпилог

Page 54: Основы Reverse Engineering

Пролог

push ebpmov ebp, esp

Вызов функции

mov esp, ebppop ebpret

ЭпилогПрисвоение

mov eax, [ebp-4]mov edx, [ebp+8]add eax, edx

push 0push offset aHello call PrintFileDataCadd esp, 8

Ветвление

cmp eax, [ebp+arg_4]jle short loc_4122DD