Copy Link
Add to Bookmark
Report
7x03 Alex Protector 1.0 beta2
[ Alex Protector 1.0 beta2 unpacking by ap0x ]
pH#7 .............F.u.l.l..R.e.v.e.r.s.e............. [ #Content ]
0x01 ................................................ [ Intro ]
0x02 ................................................ [ Unpacking ]
0x03 ................................................ [ Contact ]
0x04 ................................................ [ Outro & Greetz ]
--[ 0x01 ]---------------------------------------------[ .Intro ]-------
Da bi smo "popravili" ovaj crackme, trebace nam neki "vaspitni" alati:
[+] OllyDBG v.1.10 .................................. http://www.wasm.ru
[+] OllyAdvanced v.x ................................ http://www.wasm.ru
[+] LordPE v.1.4 .................................... http://www.wasm.ru
[+] ImpRec v.1.6 .................................... http://www.wasm.ru
[+] PeID v0.94 ...................................... http://www.wasm.ru
i naravno meta:
[+] tELock 0.99 .............................. crackme.AlexProtector.exe
Svi ovi alati su neophodni svakom reverseru pa predlazem da ako ih vec nemate,
podhitno ih nabavite! Bez njih se dalje citanje ovog teksta ne isplati!
--[ 0x02 ]---------------------------------------------[ .Unpacking ]-------
Ako pogledamo sam OEP fajla zasticenog sa AlexProtectorom videcemo sledeci kod:
00407000 > $ 60 PUSHAD
00407001 . E8 00000000 CALL crackme_.00407006
00407006 $ 5D POP EBP
00407007 . 81ED 06104000 SUB EBP,crackme_.00401006
Prilicno standardan nacin uzimanja delte i cuvanja registara. Ali da li mozemo
da uradimo standardan STACK trick i nadjemo se prilicno blizu OEPa? Ne, iz dva
razloga. Zato sto AlexProtector ne koristi POPAD kako bi vratio sadrzaj
registara na originalnu vrednost pre skoka na OEP i zato sto AlexProtector brise
hardware breakpointe tako da nam stack trik nece uspeti.
Ok kad smo to utvrdili, vreme je da pokusamo da iskoristimo exceptione koje
AlexProtector koriti ne bi li smo se sto vise priblizili OEPu. Pritiskajmo
SHIFT+F9 sve dok se ne nadjemo na sledecem delu koda:
008313C2 3300 XOR EAX,DWORD PTR DS:[EAX]
008313C4 83C4 04 ADD ESP,4
008313C7 FFE3 JMP NEAR EBX
008313C9 C3 RET
SHIFT+F9 cemo pritiskati sve dok se u ECX registru ne pojavi vrednost 00401144.
Tada cemo pogledati STACK i videcemo sledeci sadrzaj na njemu:
0012FF80 0012FF84 Pointer to next SEH record
0012FF84 0083137D SE handler
0012FF88 0083137D SE handler
Desnim klikom na SE handler i selektovanjem opcije Follow in Disassembler
dolazimo ovde:
0083137D 8B4424 0C MOV EAX,DWORD PTR SS:[ESP+C]
00831381 8380 B8000000 0>ADD DWORD PTR DS:[EAX+B8],2
00831388 51 PUSH ECX
Postavljamo breakpoint na 0083137D i pritiskamo SHIFT+F9 kako bi smo se nasli
na njemu. Traceovanjem sa F7 do ulaska u ntdll.dll (na NTu) izvrsavamo SE
handler kod. Da ne bi smo izvrsavali kod sve do SYSENTER postavljamo memoriski
breakpoint on access na region 00830000 i pritiskamo SHIFT+F9 sto nas dovodi
ovde:
008313C4 83C4 04 ADD ESP,4
008313C7 FFE3 JMP NEAR EBX
008313C9 C3 RET
Sada cemo da pogledamo da li je protector odpakovao glavnu sekciju. CTRL+G i
unosimo 00401000:
00401000 . 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8]
00401004 . 83F8 10 CMP EAX,10
00401007 . 0F87 BC000000 JA crackme_.004010C9
0040100D . 0F84 A6000000 JE crackme_.004010B9
00401013 . 8BC8 MOV ECX,EAX
00401015 . 49 DEC ECX
00401016 . 74 14 JE SHORT crackme_.0040102C
00401018 . 49 DEC ECX
00401019 . 0F85 B1000000 JNZ crackme_.004010D0
0040101F . 6A 00 PUSH 0
00401021 . FF15 F2138400 CALL NEAR DWORD PTR DS:[8413F2] ;<- Problem
00401027 . 33C0 XOR EAX,EAX
00401029 . C2 1000 RET 10
0040102C > 53 PUSH EBX
0040102D . 55 PUSH EBP
0040102E . 8B6C24 0C MOV EBP,DWORD PTR SS:[ESP+C]
00401032 . 56 PUSH ESI
00401033 . 57 PUSH EDI
00401034 . 6A 10 PUSH 10
00401036 . 68 70514000 PUSH crackme_.00405170
0040103B . 68 3C514000 PUSH crackme_.0040513C
00401040 . 55 PUSH EBP
00401041 . FF15 3C148400 CALL NEAR DWORD PTR DS:[84143C] ;<- Problem
00401047 . FF15 AE158400 CALL NEAR DWORD PTR DS:[8415AE] ;<- Veliki problem!
I kao sto vidimo protector je odpakovao glavnu sekciju ali ono sto nama ovde
predstavlja veliki problem je Import Elimination zastita koja se prepoznaje po
tome sto su svi NEAR CALL i NEAR JUMP pozivi ka APIjima zamenjeni sa pozivima ka
adresama koje nisu locirane u inicijalnoj memoriji PE32 fajla. U tom slucaju svi
ovi pozivi moraju biti prebaceni na adrese koje se nalaze unutar memorije PE32
fajla. Ali kako da ovo uradimo?
Prvo moramo da se zapitamo sledece: Da li protector unapred zna na koju ce
adresu biti alocirana memorija na koju ce on upisati podatke potrebne za Import
Elimination zastitu?
Odgovor je naravno NE, zbog cega sigurno mora postojati kod koji ce posle
odpakivanje glavne sekcije izmeniti sve NEAR CALL i NEAR JUMP pozive u pozive ka
alociranoj memoriji za Import Elimination. Dakle mi cemo pronaci kod koji
ispunjava adrese CALL i JMP naredbi tako sto cemo izvrsiti zastitu sve do
trenutka kada je glavna sekcija odpakovana ali Import Elimination popravke kod
sekcije nisu pocele. Da bi smo pronasli ovo mesto resetovacemo metu sa CTRL+F2 i
izvrsavacemo je sa SHIFT+F9 sve dok ne dodjemo do ovde:
008313C2 3300 XOR EAX,DWORD PTR DS:[EAX]
008313C4 83C4 04 ADD ESP,4
008313C7 FFE3 JMP NEAR EBX
008313C9 C3 RET
U trenutku kada se u EDI registru nalazi 00406000 nasa kod sekcija ce biti
odpakovana a Import Eliminaton popravke nece biti uradjene. Pogledajmo kod
sekciju:
00401021 FF15 FD456B02 CALL NEAR DWORD PTR DS:[26B45FD]
I postavimo memoriski breakpoint on access na 00401021. Pritiskom par puta na
SHIFT+F9 dolazimo do koda koji ispunjava code sekciju sa Import Elimination
podacima. Nalazimo se ovde:
00830C05 8901 MOV DWORD PTR DS:[ECX],EAX
00830C07 83C7 04 ADD EDI,4
00830C0A FECB DEC BL
00830C0C 58 POP EAX
00830C0D 80FB 00 CMP BL,0
Dakle na ECX {00401023} adresu se upisuje poziv ka API redirekciji. Na EAX
adresi se nalazi, adresa koja ce biti pozvana odnosno adresa API redirekcije:
008413F2 F6 13 84 00 ....
A na adresi 008413F6 imamo samu API redirekciju:
008413F6 /EB 01 JMP SHORT 008413F9
008413F8 |C9 LEAVE
008413F9 \60 PUSHAD
008413FA 0F31 RDTSC
008413FC EB 01 JMP SHORT 008413FF
008413FE C9 LEAVE
008413FF 8BD8 MOV EBX,EAX
00841401 EB 01 JMP SHORT 00841404
00841403 C9 LEAVE
00841404 8BCA MOV ECX,EDX
00841406 0F31 RDTSC
00841408 2BC3 SUB EAX,EBX
0084140A 1BD1 SBB EDX,ECX
0084140C EB 01 JMP SHORT 0084140F
0084140E C7 ???
0084140F 0F31 RDTSC
00841411 03C3 ADD EAX,EBX
00841413 13D1 ADC EDX,ECX
00841415 0F31 RDTSC
00841417 EB 01 JMP SHORT 0084141A
00841419 C7 ???
0084141A 2BC3 SUB EAX,EBX
0084141C EB 01 JMP SHORT 0084141F
0084141E C7 ???
0084141F 1BD1 SBB EDX,ECX
00841421 85D2 TEST EDX,EDX
00841423 75 0D JNZ SHORT 00841432
00841425 61 POPAD
00841426 EB 01 JMP SHORT 00841429
00841428 C7 ???
00841429 68 E9B9D477 PUSH USER32.PostQuitMessage ;<- API pointer
0084142E EB 01 JMP SHORT 00841431
00841430 - E9 C3EB01E9 JMP E985FFF8
00841435 F0:0FC7C8 LOCK CMPXCHG8B EAX
00841439 EB 01 JMP SHORT 0084143C
Dole pri dnu same redirekcije, na adresi 00841429 imamo adresu APIja koji ce
biti pozvan. Dakle sama redirekcija je prilicno jednostavna ako izuzmemo RDTSC
trik koji je dovoljan da u ImpRecu Trace Level 3 ne radi. Jos nam ostaje da
proverimo da li se samo ovde ispunjava Import Elimination tablica i spremni smo
da pocnemo sa popravkom ovog dela zastite. To mozemo da uradimo tako sto cemo
postaviti breakpoint na adresu 00830C05 (od njenog provog pozivanja) i videcemo
da samo ona upisuje podatke u code sekciju.
Sama popravka Import Eliminacije moze biti komplikovan ili lak posao. Sve
zavisi od toga da li znate kako izgleda import tablica. Ako znate znate da
pomocu ImpReca mozemo da procitamo niz API pointera i njega pretvorimo u validan
IAT tree jer ImpRec zgodno menja NEAR CALL i NEAR JUMP API pozive tako da oni
pokazuju u novu .mackt sekciju koju sam dodaje a u koju smesta IAT. To znaci da
nas "originalni" IAT i ne mora da postuje pravilo ostavljanja praznog mesta
izmedju dva importovana .dll-a. A to dalje znaci da jednostavno mozemo da
"pobacamo" validne API pointere bilo gde u memoriju i da ih iscitamo pomocu
ImpReca. Tako invalidan IAT postaje validan jer ImpRec menja sve NEAR CALL i
NEAR JUMP API pozive (ali i ostale instrukcije koje citaju API lokacije iz IATa)
koje pronadje u code sekciji, a koji pokazuju na IAT. Jedini problem koji treba
da resimo je kako da snimimo validne API pointere negde kako bi ih ImpRec
pronasao. Posto se trenutno nalazimo ovde:
00830C05 8901 MOV DWORD PTR DS:[ECX],EAX
preusmericemo upisivanje NEAR CALL i NEAR JUMP pointera ka adresama redirekcija
tako sto cemo na to mesto ubaciti skok ka praznom mestu u istoj alokaciji.
Recimo ka adresi 00831C00 na koju cemo ubaciti sledeci kod:
00831C00 60 PUSHAD
00831C01 8B58 38 MOV EBX,DWORD PTR DS:[EAX+38]
00831C04 A1 F81B8300 MOV EAX,DWORD PTR DS:[831BF8]
00831C09 8305 F81B8300 0>ADD DWORD PTR DS:[831BF8],4
00831C10 8918 MOV DWORD PTR DS:[EAX],EBX
00831C12 8901 MOV DWORD PTR DS:[ECX],EAX
00831C14 61 POPAD
00831C15 90 NOP
00831C16 90 NOP
00831C17 83C7 04 ADD EDI,4
00831C1A ^ E9 EBEFFFFF JMP 00830C0A
On je zasluzan za upisivanje validnih API pointera. Ali kako on radi? Prvo u
EBX stavljamo adresu validnog API pointera koji se u redirekciji uvek nalazi na
adresi EAX+38h. Postom u EAX stavljamo vrednost adrese 00831BF8. Ona se koristi
kao privremena promenljiva koja sadrzi mesto na kome ce biti upisan validni API
pointer. Na tu adresu cemo ubaciti vrednost 00840000 jer je to memoriska
alokacija na kojoj ce protector snimiti API redirekcije i sam izmesten IAT.
Naravno da ne bi smo stalno upisivali vrednost na isto mesto vrednost adrese
00831BF8 se u svakom prolazu povecava za cetiri. I na kraju upisujemo "validne"
vrednosti. Na mesto EAX {00840000+} upisujemo validan API pointer a na mesto ECX
{00401000+} upisujemo pointer ka validnom APIju odnosno vrednost adrese
00831BF8. Posle ovoga vracamo ukradeni kod zbog naseg skoka ka 00831C00 i
vracamo se nazad u kod za ispunjavanje Import Eliminacije.
Ako izvrsimo kod do ukradenog OEPa mete na adresi 004012E6 imacemo "validno"
ispunjenu IAT tablicu. Sada mozemo da uradimo dump i iskoristimo ImpRec kako bi
smo popravili IAT. Da bi ImpRec uopste bio u mogucnosti da pronaci IAT moramo
rucno da unesemo sledece podatke: OEP = 000012E6, RVA = 00840000 - 00400000 =
00440000 i Size = 14C. Zasto je size jednak 14C? Zato sto ako pogledamo 00840000
poslednji validni API pointer se nalazi upravo na 00840148. Klikom na Fix Dump
popravljamo IAT. Ostaje nam jos samo da popravimo i ukradeni OEP.
Da bi smo to uradili potrebno je da jos jednom restartujemo metu sa CTRL+F2 i
ponovimo sve sa pocetka teksta dok ne dodjemo do adrese 008313C4. Tada cemo
traceovati kroz kod sve dok ne dodjemo do ovde:
008311D2 83C4 04 ADD ESP,4
008311D5 85D2 TEST EDX,EDX
008311D7 ^ 75 D6 JNZ SHORT 008311AF
008311D9 61 POPAD
008311DA 8B85 AD234000 MOV EAX,DWORD PTR SS:[EBP+4023AD]
008311E0 894424 1C MOV DWORD PTR SS:[ESP+1C],EAX
008311E4 61 POPAD
008311E5 FFE0 JMP NEAR EAX ;<- Ovde!
Obratite paznju na RDTSC instrukcije, one se koriste za detekciju traceovanja
tako da svaki put kada se ona izvrsi registre EAX i EDX resetujte na nulu.
Naravno za ovo se takodje moze koristiti antiRDTSC drajver koji dolazi uz
OllyAdvanced.
Kada izvrsimo gornji JMP EAX nacicemo se ovde:
00850000 C7C7 72AFB4DF MOV EDI,DFB4AF72
00850006 8D3D 5FBA581A LEA EDI,DWORD PTR DS:[1A58BA5F]
0085000C FFCF DEC EDI
0085000E 0FACF7 F2 SHRD EDI,ESI,0F2
Ovo je obfuskovani OEP. Zasto? Zato sto se na kraju ovog koda nalaze sledece
instrukcije:
00850C74 85F7 TEST EDI,ESI
00850C76 F7C7 1CDC4C87 TEST EDI,874CDC1C
00850C7C 81E7 43C67893 AND EDI,9378C643
00850C82 - E9 5F06BBFF JMP crackme_.004012E6
Skok ka glavnoj code sekciji, odnosno skok ka kodu koji se izvrsava posle
ukradenog OEPa. Ali koje su validne instrukcije u ovoj gomili laznih? Pa ako
pogledate taj kod videcete da sve lazne instrukcije modifikuju samo EDI registar
tako da su sve ostale validne. A one su:
008503AF 55 PUSH EBP
00850635 6A FF PUSH -1
008506ED 68 F8404000 PUSH 4040F8
00850747 68 F41D4000 PUSH 401DF4
0085078F 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
008507F0 50 PUSH EAX
00850890 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
00850947 83EC 58 SUB ESP,58
00850B19 53 PUSH EBX
00850B3E 56 PUSH ESI
00850BAB 57 PUSH EDI
00850BFA 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
Njih cemo zalepiti na adresu 004012C0 u dumpovanom fajlu i pomocu LordPEa cemo
izmeniti OEP na 000012C0 i nas posao je zavrsen AlexProtector je uspesno
odpakovan.
Ako jos koji put naletite na AlexProtector ukradene bajtove mozete pronaci na
mnogo laksi nacin. Posto se oni uvek nalaze u novoj alokaciji koja ne moze da
"oslobodi" samu sebe ona ce se uvek nalaziti u memoriji nakon dolaska na lazni
OEP. Tako da bez traceovanja moze lako doci do ukradenih bajtova.
--[ 0x03 ]---------------------------------------------[ .Contact ]-------
WebSite: http://ap0x.jezgra.net
email: ap0x.rce[at]gmail[dot][com]
--[ 0x04 ]---------------------------------------------[ Outro & Greetz ]-------
Videli smo da odpakivanje AlexProtectora i nije toliko tesko ali da zastitna
opcija kao sto je Import Elimination ne pomaze dovoljno u sprecavanju
odpakivanja zasticenog software-a.
Greetz:
deroko | SND | TSRh | Reversing Labs | b4d_s3c70r | Jezgra
--[ EOF ]----------------------------------------------[ made by ap0x ]-------