EXE FAQ 

Strona g│≤wna

 

WstΩpniak

Wersja i historia tego faq
PodziΩkowania
Kontakty z autorami tekst≤w

Budowa pliku exe

Nag│≤wek PE
Nag│≤wek sekcji
Tabela import≤w

Podstawowe informacje

Co to jest ten exe packer
R≤┐nica miΩdzy packerem a crypterem
Jak rozpoznaµ czy i czym program jest spakowany - smola
Jak dziala taki program - smola

Metody odzyskiwania oryginalnego pliku exe

Metoda standardowa - smola
Procdump
Zrzucanie zawarto╢ci procesu z pamiΩci do pliku exe - smola
Procdump i Bhrama server - smola
SoftIce i DumpIce - smola
TRW2000
Odbudowa tabeli import≤w w plikach PE - TiTi/BLiZZARD (t│um. smola)

Rozpakowywanie przyk│adowych program≤w

Skrypty w Procdumpie na przyk│adzie UPX v.84 - smola

Dodatkowe informacje

S│ownik pojΩµ
Lista przydatnych tekst≤w - smola
Linki do stron


WstΩpniak


Ze wzglΩdu na do╢µ du┐e zainteresowanie zagadnieniami zwi▒zanymi z plikami exe, ich pakowaniem, rozpakowywaniem i budow▒ a tak┐e tym ┐e od d│u┐szego ju┐ czasu zajmujΩ siΩ prawie wy│▒cznie tym tematem, postanowi│em co╢ o tym wszystkim napisaµ. Mam nadziejΩ ┐e to pomo┐e chocia┐ kilku osobom poznaµ g│Ωbiej ten temat i zachΩci do w│asnych eksperyment≤w. Chcia│bym r≤wnie┐ aby ten tutorial przeistoczy│ siΩ w co╢ w rodzaju FAQ a mianowicie ka┐dy kto czuje siΩ na si│ach i posiada jak▒╢ wiedzΩ w tym temacie do│o┐y│ do niego swoje 3 grosze. S▒dzΩ, ┐e dziΩki istnieniu kilku grup crackerskich w Polsce a co za tym idzie wielu specjalist≤w ten tutorial stanie siΩ prawdziw▒ skarbnic▒ wiedzy. WiΩc je╢li ju┐ napisa│e╢ co╢ na ten temat, chcesz przet│umaczyµ jaki╢ tekst albo rozpakowa│e╢ ju┐ jakiego╢ progsa, to skontaktuj siΩ ze mn▒ (smola@pcplus.com.pl) a ja z pewno╢ci▒ umieszczΩ Tw≤j tekst wraz z Twoj▒ ksywk▒. Tekst nie musi byµ formatowany, mile widziane polskie znaki, najlepiej w windows (notatnik rulez! :). Prawdopodobnie od nastΩpnej wersji bΩdzie on wydawany w formie pliku html wiΩc bΩdzie pro╢ciej co╢ znale╢µ i oczywi╢cie bΩdzie go mo┐na umie╢ciµ na swojej stronie www.
smola

Wersja i historia tego faq

Najnowsza wersja tego faq bΩdzie zawsze dostΩpna na www.crackpl.site.pl i www.smola.prv.pl.

v0.1 - 4.02.00 - no c≤┐, to dopiero pierwsze wydanie, mam nadziejΩ ┐e w przysz│ych wersjach bedzie troszkΩ wiΩcej do poczytania.

PodziΩkowania

Przede wszystkim dla Gustawa za ca│okszta│t, za pomoc, za to ┐e wog≤le jest.
Wszystkim przysz│ym suporterom za wk│ad w rozwijanie tego faq. ;)
Za│o┐ycielom listy crackpl Gustawowi i Zomo za wiedzΩ jak▒ zdoby│em dziΩki tej li╢cie.
Wszystkim znajomym kt≤rych spotka│em bezpo╢renio (party rulez! :) oraz tym kt≤rych znam tylko z maili za przekazan▒ wiedzΩ, pomoc i zaanga┐owanie.
Wszystkim newbies kt≤rzy pisz▒ do mnie ze swoimi wielkimi problemami za to ┐e dziΩki nim jestem zmuszony g│Ωbiej siΩ wrzeraµ w konkretne zagadnienie a przez to poszerzam swoj▒ wiedzΩ.
Wszystkim ludziom z AAOCG, CookieCrk, CrackPL, UFO Crew za to ┐e s▒ i co╢ robi▒.

Kontakty z autorami tekst≤w

smola - smola@pcplus.com.pl


Budowa pliku exe


Nag│≤wek PE

Nag│≤wek sekcji

Tabela import≤w


Podstawowe informacje


Co to jest ten exe packer

 

R≤┐nica miΩdzy packerem a crypterem

 

