Witam, mam pytanie odnośnie dopisywania kodu do pliku. Wiem jak to zrobić, ale załóżmy, że dawniej pisane wirusy same dopisywały swój kod do innych plików i go wywoływały. Moje pytanie brzmi: jak dopisać kod do jakiegoś pliku (np exe) i go wywołać, skoro wcześniej musiałby być skompilowany by został uruchomiony ? Dla przypomnienia tak działały przykładowe wirusy, które wstrzykiwały swój kawałek kodu. Pozdrawiam.
Piszesz wirusa? To już niemodne.
Podsumowując: przeczytałeś gdzieś jak to niby działa i zachciało się wirusa napisać?
Jak już wyżej zauważono, to już niemodne. Idź się poucz czegoś kreatywnego.
Mistrzem w RE nie jestem, ale w przypadku plików PE będzie to mniej więcej tak: tworzysz nową sekcję, oznaczasz ją jako wykonywalną, wrzucasz tam kod swojego wirusa, zmieniasz pole AddressOfEntryPoint w nagłówku na początek dodanej sekcji, później trzeba na koniec kodu wstawić adres skoku pod oryginalny kod. W praktyce jest to jeszcze bardziej skomplikowane, kod musi być odpowiednio przygotowany (nie możesz tam po prostu wrzucić wyniku kompilacji delphi/c++ ;)), trzeba pamiętać o ewentualnych relokacjach, importach. Jeżeli to wszystko ma modyfikować sam kod wirusa to jest to jeszcze trudniejsze.
Rzecz na pewno ciekawa, ale IMO nie poradziłbyś sobie z czymś 10 razy prostszym. Polecam ^ rady kolegów :).
A nie prościej napisać złośliwy program i udostępnić go jako hot_naked_teens_xxx_blondie.exe?
@msm
Wystarczy, że masz dostęp do LoadLibrary() / GetModuleHandle() (obie funkcje siedzą w bibliotece KERNEL32.dll), funkcję pobierającą adres z załadowanych bibliotek (oryginalnie GetProcAddress() ) można z łatwością samemu napisać lub znaleźć na google.
Metoda 1 - bazę kernela sobie pobierz przez skanowanie modułów z PEB, potem skanujesz eksporty KERNEL32.dll własną procedurą GetProcAddress() w poszukiwaniu LoadLibrary() w kernelu i masz wszystko czego potrzebujesz, BEZ tablicy importów, proste jak drut i używane od lat w exe-pakerach / protektorach / wirusach i innych ustrojstwach mieszających w formacie PE
http://www.ragestorm.net/blogs/?p=369
Zalety - nie wymaga ingerencji w oryginalne struktury PE-ka
Wady - jakby nie patrzeć pobieranie bazy bibliotek przez PEB jest nieudokumentowaną metodą
Metoda 2 - skanujesz tabele importów PE-ka i szukasz wpisów LoadLibrary() / GetModuleHandle() / GetProcAddress() w 99% przypadkach znajdziesz te funkcje w każdym exeku i dllce i potem w dopisanym kodzie, po prostu odwolujesz się bezpośrednio do ich adresów
Zalety - ładna integracja z oryginalną aplikacją
Wady - tych funkcji może tam po prostu nie być
Metoda 3 - dopisujesz te funkcje do istniejącej tablicy importów
Zalety - jeszcze łądniejsza integracja z aplikacją
Wady - cała masa, przepisanie oryginalnej tabeli importów, ewentualne rozszerzenie sekcji importów (co pociąga inne konsekwencje)
Metoda 4 - tworzysz własną tablicę importów z wpisami LoadLibrary() / GetProcAddress(), ewentualnie wszystkimi innymi bibliotekami i funkcjami jakie chcesz, a oryginalną tabelę importów wypełniasz przed skokiem do OEP, jest to chyba najpopularniejsza metoda.
Zalety - prostota, zbudowanie własnej tabeli importów jest po prostu wygodne
Wady - konieczność wypełnienia oryginalnej tabeli importów aplikacji, konieczność zadbania o statyczne podlinkowanie oryginalnych bibliotek z oryginalnej tabeli importów
@Bartosz Wójcik - Dzięki!
O tym że wystarczy LoadLibrary / GetModuleHandle wiedziałem, to że GetProcAddress można sobie samemu napisać już nie, ale to i tak tylko jedna funkcja więcej.
Co innego metody - szczerze mówiąc wpadłem tylko na metodę 2 i 3, przy czym 2 odrzuciłem, nie pamiętam dlaczego ale chyba załadowałem jakiś program i nie znalazłem tych funkcji albo po prostu odrzuciłem na wszelki wypadek. Zostało mi tylko 3 i po prostu na myśl o przepisaniu całej tablicy importów i dopasowaniu reszty programu do niej (rozmiar się w końcu zmieni) się poddałem (wiadomo że prędzej czy później bym to zrobił, ale jakoś po prostu nie miałem zapału do grzebania w tym)...
Za to 1 (szczególnie) i 4 wyglądają ciekawie, nawet jeśli tego w końcu nie napiszę to warto będzie o tym poczytać. Chociaż chyba jak już mam wszystko na tacy to zrobię jeszcze jedno podejście, w końcu modyfikowanie programu na dysku jest pozbawione sensu jeśli nie można wywołać żadnej funkcji...
A czy nie jest tak, że kernel32.dll jest zawsze dostepne i załadowane? przykładowo, zawsze można zrobić GetProcAddress na funkcji z kernel32.dll bez uprzedniego LoadLibrary i zadziała. Wydaje mi się, że LoadLibrary można wykreślić z listy funkcji potrzebnych na początku.
Kumashiro, O_o, mf, gdzie napisałem że chce pisać wirusa ? Po pierwsze chodziło mi o zasade a po drugie nie pisze wira tylko chciałem wiedzieć jak to było wcześniej robione więc nie dopowiadajcie sobie historyjki.
Bartosz Wójcik napisał(a)
LoadLibrary nie można wykreślić, bo jak inaczej załadujesz biblioteki inne?
Może wyrażę się jaśniej. Potrzebne są dwie funkcje: zestawLoadLibrary
+GetProcAddress
, alboGetModuleHandle
+GetProcAddress
. W drugim przypadku zakładamy że kernel32.dll jest już załadowany, a dalsze funkcje, w tym LoadLibrary, pobieramy przez GetProcAddress.
GetProcAddress jest funkcją z biblioteki KERNEL32.dll, więc skoro masz do niej dostęp to KERNEL32.dll jest już załadowany hehe :)
Jak już wspomniano, nie muszą to być prawdziwe te funkcje, mogą być napisane samodzielnie (nie wnikam tu na ile łatwe bądź trudne to będzie).
PS. a tutaj pokazano, jak pobrać "handelek" na kernel32.dll bez GetModuleHandle, jest i gotowiec na GetProcAddress
. Nie sprawdzałem, ale jeśli to działa, to "jesteśmy w domu".