Dodanie do IAT wlasnej Dll'ki

0

Domyślam się że nie ale luknij tu :
Moja strona :
http://win32prog.republika.pl/asm/asm.html

http://win32prog.republika.pl/

I na 4programmers

http://4programmers.net/Forum/viewtopic.php?id=104575

to zobaczysz w jakie g.. sie pakujesz .

Na razie nie dokończyłem rozważań na temat PE i zanim dojdę do importów to miną
miesiące [green]

Namiar na Ziny który Ci podałem jest OK . Sciągnij wszystko i przejrzyj , jest trochę
grzebania , ale mysle że znajdziesz coś ciekawego.

Zresztą widze Deusa on posiada więcej wiedzy na ten temat ...
Pozdro

0
dzejo napisał(a)

Zresztą widze Deusa on posiada więcej wiedzy na ten temat ...

widać, rzucam się w oczy [rotfl]
OK, przejdę może do rzeczy: w C ostatnio piszę rzadko, do tego temat jest bardziej hm... niskopoziomowy więc będę się wspierał asmem.

W plikach PE występuje sporo różnych katalogów /a konkretnie to w nagłówku/, m. in. importów. Zanim przejdę do jego omówienia wspomnę czym jest RVA. RVA to mówiąc łopatologicznie adres liczony względem początku modułu. Mały przykład: powiedzmy, że nasz program znajduje się w pamięci pod adresem 0x400000 /standardowy IMAGE_BASE dla plików exe, IMAGE_BASE to też uchwyt do modułu... tak, w tym przypadku uchwyt jest wskaźnikiem/ natomiast jakaś_funkcja jest pod adresem 0x4010FF /czyli od bajtu 0xFF pierwszej sekcji... chyba, że adres pierwszej sekcji będzie niestandardowy/. RVA tej funkcji wynosi więc 0x4010FF - 0x400000 czyli 0x10FF. Należy pamiętać, że RVA nie zawsze jest równe offsetowi w pliku binarnym - sekcje mogą mieć inny /większy/ rozmiar w pamięci niż w pliku, np. sekcja '.bss' zawierająca wyłącznie dane niezainicjowane nie istnieje fizycznie w pliku - istnieje tylko wpis w nagłówku określający jej charakterystykę i rozmiar w pamięci.
Po dokładny opis wszystkich struktur i pól odsyłam na msdn, opiszę tylko to, co jest nam potrzebne do podstawowych operacji na tablicy importów /forwardowanie chyba sobie odpuszczę/. Katalog importów to tablica struktur składających się z 5 dwordów. Pierwsze 3 pola w sumie nas nie interesują /charakterystyki, info o czasie i forwardowaniu/. Pole 4 to RVA nazwy modułu, zaś 5 to również RVA/w sumie jak wszystkie adresy w strukturach PE/, który wskazuje na tablicę struktur IMAGE_THUNK_DATA /chyba tak to się nazywało... nie chce mi się sprawdzać... po padnięciu dysku nawet Lorda nie mam/. Katalog importów /jak każdy inny/ musi być wyrównany do 0x20, kończy go zaś pusty wpis - wszystkie 5 dwordów wyzerowane /ew. -1.../. Tyle jest wymagane do działania samego katalogu.
Teraz kolejna tablica /czy też może tablice/ wskazywana przez 5 dword katalogu. Jej zawartość to dwordy, sama również kończy się pustym /zerowym/ dwordem. Każdy wpis można interpretować na 3 sposoby, jako adres nazwy forwardowanej funkcji /to nas nie obchodzi aktualnie/, jako numer funkcji z pliku dll /ordinal, każda exportowana funkcja ma przypisany przy eksportowaniu numer/, bądź jako wskaźnik na... kolejną strukturę zawierającą hint /word, w sumie zbędny... zwykle 0/ i nazwę funkcji. Wskaźniki jak się pewnie domyślacie to RVA, ordinal zaś ma wartość 0x80000000 + numer_funkcji /czyli najwyższy bit dworda ustawiony - znacznik ordinala/. Thunki są podmieniane przez systemowy loader na adresy importowanych funkcji. Dobra, trochę namieszałem... Mały przykład w asm /pod fasma/:

format PE Console

section '.deus' code readable executable