Jak rozpoznaµ czy i czym program jest spakowany

Oto kilka zasad kt≤re nas upewniaj▒ ┐e program jest spakowany:

  1. Pr≤ba wczytania programu pod wdasm go zawiesza.
  2. W ogl▒danym kodzie programu pod hex edytorem wystΩpuj▒ sygnatury packer≤w i/lub dziwne nazwy sekcji (typowe to .code, .text, .data, .rdata, .rsrc itp.).
  3. EP (entry point) jest ustawiony na inn▒ warto╢µ ni┐ 401000.
  4. Tabela import≤w (import table) w kodzie programu zawiera tylko kilka funkcji jak np. GetProcAddress, LoadLibrary, GlobalAlloc, ExitProcess.
  5. Og≤lnie zawarto╢µ execa nie przypomina standardu gdzie wydaje siΩ byµ sporo wolnego miejsca wype│nionego zerami.

Generalnie dobrym zwyczajem przed debugowaniem ka┐dego proga jest obejrzenie jego kodu pod jakim╢ hex edytorem i ew. Procdumpem. NajczΩ╢ciej na podstawie powy┐szych test≤w mo┐na ju┐ okre╢liµ rodzaj u┐ytego exepackera i podj▒µ stosowne kroki celem rozpakowania. Nieocenionym programem tutaj jest oczywi╢cie procdump. Je╢li jednak wci▒┐ nie wiemy czym spakowany jest dany progs to mo┐emy jeszcze u┐yµ jakiego╢ analizatora. Jest to specjalny program kt≤ry rozpoznaje kilkadziesi▒t rodzaj≤w format≤w plik≤w. Wartym u┐ycia jest np. FileInfo. Jego obecna wersja to 2.12 z dnia 31/01/2000. Je╢li i to nie pomaga to niestety pozostaje tylko jego prze╢ledzenie pod debuggerem krok po kroku. Niezast▒pionymi s▒ tu TRW2000 lub SoftIce + DumpIce.
smola

Jak dzia│a taki program

Og≤lna zasada dzia│ania exepackerow jest podobna do dzia│ania loadera czy nawet wirusa :), tzn. najpierw jest uruchamiana procedura rozpakowuj▒ca kt≤ra to odtwarza strukturΩ execa sprzed kompresji i kiedy taki exec jest ju┐ odtworzony nastΩpuje skok do oryginalnego entry pointa. Nasze zadanie polega na znalezieniu w│a╢nie tego miejsca i wykonaniu zrzutu zawarto╢ci pamiΩci tego odbudowanego execa. Nie zawsze jest to proste, czΩsto taki packer zwiera procedury antydebug, zbΩdny kod utrudniaj▒cy ╢ledzenie jak r≤wnie┐ mo┐e zamazywaµ cze╢µ nieistotnych ju┐ danych w kodzie execa a to siΩ wi▒┐e z tym ┐e po zrobieniu zrzutu pamiΩci taki exec po prostu nie bΩdzie dzia│a│. Jedynym wyj╢ciem jest tylko analiza krok po kroku procedury rozpakowuj▒cej execa pod debuggerem.
smola


Metody odzyskiwania oryginalnego pliku exe


Metoda standardowa

Stosunkowo najpro╢ciej i najszybciej jest rozpakowaµ jaki╢ program u┐ywaj▒c depakera napisanego tylko do konkretnego pakera. Czyli np. do programu spakowanego aspack'iem najlepiej u┐yµ unaspack. Zazwyczaj depakery maj▒ tak▒ sam▒ nazwΩ jak paker z tym ┐e zawieraj▒ przedrostek 'Un' b▒d╝ 'De'. Niestety wci▒┐ s▒ wypuszczane coraz to nowsze wersje program≤w pakuj▒cych kt≤re s▒ niekompatybilne w d≤│ (tzn. ┐e depaker napisany do wersji np. 1.30 mo┐e i z reg≤│y nie dzia│a z wersj▒ 1.31) w wyniku czego jeste╢my zmuszeni do u┐ycia innych metod dekompresji. Mimo wszystko jest to i tak najlepszy spos≤b rozpakowywania, poniewa┐ w 99% przypadk≤w rozpakowany program wygl▒da tak samo jak przed kompresj▒.
smola

Procdump

Zrzucanie zawarto╢ci procesu z pamiΩci do pliku exe

