Download - Основы Reverse Engineering
Как выглядят функции?
void myfunc (void){
}
myfunc:push ebpmov ebp, esp
mov esp, ebppop ebpret
C++ ASM
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
Как располaгаются Локальные переменные?
void myfunc (void){ int a=0x10;}
myfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov esp, ebppop ebpret
C++ ASM
Что есть стековый фрейм?
Стековый фреймmyfunc:push ebpmov ebp, esp
mov esp, ebppop ebpret
myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret
ESP
0x00000000
0xFFFFFFFF
Стековый фреймmyfunc:push ebpmov ebp, esp
mov esp, ebppop ebpret
myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret
ESP
EBP (func2)
0x00000000
0xFFFFFFFF
Стековый фреймmyfunc:push ebpmov ebp, esp
mov esp, ebppop ebpret
myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret
ESPEBP
0x00000000
0xFFFFFFFF
EBP (func2)
Стековый фрейм
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)
Стековый фрейм
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)
Стековый фрейм
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)
Стековый фрейм
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)
Стековый фрейм
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)
Стековый фрейм
ESPEBP
0x00000000
0xFFFFFFFF
myfunc:push ebpmov ebp, esp
mov esp, ebppop ebpret
myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret
EBP (func2)
Стековый фрейм
ESPEBP
0x00000000
0xFFFFFFFF
myfunc:push ebpmov ebp, esp
mov esp, ebppop ebpret
myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret
EBP (func2)
Стековый фрейм
ESP
0x00000000
0xFFFFFFFF
myfunc:push ebpmov ebp, esp
mov esp, ebppop ebpret
myfunc2:push ebpmov ebp, espcall myfuncmov esp, ebppop ebpret
Как возвращается значение из функции?
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
Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov esp, ebppop ebpret
ESPEBP
EBP v1.0
0x00000000
0xFFFFFFFF
Стековый фреймmyfunc:push ebpmov ebp, espsub esp, 4mov [ebp-4],0x10mov eax, [ebp-4]mov esp, ebppop ebpret
ESP
EBP
EBP v1.0
0x00000000
0xFFFFFFFF
Стековый фрейм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
Как передаются аргументы в функции?
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
Стековый фреймmyfunc2:push ebpmov ebp, esppush 8call myfuncmov esp, ebppop ebpret ESPEBP
EBP v1.0
0xFFFFFFFF
Стековый фреймmyfunc2:push ebpmov ebp, esppush 8call myfuncmov esp, ebppop ebpret
ESP
EBP
EBP v1.0
0xFFFFFFFF
0x00000008
Стековый фрейм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
Стековый фрейм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
Стековый фрейм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
Стековый фрейм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
Стековый фрейм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
Стековый фрейм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
Стековый фрейм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
Как влияют конвенции вызова?
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
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)
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)
Как выглядит работа со структурами?
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)
Как выглядят структуры в стеке?
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
Как выравнивается структура в памяти
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;
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
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
Как не сойти с ума от ассемблера?
Кристина Цифуэнтэс (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 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