entry $
        jmp     $

        align   0x20
  data import   ; oznacz adres jako poczatek katalogu importow
        dd      0, 0, 0, RVA _nazwa_liba1, RVA _thunki_liba1
        dd      0, 0, 0, RVA _nazwa_liba2, RVA _thunki_liba2
        dd      0, 0, 0, 0, 0  ; pusty wpis - koniec
  end data      ; oznacz jako koniec

_nazwa_liba1    db 'libek1.dll', 0
_nazwa_liba2    db 'jakis_inny_libek.dll', 0

_thunki_liba1:
Proc_1_z_liba   dd RVA __Proc1_z_liba1  ; import porzez nazwe
Proc_2_z_liba   dd RVA 0x80000020       ; import poprzez ordinal funcji o numerze 0x20
                dd 0                    ; koniec wpisow dla tej biblioteki
_thunki_liba2:
inna_procka     dd RVA __inna_procka
                dd 0

__Proc1_z_liba1 dw 0                    ; hint - podpowiedz dla loadera /ordinal/
                db 'jakas_procka_z_libek1', 0
__inna_procka   dw 0
                db 'insza_procka_z_inszego_liba', 0

ok, omawiamy... a jest co omawiać? Wszystko zgadza się z tym co napisałem wcześniej, ale co tam... W katalogu importów widzimy 3 wpisy /3 jest pusty - koniec katalogu/. Zbędne dla nas pola są wyzerowane. Pierwszy wpis powoduje załadowanie biblioteki o nazwie 'libek1.dll' /jak widzimy nazwa dll'a to zwykły ansi string zakończony nullem/. Z 'jakis_inny_libek.dll' jest podobnie. Tablica _thunki_liba1 zawiera 2 wpisy + terminator. Pierwszy wskazuje na strukturę costam_IMPORT_BY_NAME /nie chce mi się szukać ;P/, drugi dword to ordinal - najwyższy bit ustawiony oznacza, że niższy word jest numerem, z jakim dana funkcja została wyeksportowana i wedle którego na zostać zaimportowana /w tym wypadku 0x20/. Teraz ostatni element układanki czyli IMPORT_BY_NAME - word na początku /hint/ sugeruje jaki ordinal ma dana funkcja, ale to tylko podpowiedź /aby system najpierw sprawdził czy funkcja o tym ordinalu jest poszukiwaną zamiast przeszukiwać wszystko po kolei... zwykle i tak musi ;P/ , znaczenie ma tutaj nazwa zapisana po nim. Wielkość liter ma znaczenie! I tu może wtrącę małą uwagę: autor tematu się myli - IAT to tablica adresów importowanych funkcji, nie katalog importów. W naszym przypadku IAT to obszar od _thunki_liba1 do __Proc1_z_liba1. OK, może teraz jakiś działający program?

format PE GUI

        push    0
        push    0
        push    _info
        push    0
        call    [MessageBoxA]
        push    0
        call    [ExitProcess]

_info   db 'Mam recznie zbudowana tabele importow!?', 0
        align   0x20
  data import   ; oznacz adres jako poczatek katalogu importow
        dd      0, 0, 0, RVA _kernel32, RVA ExitProcess
        dd      0, 0, 0, RVA _user32, RVA MessageBoxA
        dd      0, 0, 0, 0, 0  ; pusty wpis - koniec
  end data      ; oznacz jako koniec

_kernel32       db 'kernel32.dll', 0
_user32         db 'user32.dll', 0

; poczatek IAT
ExitProcess     dd RVA _ExitProcess
                dd 0
MessageBoxA     dd RVA _MessageBoxA
                dd 0
; koniec IAT
_ExitProcess    dw 0 ; hint - i tak w kazdej wersji dlla sa inne ordinale
                db 'ExitProcess' ; za nulla robi hint z _MessageBoxA
_MessageBoxA    dw 0
                db 'MessageBoxA'