Termin ten zwany r≤wnie┐ ProcessDump polega na przeniesieniu procesu z pamiΩci komputera do wykonywalnego pliku exe. W zasadzie mo┐na to zrobiµ na dwa sposoby: albo przez FullDump albo przez PartialDump. Pierwszy z nich polega na zrzuceniu zawarto╢ci procesu w jednym ca│ym kawa│ku czyli wszystkie sekcje programu znajduj▒ siΩ w tych miejscach na kt≤re wskazuj▒ ich RVA. Mankamentem tego rozwi▒zania jest to ┐e taki plik mo┐e zajmowaµ bardzo du┐o miejsca na dysku i dlatego jest te┐ druga metoda znana pod nazw▒ PartialDump, czyli zrzut procesu (a w zasadzie jego poszczeg≤lnych sekcji) z pamiΩci po kawa│ku. Ten spos≤b pozwala na znaczne oszczΩdno╢ci miejsca na dysku jednak zmusza nas do p≤╝niejszego rΩcznego "posklejania" tych wszystkich sekcji. Jakiego by jednak sposobu nie u┐yµ, to i tak czeka nas rΩczna odbudowa takiego pliku. Przede wszystkim chodzi tutaj o sekcjΩ import≤w, czyli miejsce w pliku PE gdzie znajduj▒ siΩ nazwy wszystkich funkcji z jakich korzysta program. W uproszczeniu problem le┐y w tym i┐ w miejscach gdzie powinny byµ wska╝niki (pointer) na stringi z nazwami funkcji s▒ rzeczywiste adresy tych funkcji. Dok│adny opis tego zagadnienia wraz ze sposobem naprawy znajduje siΩ w Odbudowa tabeli import≤w w plikach PE.

(to jeszcze nie koniec)

smola

Procdump i Bhrama server

Do czego w│a╢ciwie s│u┐y ta opcja Bhrama Server?

DziΩki uaktywnieniu Bhrama Server mo┐emy zdalnie sterowaµ ProcDumpem czy to poprzez pluginy (m.in. do vbox, securom czy petit) czy SoftIce (z zainstalowanym DumpIce). Generalnie chodzi o to aby przej╢µ prockΩ depakujac▒ exepackera, zatrzymaµ dalsze wykonywanie procesu i przekazaµ sterowanie do Procdumpa kt≤ry to piΩknie nam zrzuca pamiΩµ procesu i zapisuje na dysk gotowego execa. Bhrama jest w│a╢nie takim │▒cznikiem.

Komunikacja z Bhrama polega na samodzielnym rozpakowaniu programu ew. ominiΩciu procedur antydebug, zamro┐eniu ╢ledzonego procesu (suspend) i umieszczeniu jego identyfikatora PID (process ID) oraz dodatkowych opcji rozpakowania (szczeg≤lowe info w pliku bhrama.txt do│▒czonym do Procdumpa) w odpowiednim miejscu struktury BhramaComStruc, znalezieniu uchwytu okna 'ProcDump32 - Dumper Server' a nastΩpnie wys│aniu tego wszystkiego funkcj▒ SendMessage i zako±czenia w│asnego procesu.

SendMessage uchwyt_okna_Bhrama_Server,WM_COPYDATA,0,offset DataServices

W zale┐no╢ci od potrzeby Bhrama oferuje 2 rodzaje us│ugi: Full Dump (wszystkim zajmie siΩ Procdump) albo Partial Dump. W tym drugim przypadku musimy sami okre╢liµ pocz▒tek i d│ugo╢µ obszaru pamiΩci do zrzucenia. Po wys│aniu komunikatu WM_COPYDATA Procdump automatycznie odwali za nas ca│▒ "czarn▒ robotΩ" i zapisze gotowego exeka do pliku. WiΩcej szczeg≤│≤w mo┐na znale╢µ w dokumentacji Procdumpa jak r≤wnie┐ poprzez analizΩ ╝r≤de│ plugin≤w.
smola

SoftIce i DumpIce

SoftIce jak ju┐ pewinie wiesz jest debuggerem, czyli programem mog▒cym ╢ledziµ wykonywanie siΩ innego programu krok po kroku. Natomiast DumpIce jest swoistego rodzaju nak│adk▒ na SI, dodaj▒c▒ jemu wiele nowych mo┐liwo╢ci. Obecnie DumpIce jest w wersji 6.11 (26/01/2000) i pozwala nam nawet na s│uchanie swoich ulubionych mp3 w trakcie debugowania... :) Ale to nie jest jego najwa┐niejsz▒ cech▒. Ot≤┐ po zainstalowaniu go umo┐liwia nam bezproblemowe zrzucenie zawarto╢ci pamiΩci bezpo╢rednio z SI do pliku, jak r≤wne┐ mo┐e siΩ komunikowaµ przez Bhrama serwer z Procdumpem. A co to oznacza to chyba nie muszΩ m≤wiµ. Wystarczy ┐e uruchomimy Procdumpa i uaktywnimy Bhrama Serwer, nastΩpnie przejdziemy w SI przez procedure depakuj▒c▒ exepackera, ustawimy sie na oryginalnym EP (entry point) i wpiszemy komendΩ:

