Kompresja plików exe moze sprawic poczatkujacym troche klopotów z dobraniem sie do programu. Dostaje czesto pytanie na ten temat wiec postanowilem rozpoczac serie tekstów na ten temat. Na poczatek informacje o których dyskutowalismy na liscie.
Postanowilem napisac pare rad jak dobrac sie do takich plików. Za przyklad posluzy nam WinAmp 2.00 i swietny programik - Proc Dump 1.0 beta. Otóz pewne jest, ze kazdy plik uruchomieniowy który jest skompresowany wzglednie szyfrowany mozna zawsze zdekompresowac poniewaz to wlasnie sie dzieje w pamieci podczas uruchomienia programu. Czesto program tak skompresowany zawiera sztuczki antydebug a szczegolnie antySoftIce. Problem sztuczek anty narazie pomine bo nie jest on istotny w naszym przykladzie (moze opisze innym razem). Coz, na poczatek zawsze nalezy przygladnac sie startowemu kodowi programu (tam gdzie skacze 'entry point'). Otoz, dla programow Win32 czesto taki kod wyglada podobnie i wywoluje kilka standardowych startowych funkcji API. Dla np. Notatnia Win95 przy entrypoint :1000 taki kod wyglada mniej wiecej:
014F:00401000 55 PUSH EBP --> Entry Point 014F:00401001 8BEC MOV EBP,ESP 014F:00401003 83EC44 SUB ESP,44 014F:00401006 56 PUSH ESI 014F:00401007 FF1548734000 CALL [KERNEL32!GetCommandLineA] 014F:0040100D 8BF0 MOV ESI,EAX 014F:0040100F 8A00 MOV AL,[EAX] ................ cos tam 014F:0040104C 50 PUSH EAX 014F:0040104D FF1558734000 CALL [KERNEL32!GetStartupInfoA] ..............., cos tam 014F:00401064 6A00 PUSH 00 014F:00401066 6A00 PUSH 00 014F:00401068 FF155C734000 CALL [KERNEL32!GetModuleHandleA] 014F:0040106E 50 PUSH EAX 014F:0040106F E87B0E0000 CALL 00401EEF --> uruchomienie programu 014F:00401074 50 PUSH EAX 014F:00401075 8BF0 MOV ESI,EAX 014F:00401077 FF1554734000 CALL [KERNEL32!ExitProcess] --> zakonczenie programu.
Dla wiekszosci wyglada to podobnie. Natomiast w przypadku kompresji lub szyfracji programu w miejscu 'entry point' jest zreguly funkcja dekompresujaca lub deszyfrujaca. Wyglada to tak :
W taki wypadku nalezalo by znalesz adres gdzie w pamieci lokowany jest dekompresowany kod i moment skoku do niego. Coz, nie bede opisywal sposobu jak to szukac bo kod dekompresji jest z reguly krotki i mozna go przesledzic czy to SoftIcem czy innym debuggerem. Przygladnijmy sie w takim razie kodowi startowemu WinAmp 2.0
:u 4d1000 l f 014F:004D1000 669C PUSHF 014F:004D1002 60 PUSHAD 014F:004D1003 E8CA000000 CALL 004D10D2 ---> skok do proc. dekompresji 014F:004D1008 0300 ADD EAX,[EAX] 014F:004D100A 0400 ADD AL,00 014F:004D100C 0500060007 ADD EAX,07000600 :u eip l 8f 014F:004D10D2 58 POP EAX 014F:004D10D3 2C08 SUB AL,08 014F:004D10D5 50 PUSH EAX .......cos tam 014F:004D1108 50 PUSH EAX 014F:004D1109 800424BF ADD BYTE PTR [ESP],BF 014F:004D110D 833A00 CMP DWORD PTR [EDX],00 014F:004D1110 0F84A7140000 JZ 004D25BD ---> zakonczenie dekompresji 014F:004D1116 F70200000080 TEST DWORD PTR [EDX],80000000 014F:004D111C 741B JZ 004D1139 .....itd 014F:004D25BD 8B6C2418 MOV EBP,[ESP+18] 014F:004D25C1 8BFD MOV EDI,EBP 014F:004D25C3 81EF00004000 SUB EDI,00400000 014F:004D25C9 85FF TEST EDI,EDI 014F:004D25CB 7443 JZ 004D2610 --> tu jakies sprawdzenia ......itd :u eip l 2f 014F:004D2617 81C62A160000 ADD ESI,0000162A 014F:004D261D 6A05 PUSH 05 014F:004D261F 59 POP ECX 014F:004D2620 F3A4 REPZ MOVSB 014F:004D2622 61 POPAD 014F:004D2623 669D POPF 014F:004D2625 E94653F5FF JMP 00427970 --> skok do glownego programu 014F:004D262A E96B69F5FF JMP 00428F9A
Po czym poznalem, ze w tym miejscu jest skok do glownego progamu, ano po tym ze tam juz zaczyna sie standardowy kod z wywolaniami funkcji startowych API. Zreszta jak sobie na starcie wyswietlimy zawartosc pamieci d cs:00427970 to zobaczymy podczas sledzenia, ze funkcja dekompresji wlasnie tam zapisuje dane. Najwazniejszy jest dla nas JMP 00427970 po ktorym nastepuje wykonanie juz zdekompresowanego kodu a jak do niego dojdziemy to juz obojetne (nawet metoda prob i bledow).
Teraz wykorzystamy program ProcDump do dekompresji. Umozliwia on oprocz dekompresji dowolnie spakowanych exe (co nie zawsze dziala), zdefiniowanie za pomoca skryptu sposobu sledzenia i zapisania dekompresowanego pliku szczegolnym pakerem. Jest tam plik skript.ini w ktorym wlasnie to definiujemy. Sa tam juz zdefiniowane Shrinker, PEShield, WWPack. Program wykorzystuje kilka komend do takiej definicji, zreszta sami zagladnijcie do pliku to zobaczycie. W kazdym razie dodajemy nowa sekcje np. WinAmp.
[INDEX] P1=PEShield ...... P7=WinAmp [WinAmp] L1=LOOK E9,46,53,F5,FF L2=BP L3=STEP
Co znaczy szukaj ciagu bajtow naszego skoku JMP 00427970 (jego postaci szesnastkowej) , po jego znalezieniu zastaw na nim pulapke i po jej wykonaniu zapisuj sledzony program jako zdekompresowany. Proste prawda. Uruchamiamy ProcDump wybieramy trace nasz typ WinAmp, wybieramy WinAmp.exe i program pieknie sie dekompresuje i co najwazniejsze dziala po tej dekompresji.
Mysle, ze ProcDump wart jest zainteresowania i przecwiczenia np wlasnie na WinAmp. Zawsze mozemy trafic na program skompresowany nieznanego typu kompresorem i wtedy damy sobie rade. Ci co nie znaja ProcDump powini go jak najszybciej sciagnac z http://www.suddendischarge.com/ w sekcji NonDOs wzglednie najnowsze wersje powinny byc na http://pub.vse.cz/pub/msdos/SAC/pc/pack/
CrackPl - (c) hyperreal.art.pl 1998