[
Jak rozpakować programy spakowane nieznanymi exe-pakerami pod Win9x
]
[ Rozpakowanie WinAmpa 2.0 za pomoca ProcDump ]|
Kompresja plików exe może sprawić
początkującym trochę kłopotów z dobraniem się do programu.
Dostaje często pytanie na ten temat wiec postanowiłem rozpocząć
serie tekstów na ten temat. Na początek informacje o których
dyskutowaliśmy na liście.
Postanowiłem napisać parę rad jak dobrać się
do takich plików. Za przykład posłuży nam WinAmp 2.00 i świetny
programik - Proc Dump 1.0 beta. Otóż
pewne jest, ze każdy plik uruchomieniowy który jest skompresowany
względnie szyfrowany można zawsze zdekompresować ponieważ to właśnie
się dzieje w pamięci podczas uruchomienia programu. Często
program tak skompresowany zawiera sztuczki antydebug a szczególnie
antySoftIce. Problem sztuczek anty narazie pominę bo nie jest on
istotny w naszym przykładzie (może opisze innym razem). Cóż, na
początek zawsze należy przyglądnąć się startowemu kodowi
programu (tam gdzie skacze 'entry point'). Otóż, dla programów
Win32 często taki kod wygląda podobnie i wywołuje kilka
standardowych startowych funkcji API. Dla np. Notatnik Win95 przy
entrypoint :1000 taki kod wygląda mniej więcej:
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] --> end programu.
Dla większości wygląda to podobnie. Natomiast w
przypadku kompresji lub szyfracji programu w miejscu 'entry point'
jest z reguły funkcja dekompresująca lub deszyfrująca. Wygląda
to tak :
Start programu
Funkcja dekompresji pod pewien adres w pamięci
Sprawdzenie czy wszystko ok
Skok (jmp) pod adres w pamięci czyli nasz główny program.
W taki wypadku należało by znaleˇć adres gdzie
w pamięci lokowany jest dekompresowany kod i moment skoku do niego.
Cóż, nie będę opisywał sposobu jak to szukać bo kod
dekompresji jest z reguły krotki i można go prześledzić czy to
SoftIcem czy innym debuggerem. Przyglądnijmy się 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 poznałem, ze w tym miejscu jest skok do głównego
programu, ano po tym ze tam już zaczyna się standardowy kod z wywołaniami
funkcji startowych API. Zresztą jak sobie na starcie wyświetlimy
zawartość pamięci d cs:00427970 to
zobaczymy podczas śledzenia, ze funkcja dekompresji właśnie tam
zapisuje dane. Najważniejszy jest dla nas JMP
00427970 po którym następuje wykonanie już
zdekompresowanego kodu a jak do niego dojdziemy to już obojętne
(nawet metoda prob. i błędów).
Teraz wykorzystamy program ProcDump do
dekompresji. Umożliwia on oprócz dekompresji dowolnie spakowanych
exe (co nie zawsze działa), zdefiniowanie za pomocą skryptu
sposobu śledzenia i zapisania dekompresowanego pliku poszczególnym
pakerem. Jest tam plik skript.ini w którym właśnie to
definiujemy. Są tam już zdefiniowane Shrinker, PEShield, WWPack.
Program wykorzystuje kilka komend do takiej definicji, zresztą sami
zaglądnijcie do pliku to zobaczycie. W każdym 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 ciągu bajtów naszego skoku JMP
00427970 (jego postaci szesnastkowej) , po jego znalezieniu zastaw
na nim pułapkę i po jej wykonaniu zapisuj śledzony program jako
zdekompresowany. Proste prawda. Uruchamiamy ProcDump wybieramy trace
nasz typ WinAmp, wybieramy WinAmp.exe i program pięknie się
dekompresuje i co najważniejsze działa po tej dekompresji.
Myślę, ze ProcDump wart jest zainteresowania i
przećwiczenia np właśnie na WinAmp. Zawsze możemy trafić na
program skompresowany nieznanego typu kompresorem i wtedy damy sobie
rade. Ci co nie znają ProcDump powinni go jak najszybciej ściągnąć
z http://www.procdump32.cjb.net/ |