PAGEIN B ProcDump32 - Dumper Server

a Procdump nam piΩknie zrzuci proces do pliku exe. Dzia│a bezb│Ωdnie. Je╢li masz jakie╢ k│opoty z dzia│aniem tej komendy to dopisz sobie do winice.dat nastΩpuj▒c▒ linijkΩ:

F3=" PAGEIN B ProcDump32 - Dumper Server; "

Po prze│adowaniu systemu naci╢niΩcie klawisza F3 powoduje zapisanie gotowego exeka na dysk (oczywi╢cie Bhrama Server musi byµ aktywny).
smola

TRW2000

Odbudowa tabeli import≤w w plikach PE

Tekst napisany 18.07.99 przez TiTi/BLiZZARD
Do╢µ swobodnie przet│umaczony 3.02.00 (rev. 01) przez smola/crackpl

1. Komu to jest przydatne?

Cze╢µ wszystkim! Napisa│em ten tekst, poniewa┐ w czasie kiedy pracowa│em nad programem typu process dumper (program kt≤ry zrzuca zawarto╢µ uruchomionego procesu do pliku exe) testowa│em wiele paker≤w/enkrypter≤w kt≤re czyni│y tablicΩ import≤w nieu┐yteczn▒ i zrzucone pliki exe wymaga│y odbudowywania tej tablicy. Szukaj▒c w wielu miejscach w sieci informacji na ten temat nie znalaz│em nic konkretnego, wiΩc je╢li siΩ tym interesujesz, to masz przed sob▒ tego ma│ego helpa.

Dla przyk│adu program spakowany Petite v2.1 po zrzuceniu z pamiΩci do pliku wymaga odbudowania tabeli import≤w (a dok│adniej jej skorygowania) aby plik exe uruchamia│ siΩ poprawnie. Podobnie jest w przypadku program≤w spakowanych aspack'iem, pepack'iem, pesentry itp. To w│a╢nie dlatego funkcje odbudowy tabeli import≤w s▒ niezbΩdne w ka┐dym programie zrzucaj▒cym proces do pliku. Np. Phoenix Engine napisany przez G-RoM/UCF u┐yty w ProcDump'ie albo PERebuilder napisany przez Virogen/PC i mnie.

Temat ten jest bardzo specyficzny i do╢µ skomplikowany, dlatego zak│adam ┐e znasz ju┐ strukturΩ plik≤w exe. Je╢li nie, to powiniene╢ zapoznaµ siΩ z jak▒╢ dokumentacj▒ na ten temat (na ko±cu pliku zamie╢ci│em spis u┐ytecznych tekst≤w - smola).

2. WstΩpny komentarz.

Najpierw parΩ s│≤w o tabeli import≤w oraz RVA/VA (uwaga, autor w oryginale u┐ywa zamiennie s│≤w offset i adres - smola).

WzglΩdny adres tabeli import≤w (ang. import table relative virtual address - RVA) jest zapisany w odpowiednim miejscu w nag│≤wku pliku PE. Miejsce to nazywa siΩ directory entry a jego offset mo┐na wyliczyµ nastΩpuj▒co: offset nag│≤wka PE + 80h. Adres ten nie odpowiada offsetowi tabeli import≤w w pliku (z wyj▒tkiem sytuacji kiedy plik zosta│ zrzucony z pamiΩci), wiΩc pierwsz▒ rzecz▒ jak▒ trzeba zrobiµ jest znalezienie tabeli import≤w w pliku PE i przeliczenie RVA na odpowiedni adres wirtualny VA (virtual address). Jest kilka sposob≤w aby to osi▒gn▒µ. Mo┐na napisaµ w│asn▒ procedurΩ "miel▒c▒" (parser) nag│≤wki sekcji (sections directory) i wyliczaj▒c▒ poprawny adres wirtualny VA ale │atwiej jest to zrobiµ poprzez u┐ycie funkcji API kt≤ra zosta│a specjalnie do tego celu stworzona. Funkcj▒ t▒ jest zawarta w bibliotece IMAGEHLP.DLL (biblioteka u┐ywana przez Windows 9x oraz Windows NT) i nazywa siΩ ImageRvaToVa. Poni┐ej jej opis (pe│ny jej opis jest zawarty w msdn library):

