---------------------------------------------------------------------------------------------
Patchowanie modulow DLL w pamieci by mIG-21^CookieCrK
---------------------------------------------------------------------------------------------

Poziom trudnosci: latwy (jesli czytelnik zna format PE :-))
Narzedzia:
	1. WinICE
	3. Jakikolwiek kompilator pod Windows

Zastosowanie/cel:
	InterState'82 (patrz nizej)
---------------------------------------------------------------------------------------------

Na samym poczatku chcialbym wyjasnic, ze tutorial NIE podaje kompletnej metody zlamania
zadnego programu. Jesli ktos szuka dokladnego opisu crackowania InterState'82 (z offsetami,
itd.) to zapewne zle trafil.

Dosyc tego nudzenia, przejdzmy do konkretow. Jakis czas temu w moje rece dostala sie gra
InterState'82. Problem polegal na tym, ze na plytce nie bylo sciezki audio i nalezalo
spatchowac program. Wzialem sie do roboty i po 20 minutach mialem zlokalizowane odpowiednie
miejsce w kodzie. Niestety wprowadzenie tych zmian na stale okazalo sie trudniejsze, poniewaz
gra zawierala 1 plik exe o rozmiarze ok.50kb i kilka duzych plikow dll. Okazalo sie, ze
praktycznie caly kod znajdowal sie w tych dll'ach. Dodatkowo, wszystkie pliki byly spakowane
(NeoLite'm). Poniewaz ProcDump nie potrafi rozpakowac plikow dll pozostalo jedynie patchowanie
w pamieci. W przypadku plikow exe, gdzie ImageBase jest staly, nie ma z tym problemu. Niestety
dll'e moga byc (i najczesciej sa) relokowane pod inny adres. Ten tutor opisuje wlasnie metode
obliczania adresow w relokowanym dll'u.
Zaczynamy od obliczenia adresu wzgledem bazy (ImageBase). Odpalamy SoftIce'a i znajdujemy
miejsce w dll'u, ktore chcemy patchowac (przestajemy trace'owac na nim). Patrzymy na adres
w EIP (powinien byc stosunkowo wysoki). Teraz wpisujemy polecenie MOD (wyswietla ono wszystkie
moduly zaladowane do systemu). Nas interesuje tylko kolumna Base. Szukamy nazwy naszego dll'a
i spisujemy sobie adres jego bazy. Teraz wpisujemy w SoftIce: ?eip-[adres spisanej bazy]
(klamry sa niepotrzebne). W ten sposob otrzymamy przesuniecie (offset) miejsca do patchowania
wzgledem bazy dll. Jest to wartosc stala. No dobrze, mamy offset, ale skad wziac adres bazy?
Jesli mamy SoftIce, to wyciagamy go po prostu poleceniem MOD, ale chcac zrobic program
automatycznie zmieniajacy dane miejsce w obszarze pamieci dll'a, musimy sie posluzyc inna
metoda. W sklad systemu Windows wchodzi biblioteka toolhelp.dll, ktorej zadaniem jest
zdobywanie informacji o uruchomionych w systemie procesach. Pierwsza czynnoscia, jaka musimy
wykonac jest tzw. migawka systemu. Do tego celu sluzy funkcja CreateToolhelp32Snapshot()
Aby zdobyc dane na temat zaladowanego dll'a wywolujemy ja z parametrami: TH32CS_SNAPMODULE i 
identyfikatorem procesu, ktory zaladowal dany modul. Nastepnie wywolujemy funkcje:
Module32First(), i w petli Module32Next(). Za kazdym razem porownujemy zawartosc czlonka
szModule zwroconej struktury z nazwa naszego dll'a-celu. Gdy te dwie wartosci beda rowne,
zachowujemy wartosc czlonka modBaseAddress. Jest to wskaznik (pointer) zawierajacy adres bazy.
Wystarczy teraz do tego adresu dodac nasz obliczony, staly offset i mamy miejsce w pamieci,
ktore musimy patchowac. Do tego celu jak zwykle uzywamy WriteProcessMemory(). Robimy to w taki
sposob: Wywolujemy funkcje OpenProcess z identyfikatorem procesu, ktory zaladowal dll'a jako
3cim parametrem. W tym celu mozemy uzyc czlonka th32ProcessId ze struktury MODULEENTRY32
(zwroconej przez Module32Next()). Zwrocony przez OpenProcess uchwyt procesu wykorzystujemy
jako parametr do WriteProcessMemory. Jako wskaznik do bufora docelowego podajemy sume
obliczonego stalego offsetu i zdobytego przez nas adresu bazy. Pozostale parametry sa chyba
oczywiste. Tak oto wprowadzilismy zmiany do kodu zaladowanego dll'a. Bede one wazne az do
momentu zamkniecia procesu, ktory go wczytal, lub do wywolania FreeLibrary() na bibliotece.
Poniewaz tutorial jest mimo wszystko "troche" zagmatwany (a ja prawdopodobnie nie jestem
dobrym nauczycielem :-)), dolaczam do tekstu zrodlo w C funkcji dokonujacej tych zmian.
Jesli ktos nie zrozumial tutoriala, to radze przesledzic ten kod, moze on troche ulatwi nauke.
Btw. ten typ zabezpieczen nie jest popularny, z CD-check'iem w dll'u spotkalem sie tylko 2 razy
(w Unreal'u i InterState'e), z tym ze ten pierwszy nie byl spakowany. Sadze, ze temat zostal
wyczerpany. Nie jest to trudne zagadnienie i przypuszczam, ze wiekszosc osob sama by na to
rozwiazanie wpadla. Jedyna przeszkoda moglby byc brak opisu API biblioteki ToolHelp. Niemniej
jednak chcialem sie podzielic swoimi doswiadczeniami z tym rodzajem zabezpieczeniem.

mIG-21^CookieCrK <mIG21@box43.gnet.pl>

PS. Jesli bedzie zapotrzebowanie na opis API ToolHelp'a, to moge wyslac go na strone.
    W razie potrzeby, mozna mailowac na podany wyzej adres.

PS2.Nie radze modyfikowac w ten sposob dll'i systemowych, bibliotek Visual Basica, C/C++,
    itp. Windows uzywa tej samej kopii dll'a dla wszystkich procesow, wiec (prawdopodobnie)
    cos nie bedzie dzialalo taki sposob, jak bysmy tego chcieli.

PS3.Do zdobycia ImageBase DLL'a moze rowniez posluzyc biblioteka psapi.dll (a dokladniej
    funkcja GetModuleInformation().

http://www.cookiecrk.z.pl/
e-mail: cookiecrk@z.pl