W przypadku braku informacji o entry poincie fasm ustawia na poczatek pierwszej sekcji. Jeżeli sekcja nie jest zdefiniowana fasm tworzy sekcję '.flat' o uniwersalnych atrybutach /ERW/. Co robi nasz programik? Wyświetla messageboxa i kończy proces /można też wrócić do kernela poprzez ret jeżeli jest to jedyny wątek/. Jak już pisałem loader windowsowy podmienia wpisy w thunkach /IAT/ na adresy importowanych funkcji. W sumie to to są dla mnie oczywiste rzeczy ale większość pewnie nie wie, gdzie góra a gdzie dół więc pytać :-) Jak widać IAT i katalog importów nie są zbyt skomplikowane /exporty są 'ciekawsze'/. Jak dodać własny wpis do katalogu - dll'kę? Można sprawdzić czy za katalogiem nie ma przypadkiem 20 bajtów /czyli jeden wpis/ wolnej przestrzeni... ale można sobie odpuścić - jeszcze nie widziałem execa /może za wyjątkiem tych cudów z borland'ów/, który miałby tam odpowiednio luźno, zwykle są 'tam' za wąskie ;P. Co nam pozostaje? Najprościej to będzie powiększyć ostatnią sekcję i na jej koniec przenieść katalog powiększony o jeden wpis... ale sam katalog, z powyższego kodu chyba jasno wynika, że thunków ruszać nie wolno /no... prawie, bo dać się da wszystko/. Ew. można też zobaczyć czy na końcu wspomnianej sekcji nie ma odpowiedniej liczby zer. Trzeba sprawdzić, czy rozmiar w pamięci nie jest większy od fizycznego - "takie niby .bss", dopisanie czegoś mogłoby spowodować różne dziwne zachowania programu jeżeli autor zapomniał o inicjowaniu - program zamiast 0 może odczytać np. fragment nazwy naszego liba... a jak tam miał być wskaźnik to się wysypie :>. Jedyne wyjście to dodanie nowej sekcji /kiedyś można było umieścić katalog w nagłówku pliku, ale teraz to już raczej nie trybi/. I tu znów trzeba na uważać - Overlay czyli doklejenie danych na końcu execa, często stosowane przez samorozpakowywacze i inne takie - w nagłówku pliku jest pole SizeOfImage określające rozmiar obrazu wykonywalnego, wszystko co 'wystaje' jest przez system ignorowane i może być potem przez program wygodnie wczytywane. Dobra, tyle teoretyzowania. Jakieś podstawy podałem, potem napiszę mały programik dodający nowy wpis. W sumie to temat jest bardzo rozległy /jeżeli chodzi o budowę plików PE/, to co napisałem jest niezrozumiałe bez podstawowej wiedzy o PE... żeby tą wiedzę podać musiałbym napisać ze 4x więcej i opisać kilkanaście struktur... to już innym razem. OK, piszcie czego nie rozumiecie, ja się zajmę swoimi sprawami a jak będę miał chwilę to rzucę kawałkiem kodu /może nie na wszystkie metody, ale.../.

0

IAT to tablica adresów importowanych funkcji

Tak właśnie działał przykład zamieszczony przez "przechodzień" .A biblioteka nie była
dodawana lecz wkompilowana w .exe . Modyfikowany był tylko wpis dotyczący 'strcmp' poprzez
bibliotekę .

Więc zapytam dla pewności , wystarczy jedynie aby program załadował .dll
i wykonał kod z niego , bez mieszania w importach .

@Deus
Pytanie ignoranta .
Czy koniecznie trzeba zamieszczać nazwy funkcji zawartych w dodanym .dll ,
czy wystarczy dodać tylko informację o nazwie biblioteki a resztę olać .
I czy jest szansa że wtedy wykona się kod inicjujący bibliotekę , bo to chyba by wystarczyło .
Wystarczyło ... to się kurcze rozlazie wszystko bo nie ma miejsca .. :|
Ale bez szczegółów , Tak - czy Nie :-D

Nie grzebałem na razie tak dokładnie w Importach ,z tąd pytanie .
na razie przeryłem budowę PE , sekcje , dodawanie kodu , i takie tam pierdoły
wątek wyprzedził trochę to co do tej pory przeanalizowałem.
Biorę się za lekturę bo mnie to zaciekawiło...

0

Musi być co najmniej jeden import. Ale całość można zmieścić w 28 bajtach+lib:

  • 20 bajtów - wpis
  • 2 thunki /ordinal + null/
  • nazwa
    Ordinala można spisać dowolnego /ważne, żeby taki być w bibliotece/. Mnie jeszcze nigdy ord = 2 nie zawiódł ;P
    Hmmm... na Windows Server 2003 wystarczy tylko pusty thunk :| Z tego co pamiętam to większość wersji Win wymaga jednak pojedynczego wpisu - zawsze się jeden zostawia w packerach ze statycznym ładowaniem bibliotek /wszystkie liby ładowane przez oryginalne importy są zawarte w importach unpackera/.
    czyli na 2k3 przejdzie takie coś:
    dd 0, 0, 0, RVA $ + 28, RVA $ + 4
    dd 0, 0, 0, 0, 0
    db 'lib.dll', 0

    czyli pierwszy dword wpisu jest jednocześnie jedynym thunkiem a nazwa jest za ostatnim wpisem. 20 bajtów + nazwa :>