# LPVOID ImageRvaToVa(
#  IN PIMAGE_NT_HEADERS NtHeaders,
#  IN LPVOID Base,
#  IN DWORD Rva,
#  IN OUT PIMAGE_SECTION_HEADER *LastRvaSection
#);
#
#Parametry :
# NtHeaders 
#   Wska╝nik do struktury IMAGE_NT_HEADERS. T▒ strukturΩ
#   mo┐na uzyskaµ poprzez wywo│anie funkcji ImageNtHeader.
# Base
#   Okre╢la adres bazowy obrazu pliku kt≤ry jest mapowany
#   wewn▒trz pamiΩci poprzez wywo│anie funkcji MapViewOfFile.
# Rva
#   Okre╢la gdzie ma po│o┐yµ RVA.
# LastRvaSection
#   Wska╝nik do struktury IMAGE_SECTION_HEADER kt≤ra
#   opisuje ostatni▒ sekcjΩ RVA. Parametr opcjonalny.
#   Je╢li podany, wskazuje na zmienn▒ kt≤ra zawiera
#   warto╢µ ostatniej sekcji u┐ytej do okre╢lenia
#   obrazu pliku do przeliczenia RVA na VA. 

Jak widaµ jest bardzo prosta w u┐yciu... :) Po prostu musisz mieµ mapΩ swojego pliku PE w pamiΩci i wtedy wywo│ujesz t▒ funkcjΩ aby otrzymaµ poprawny VA do tabeli import≤w.
Zauwa┐, ┐e powy┐ej pomin▒│em wszystkie znaczniki RVA/VA, ale nie zapomnij o przeliczeniu jednego na drugi kiedy bΩdziesz odczytywaµ lub zapisywaµ RVA z/do pliku PE podczas jego odbudowy.

3. Pe│ne obja╢nienie.

Poni┐ej jest pe│ny opis odbudowania zmienionej tabeli import≤w w pliku PE skompresowanego przez petite v2.1 (plik zosta│ zrzucony bezpo╢rednio z pamiΩci).

00 s▒ reprezentowane przez spacjΩ ' '
inne znaki s▒ reprezentowane przez '-'
0000C1E8h : 00 00 00 00 00 00 00 00 00 00 00 00 BA C2 00 00              ----
0000C1F8h : 38 C2 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ----            
0000C208h : C5 C2 00 00 44 C2 00 00 00 00 00 00 00 00 00 00  --------        
0000C218h : 00 00 00 00 D2 C2 00 00 54 C2 00 00 00 00 00 00      --------    
0000C228h : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                  
0000C238h : 7F 89 E7 77 4C BC E8 77 00 00 00 00 E6 9F F1 77  --------    ----
0000C248h : 1A 38 F1 77 10 40 F1 77 00 00 00 00 4F 1E D8 77  --------    ----
0000C258h : 00 00 00 00 00 00 4D 65 73 73 61 67 65 42 6F 78        MessageBox
0000C268h : 41 00 00 00 77 73 70 72 69 6E 74 66 41 00 00 00  A   wsprintfA   
0000C278h : 45 78 69 74 50 72 6F 63 65 73 73 00 00 00 4C 6F  ExitProcess   Lo
0000C288h : 61 64 4C 69 62 72 61 72 79 41 00 00 00 00 47 65  adLibraryA    Ge
0000C298h : 74 50 72 6F 63 41 64 64 72 65 73 73 00 00 00 00  tProcAddress    
0000C2A8h : 47 65 74 4F 70 65 6E 46 69 6C 65 4E 61 6D 65 41  GetOpenFileNameA
0000C2B8h : 00 00 55 53 45 52 33 32 2E 64 6C 6C 00 4B 45 52    USER32.dll_KER
0000C2C8h : 4E 45 4C 33 32 2E 64 6C 6C 00 63 6F 6D 64 6C 67  NEL32.dll_comdlg
0000C2D8h : 33 32 2E 64 6C 6C 00 00 00 00 00 00 00 00 00 00  32.dll          

Jak widaµ tabela import≤w podzielona jest na trzy g│≤wne czΩ╢ci:

  • od C1E8h->C237h : Tablica ze struktur▒ IMAGE_IMPORT_DESCRIPTOR,
                      ka┐dy jeden odpowiada importowanej bibliotece DLL.
                      Koniec tablicy jest wype│niony zerami.
   IMAGE_IMPORT_DESCRIPTOR struct
      OriginalFirstThunk  	dd 0  ;RVA do original unbound IAT
      TimeDateStamp		dd 0  ;tutaj nie u┐ywany
      ForwarderChain		dd 0  ;tutaj nie u┐ywany
      Name			dd 0  ;RVA do stringu z nazw▒ biblioteki DLL
      FirstThunk		dd 0  ;RVA do tablicy IAT
   IMAGE_IMPORT_DESCRIPTOR ends
  • od C238h->C25Bh : Tablica z d│ugimi s│owami (DWORD) wywo│uj▒ca 'IAT'
                      wskazywany przez FirstThunk ze struktury IMAGE_IMPORT_DESCRIPTOR
                      Ka┐dy DWORD z tej tablicy odpowiada importowanej funkcji.
  • od C25Ch->C2DDh : S▒ to stringi z nazwami importowanych funkcji oraz
                      bibliotek DLL. Problem le┐y w tym ┐e nie ma tu okre╢lonego
                      porz▒dku, czasem nazwy bibliotek s▒ przed nazwami funkcji,
                      czasami odwrotnie a nieraz s▒ wymieszane ze sob▒.

