1 Zásobník, ABI a rozbor funkce
- popsat volací konvence a poznat je v assembleru
- přečíst prolog, epilog a rámec zásobníku
- odvodit typ proměnné z instrukcí
- vysvětlit princip SEH
Ke zkoušce se počítá šest otevřených otázek hlavně na teorii, ale stejné znalosti potřebuješ i na úlohách. Na distanční zkoušce jde o dva okruhy, u kterých musíš mluvit bez přípravy.
1.1 Ukázka: co čteme
Funkce začíná téměř vždy stejně:
push ebp ; ulož rámec volajícího
mov ebp, esp ; nový rámec
sub esp, 8 ; místo pro lokální proměnné
...
mov esp, ebp ; epilog: zruš lokální proměnné
pop ebp
ret
Z sub esp, 8 víme, že lokální proměnné zabírají 8 bajtů. Z [ebp+8] je první parametr a z [ebp-4] první lokální proměnná.
CALL uloží návratovou adresu a skočí. RET ji vyzvedne.
1.2 Volací konvence
| Konvence | Parametry | Kdo uklízí zásobník |
|---|---|---|
__cdecl |
zásobník zprava | volající, add esp, n po volání |
__stdcall |
zásobník zprava | volaný, ret n |
__fastcall |
první v ECX, EDX | volaný |
__thiscall |
this v ECX |
volaný |
| Windows x64 | RCX, RDX, R8, R9 | volající |
| Linux x64 | RDI, RSI, RDX, RCX, R8, R9 | volající |
Jak ji poznat: add esp, 8 za call znamená __cdecl se dvěma parametry. Funkce končící ret 8 je __stdcall.
1.3 Typ proměnné z instrukcí
| Vidíš | Znamená |
|---|---|
MOVSX |
hodnota se znaménkem |
MOVZX |
hodnota bez znaménka |
JG, JL, JGE |
porovnání se znaménkem |
JA, JB, JNB |
porovnání bez znaménka |
[REG], [REG+4], [REG+8] |
ukazatel na strukturu |
[EBP+8] předané do API |
typ z dokumentace API |
Typy z API jsou nejlevnější informace: jakmile víš, že je argument CreateFileA, znáš jeho význam i typ.
1.4 Strukturovaná obsluha výjimek
32bitový kód registruje obsluhu na zásobníku a ukazatel na ni je ve FS:[0]. Struktura _EXCEPTION_REGISTRATION obsahuje předchozí záznam a handler, MSVC přidává scopetable a trylevel. Výjimky proto tvoří spojový seznam.
Při analýze si všimni, že except a catch bloky nejsou v normálním toku, a přitom v nich může být důležitý kód. Obfuskace toho využívají.
1.5 Dekorace jmen
C++ kóduje do symbolu typy parametrů, kvůli přetěžování. _foo@8 je __stdcall se 8 bajty argumentů. Není-li symbol, je to první vodítko k typu.
1.6 Kvíz
1.7 Tahák
[ebp+8]parametr,[ebp-4]lokální proměnná,[ebp+4]návratová adresa.add esp, nza voláním: cdecl.ret n: stdcall.thisv ECX: thiscall.- x64 Windows: RCX, RDX, R8, R9, uklízí volající.
- MOVSX a JG se znaménkem, MOVZX a JA bez.
- SEH: spojový seznam, hlava ve
FS:[0].