@poniższy post - dll to Dynamic Link Library, więc brak exportów mija się z celem przy ładowaniu statycznym /przez tablicę importów/.

p.s. piszcie mnie z małej litery :>

0

No dobra , trochę dziwne bo biblioteka wcale nie musi udostępniać jakichś funkcji
dla .exe , może zostać załadowana wykonać swój kod i podziękować .

p.s. piszcie mnie z małej litery

A niby czego ? , nie bądz taki skromny w SPACJA końcu można się dowiedzieć paru reczy
z tego co piszesz :-D .

0

Moge tylko polecac ten link http://www.tuts4you.com/blogs/download.php?list.30
:D naprawde wiele dobrych tutoriali :-) .Bardzo przejrzyscie i elegancko, sposob dodania nowej sekcji do kodu pokazuje "Manually Adding A Section", goraco polecam. :-P

0

Przeprowadziłem procedurę ze strony LordaPE dodania dll do Notepad .
Niestety nie mam co dalej wnikać w ten sposób bo program po modyfikacji
wywala się na ryja , czyli do niczego .Nie jest tak cudownie jakby się wydawało .
Dodaje sekcję do pliku , przebudowuje importy - ale Notepad po odpaleniu nie działa
zmiana Entry Point na wszelkie inne nie pomogła , lipa....

A dlaczego ? może dla tego :

Ponieważ Notepad w wersji XP ( jak i inne pliku wchodzące w skład ) zawiera tzw. Bound Import .
Utrudnia to wszelkie manipulacje na pliku bo wpisy w katalogach są zablokowane
nazwami Bibliotek i wszelkie manipulacje na pliku kończą się źle .
Czyli zamiast sekcji import pliki .exe zawierają wpisy ( bo to nawet nie sekcja) o bibliotekach
jakich program używa .

Nie można do takiego pliku dodać żadnej dodatkowej sekcji ,fizycznie można ale nie da się jej
uruchomić , bo nie ma miejsca przez
ten cholerny Bound Import na dodanie wpisu-katalogu o nowej sekcji , dodanie takiego
katalogu uszkadza plik .
Natknąłem się kiedyś na ten problem pisząc wirusa PE , dodającego sekcję do pliku .
Musiał on ostatecznie rozpoznać pliki z Bound Import i odpuścić je sobie .
No chyba że jest jakaś metoda aby to ominąć .
Ale z tego co oglądałem w Hex edytorze , to Notepad po zabiegu LordemPE jest
po prostu zrypany .

Nasuwa się więc inne rozwiązanie , do plików które nie zawierają Bound Import ,
można go dodać z wpisem o bibliotece którą chcemy załadować , spróbuję właśnie
tak ...

0

oj dzejo, dzejo... a próbowałeś może usunąć katalog Bound Import z pliku? Ustaw offset i rozmiar na 0 i wtedy spróbuj dodać, boundy są opcjonalne... Na moje oko obszar Bound Import po wyzerowaniu i wyrównaniu adresu do 0x20 świetnie nadaje się do umieszczenia katalogu importów. W każdym razie Notepad z WinServ2k3 sp1/identyczny - albo prawie - jak w XP sp2/ po takiej operacji ładuje dodatkowy pakuneczek aż miło... /normalnie, bez usunięcia boundów faktycznie się sypał/ :>

0

Ale jeśli są , to są brane pod uwagę przy ładowaniu pliku .
Miełem jednak nadzieję że dodanie bound będzie łatwiejszym sposobem na załadowanie
biblioteki ,
dodałem więc ręcznie dane o bibliotece , ale dupa , i tak musi być jeszcze powiązanie
z symbolami w importach i na razie utknąłem .
Idę odpocząć bo mi oczy zgwożdziały od tych Hexów 8-O .

0

Ale jeśli są , to są brane pod uwagę przy ładowaniu pliku .

właśnie, jeżeli są - wywal wpis o katalogu bound z nagłówka - katalog importów zawiera wszystkie informacje potrzebne do załadowania modułu... a przynajmniej taki mi się wydaje... SOA#1: u mnie działa ;P

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0