Ma│e wyja╢nienie nt. tabeli import≤w

OriginalFirstThunk jest tablic▒ IAT (import address table - IAT) kt≤r▒ PE loader poszukuje w pierwszej kolejno╢ci. Je╢li wystΩpuje, to wtedy PE loader u┐ywa jej do skorygowania ewentualnych problem≤w w tablicy FirstThunk IAT. Jednorazowo wczytuje do pamiΩci ka┐dy DWORD z tablicy FirstThunk zawieraj▒cy RVA do stringu z nazwa funkcji i podmienia go z RVA na prawdziwy adres funkcji (ta lokacja w pamiΩci nie mo┐e byµ u┐ywana kiedy wywo│ywana jest ta funkcja). WiΩc najpro╢ciej: to nie jest problem z tablic▒ import≤w, bo jest ona odpowiednio wype│niana a OriginalFirstThunk zostaje niezmieniony.

I tutaj dochodzimy do naszego problemu

Po tym kr≤tkim wyja╢nieniu dochodzimy do sedna problemu. Ot≤┐ je╢li spr≤bujesz teraz uruchomiµ taki plik exe zawieraj▒cy tabelΩ pokazan▒ powy┐ej, nie zostanie on wczytany a windows wy╢wietli komunikat o b│Ωdzie. Dlaczego? Ano dlatego, ┐e tablica OriginalFirstThunk zosta│a usuniΩta.

ZapamiΩtaj to, ┐e dla ka┐dej struktury IMAGE_IMPORT_DESCRIPTOR w tej tabeli import≤w OriginalFirstThunk zawiera warto╢µ 00000000h. Hm, domy╢lamy siΩ, ┐e kiedy plik exe jest uruchamiany to PE loader pr≤buje wzi▒µ nazwy importowanych funkcji z tablicy FirstThunk, ale jak sobie przypominasz, ta tablica nie zawiera RVA do string≤w z nazwami funkcji, tylko RVA do adres≤w funkcji w pamiΩci.

Co mamy do zrobienia

To co teraz powinni╢my uczyniµ aby otrzymaµ dzia│aj▒cy plik exe, to odbudowa zawarto╢ci tablicy FirstThunk poprzez wstawienie do niej warto╢ci wskazuj▒cych na stringi z nazwami funkcji kt≤re widzieli╢my w trzeciej czΩ╢ci tabeli import≤w. Wbrew pozorom nie jest to trudne zadanie, ale potrzebujemy wiedzieµ kt≤ry IAT odpowiada danej funkcji jako ┐e stringi z nazwami funkcji nie s▒ pouk│adane w ten sam spos≤b jak cz│onkowie FirstThunk.

No wiΩc dla ka┐dego IAT potrzebujemy zidentyfikowaµ nazwΩ funkcji kt≤ra jemu odpowiada. W tej chwili mamy ju┐ nazwy bibliotek DLL, poniewa┐ mamy IMAGE_IMPORT_DESCRIPTOR. Wska╝niki DWORD do ich nazw nie zosta│y oczywi╢cie zmienione.

W jaki spos≤b zidentyfikowaµ ka┐d▒ funkcjΩ

Jak ju┐ wspomnia│em wcze╢niej, ka┐dy uszkodzony IAT jest RVA do adresu funkcji w pamiΩci. Te adresy w trakcie trwania sesji, czyli dop≤ki nie zrestartujesz kompa, nie zmieniaj▒ siΩ na inne, wiΩc mo┐emy por≤wnaµ je z adresami funkcji na kt≤re wskazuje uszkodzony IAT i ustawiµ na nim wska╝nik (pointer) do string≤w z nazwami funkcji.

Aby to zrobiµ skorzystamy z bardzo u┐ytecznej funkcji API z biblioteki Kernel32.dll kt≤ra nosi nazwΩ GetProcAddress. Zwraca nam ona adres zadanej funkcji. Poni┐ej jej opis:

GetProcAddress(
    HMODULE	hModule,	// uchwyt (handle) do biblioteki DLL
    LPCSTR	lpProcName 	// nazwa funkcji
);
  • Parametr hModule jest uchwytem do biblioteki DLL (okre╢la on adres bazowy
    (base address) obszaru modu│u w pamiΩci), kt≤ry to mo┐emy odczytaµ u┐ywaj▒c
    kolejnej funkcji API GetModuleHandleA:
    HMODULE GetModuleHandle(
        LPCTSTR  lpModuleName 	// adres nazwy modu│u dla kt≤rego zwr≤cony zostanie uchwyt
    );
  • lpModuleName jest po prostu wska╝nikiem do nazwy pliku DLL kt≤ry to mo┐emy
    pobraµ z cz│onka struktury IMAGE_IMPORT_DESCRIPTOR.Name
  • lpProcName jest wska╝nikiem do stringu zawieraj▒cego nazwΩ funkcji.

WiΩc aby naprawiµ uszkodzony IAT, musimy sprawdziµ wszystkie nazwy funkcji wystΩpuj▒ce w trzeciej czΩ╢ci tabeli import≤w dop≤ki GetProcAddress nie zwr≤ci nam adresu szukanej funkcji.

Wiedz, ┐e czasem funkcja jest importowana poprzez liczbΩ (ordinal number). Te numery s▒ s│owami (WORDS) i wyliczaµ je nale┐y nastΩpuj▒co: offset nazwa_funkcji - 2. Tak wiΩc Twoja procedura "miel▒ca" powinna sprawdzaµ jak dana funkcja jest importowana; czy przez nazwΩ czy przez numer.

Poni┐ej przyk│ad rekonstrukcji tabeli import≤w

Spr≤buje wyja╢niµ w jaki spos≤b nale┐y naprawiµ pierwsz▒ importowan▒ funkcjΩ z pierwszej importowanej biblioteki DLL na podstawie powy┐szego opisu tabeli import≤w.

  1. Szukamy pierwszej tablicy struktury IMAGE_IMPORT_DESCRIPTOR (C1E8h), i pobieramy z niej nazwΩ biblioteki DLL, wskazywan▒ przez cz│onka .Name (C1E4h, kt≤ry wskazuje na C1BAh). Widzimy ┐e jest to USER32.dll.
  2. Patrzymy na cz│onka struktury .FirstThunk, kt≤ry wskazuje na tablice IAT; ka┐dy jeden odpowiada jednej importowanej funkcji z tej biblioteki DLL (user32.dll). W tym przypadku jest to C1F8h, kt≤ry wskazuje na C238h. WiΩc pod C238h mamy nasz uszkodzony IAT kt≤ry oczywi╢cie musimy naprawiµ (mo┐esz zapamiΩtaµ ┐e ta tablica IAT zawiera 2 d│ugie s│owa (DWORD), wiΩc 2 funkcje s▒ importowane z tego DLL'a.
  3. Teraz bierzemy pierwszy uszkodzony IAT. Jego warto╢µ to 77E7897Fh. To jest w│a╢nie adres jakiej╢ funkcji le┐▒cej w pamiΩci.
  4. Dla ka┐dej nazwy funkcji z trzeciej czΩ╢ci tabeli import≤w musimy wywo│aµ funkcjΩ API GetProcAddress. Kiedy funkcja ta zwr≤ci nam w│a╢nie warto╢µ 77E7897Fh, odnale╝li╢my w│a╢ciw▒ funkcjΩ. Teraz ustawiamy uszkodzony IAT tak ┐eby wskazywa│ na nazwΩ poprawnej (w tym przypadku jest to 'wsprintfA').
  5. Teraz musimy zmieniµ IAT aby wskazywa│ na offset (string nazwa_funkcji) -2. Dlaczego -2? Poniewa┐ czasami jest u┐ywane normalne sortowanie funkcji. W tym przypadku zamieniamy zawarto╢µ adresu C238h tak aby wskazywa│ na C26Ah (zamiast 77E7897Fh).
  6. To wszystko, teraz funkcja jest naprawiona i trzeba tylko powt≤rzyµ te zabiegi dla pozosta│ych IAT.

Nota ko±cowa

Opisa│em og≤lny spos≤b postΩpowania. Oczywi╢cie dzia│a on tylko na DLL'e kt≤re s▒ aktualnie wczytane do pamiΩci. Dla pozosta│ych musisz je najpierw wczytaµ lub przekszta│ciµ ich tablice eksport≤w aby znale╝µ poprawne adresy funkcji.

To chyba tyle. Komentarze, raporty o jako╢ci itp. mi│e rzeczy mile widziane... :)
smola


Rozpakowywanie przyk│adowych program≤w


Skrypty w Procdumpie na przyk│adzie UPX v.84

Mam pewien drobny problemik z niemieck▒ wersj▒ winrara 2.6. Polsk▒ i angielsk▒ skraczy│em ale ta nie wiem czemu jest spakowana UPX'em i niestety nie mogΩ jej rozpakowaµ procdumpem. Chcia│em zastosowaµ si loadera i jako╢ doj╢µ do w│a╢ciwego entrypoint'a ale loader nie zatrzymuje siΩ na nim wiΩc uruchomi│em pe-editor i niestety nie wiem co dalej bo tam zamiast zwyk│ych .code, .data itp. jest UPX0 i UPX1. Jak mam siΩ za to zabraµ?

Aby rozpakowaµ takiego UPX nale┐y posiadaµ Procdumpa 1.5 (obecna wersja to 1.6.2), jaki╢ hex edytor np. Hex Workshop i oczywi╢cie Notepada... :) Pierwszym krokiem kt≤ry nale┐y uczyniµ jest u┐ycie standardowego skryptu UPX z Procdumpa. Niestety w moim przypadku on nie dzia│a│ a kilka pr≤b jego modyfikacji r≤wnie┐ nie przynios│o ┐adnych rezultat≤w. No to zabra│em siΩ za samego execa. I tu w│a╢nie jest ta sytuacja o kt≤rej piszesz z niemo┐no╢ci▒ u┐ycia loadera z si. Ale my ju┐ wiemy co trzeba zrobiµ z tym fantem (vide wcze╢niejsze problemy z paj▒kiem itp. - polecam poczytaµ archiwum listy crackpl), wiΩc zmieniamy characteristic pierwszej sekcji UPX0 z e0000040 na e0000020.

Gdyby Procdump z jaki╢ powod≤w nie m≤g│ wczytaµ execa (czasami tak mam) to nale┐y u┐yµ jakiego╢ hex edytora (np. Hex Workshop lub Hiew). Atrybuty sekcji znajduj▒ siΩ na samym ko±cu nag│≤wka sekcji i zaraz przed nazw▒ nastΩpnej sekcji. PamiΩtaµ nale┐y ┐e bajty zapisywane s▒ w notacji intela czyli np. liczba 12345678h jest zapisana jako 78563412h.

Dobra, teraz odpalasz loadera i sw≤j prog i l▒dujesz w si. Jeste╢? :) Ok. WiΩc teraz przewijasz okienko code a┐ dochodzisz do miejsca w kt≤rym nastΩpuje ostatni skok jmp xxxxxxxx. W tym to w│a╢nie miejscu procedura rozpakowuj▒ca skacze do rozpakowanego i gotowego ju┐ do u┐ycia pliku exe. Zapisujesz ten adres gdzie ma nast▒piµ skok np. jmp 401000 oraz mnemoniki tego skoku czyli e9 i bajty odpowiadaj▒ce d│ugo╢ci skoku (w si mo┐na w│▒czyµ ich podgl▒d komend▒ code on) i wychodzisz z si oraz zamykasz tego proga. Teraz dla odmiany odpalasz Notepada i edytujesz plik scrip.ini z Procdumpa. Twoja wersja UPX powinna wygl▒daµ tak:

Pxx=UPX 0.84
gdzie xx jest kolejnym numerem skryptu, nazwa mo┐e byµ dowolna.

[UPX 0.84]
L1=OBJR
L2=LOOK E9,xx,xx,xx,xx
L3=BP
L4=EIP
L5=STEP
OPTL1=00000000
OPTL2=01010001
OPTL3=01010001
OPTL4=00030000
OPTL5=00000000
gdzie xx,xx,xx,xx s▒ w│a╢nie tymi bajtami odpowiadaj▒cymi d│ugo╢ci skoku z jmp, nazwa oczywi╢cie taka sama jak powy┐ej.

Zapisujesz to wszystko, odpalasz ProcDumpa i rozpakowujesz swojego execa u┐ywaj▒c tego skryptu. Po rozpakowaniu mo┐esz jeszcze (ale nie musisz) ustawiµ poprawny entry point bo ten wskazuje na adres jmp xxxxxxxx a nie na sam xxxxxxxx. EP obliczasz odejmuj▒c od xxxxxxxx adres bazowy (image base), czyli np. xxxxxxxx to 401000 a image base to 400000, wiec entry point to 1000.
smola


Dodatkowe informacje


S│ownik pojΩµ

Lista przydatnych tekst≤w

Poni┐ej spis materia│≤w kt≤re mo┐na namierzyµ w sieci tytu│/nazwa pliku/rozmiar:

  • Orygina│ tekstu o odbudowywaniu tabeli import≤w
    ImportReb_Essay.txt - 11445
  • PE file format - v1.7 1998/07/29
    pe.txt - 82622
  • The Portable Executable File Format by Randy Kath
    pefile.txt - 75175
  • PORTABLE EXECUTABLE FORMAT by Micheal J. O'Leary
    pe.doc - 44782
  • PORTABLE EXECUTABLE EXPORT-TABLE FORMAT by lorian [uCF/xFORCE]
    export.txt - 7115
  • Includy z nag│≤wkami PE, sekcji itp.
    imghdr.inc - 9806

smola

Linki do stron

www.crackpl.site.pl