0% found this document useful (0 votes)
204 views

Rebuild Manually The IAT & Inject DLL in A Portable Executable File

The document provides instructions for manually rebuilding the import address table (IAT) and injecting a DLL into a portable executable file without recompiling source code. It describes creating a new section to hold the injected code, then rebuilding the IAT by adding strings for imported DLLs and functions and filling out the required IMAGE_IMPORT_DESCRIPTOR structure. Pointers in the IAT are updated to reference the injected functions.

Uploaded by

kocayusuf13
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
204 views

Rebuild Manually The IAT & Inject DLL in A Portable Executable File

The document provides instructions for manually rebuilding the import address table (IAT) and injecting a DLL into a portable executable file without recompiling source code. It describes creating a new section to hold the injected code, then rebuilding the IAT by adding strings for imported DLLs and functions and filling out the required IMAGE_IMPORT_DESCRIPTOR structure. Pointers in the IAT are updated to reference the injected functions.

Uploaded by

kocayusuf13
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

Rebuild Manually the IAT & Inject DLL In a Portable Executable file

Description: This article demonstrates couple of steps to rebuild the whole IAT table and to
inject your DLL in a portable executable file without recompiling source code.

Tools to be use: Ollydbg.


Main Steps to be done: Create new Section (Manually). Re-build the IAT (Manually).

Creating new Section


A new section is required in case there are no enough places to insert the required code. There are many useful tools can do this for you. However, in this tutorial, I will show you how we can do this by hand. Before proceeding, we will brief the structure of the Image Section Header.
_IMAGE_SECTION_HEADER_ BYTE Name; union Misc; DWORD PhysicalAddress; DWORD VirtualSize; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; _IMAGE_SECTION_HEADER_

Only useful members will be described: Name: An 8-byte, null-padded UTF-8 string. The name is just a label and can be left empty. VirtualSize: The total size of the section when loaded into memory, in bytes. If this
value is greater than the SizeOfRawData member, the section is filled with zeroes. This field is valid only for executable images and should be set to 0 for object files.

VirtualAddress: The address of the first byte of the section when loaded into memory, relative to the image base. For object files, this is the address of the first byte before relocation is applied. SizeOfRawData: The size of the initialized data on disk, in bytes. This value must be a multiple of the FileAlignment member of the IMAGE_OPTIONAL_HEADER structure. If this value is less than the VirtualSize member, the remainder of the section is filled with zeroes. If the section contains only uninitialized data, the member is zero. PointerToRawData: A file pointer to the first page within the COFF file. This value must be a multiple of the FileAlignment member of the IMAGE_OPTIONAL_HEADER structure. If a section contains only uninitialized data, set this member is zero. Characteristics: Contains flags such as whether this section contains executable code, initialized data, uninitialized data. More details about Section headers in the following link:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680341%28v=vs.85%29.aspx

The first section table starts at offset F8 from PE Header offset and each section is 28 bytes long and should look like the following: F8 ********** START 00 8 Bytes 08 DWORD 0C DWORD 10 DWORD 14 DWORD 18 DWORD 1C DWORD 20 WORD 22 WORD 24 DWORD OF SECTION TABLE *******Offsets shown from here********
Name of first section header misc (VirtualSize) Actual size of data in section. virtual address RVA where section begins in memory. SizeOfRawData Size of data on disk (multiple of FileAlignment). PointerToRawData Raw offset of section on disk.
PointerToRelocations Start of relocation entries for section, zero if none. PointerToLinenumbers Start of line-no. Entries for section zero if none. NumberOfRelocations This value is zero for executable images. NumberOfLineNumbers Number of line-number entries for section. Characteristics.

From below, we can understand that the Offset of PE Header = e_lfanew = C8

So, the First Section Table should be starting from: C8 + F8 = 1C0.


The new section table should starts at offset: 1C0 + 4x28 = 260. First 8 bytes will be Name ".IAT" (ASCII: 2E 49 41 54 00 00 00 00) Next DWORD is VirtualSize = 1000h (Reverse order = 00 10 00 00)

Next DWORD is VirtualAddress = Virtual Address + Virtual Size = C000 + 230 = C230. Since our SectionAlignment is 1000 we must round this up to the nearest 1000 which makes D000h (Reverse Order 00 D0 00 00) The next DWORD is SizeOfRawData = 1000 (Reverse order = 00 10 00 00) The next DWORD is PointerToRawData = E00 (Reverse Order = 00 0E 00 00) The next 12 bytes can be left null. The final DWORD is Characteristics = E00000E0 (for code, executable, read and write). Section table should be looking as below:

Still Number of Section & SizeofImage to be changed. Offset of Number of section (word) is: Offset of PE Header + 06 = C8 + 06 = CE So, at offset CE, the value 04 00 must be change to 05 00 Offset of SizeofImage (Dword) is: Offset of PE Header + 50 = C8 + 50 = 118 So, at offset 118, the value 30 C2 must be change to 00 E0

The Final Step for New Section is to add 1000 bytes at the end of the file. We have successfully create new Section called IAT. Run the application, and it should works fine.

Re-build the IAT


The import directory entry of the import table leads us to the position of the import table inside the file image. There is a container for each imported DLL, import descriptor, which embraces the address of first thunk and the address of original first thunk, the pointer to DLL name. The First Thunk refers to the location of the first thunk; the thunks will be initialized by PE loader of Windows during running the program. The Original First Thunk points to the first storage of the thunks, where provide the address of the Hint data and the Function Name data for each functions. In the case, the First Original Thunk is not present; it will refer to where the Hint data and the Function Name data are located. The import descriptor is represented with IMAGE_IMPORT_DESCRIPTOR structures as the following definition:
IMAGE_IMPORT_DESCRIPTOR struct OriginalFirstThunk TimeDateStamp dd 0 ; ForwarderChain dd 0 ; Name FirstThunk IMAGE_IMPORT_DESCRIPTOR ends dd 0 ; RVA to original unbound IAT (table of names) not used here not used here dd 0 ; RVA to DLL name sring dd 0 ; RVA to IAT array (table of doors)

OriginalFirstThunk: It points to the first thunk, IMAGE_THUNK_DATA, the thunk holds the
address of the Hint and the Function name.

TimeDateStamp: It contains the time/data stamp if there is the binding. If it is 0, no


bound in imported DLL has happened. In new days, it sets to 0xFFFFFFFF to describe the binding occurred.

ForwarderChain: In old version of binding, it acts as referee to the first forwarder chain
of API. It can be set 0xFFFFFFFF to describe no forwarder.

Name: It shows the relative virtual address of DLL name. FirstThunk: It contains the virtual address of the first thunk arrays that is defined by
IMAGE_THUNK_DATA, the thunk is initialized by loader with function virtual address. In the absence view of the Original First Thunk, it points to the first thunk, the thunks of the Hints and The Function names.

Back to our application, lets import the DLLs and functions mentioned below: 1. KERNEL32.DLL GetModuleHandleA ExitProcess 2. USER32.DLL GetDlgItemTextA MessageBoxA SetDlgItemTextA DialogBoxParamA 3. INSERTMSG.DLL E33 Adding imports manually is just a matter of patient. Load the application with Olly, move to the new Section IAT, then add following strings with the names of all DLLs and APIs you need. Starting from 0040D07A, Select number of bytes and Select Edit, then enter API functions and DLL names (ASCII) as above.

After changing all required bytes, Should be looking like below

Now we must start filling information related to lookup table Import lookup table for Kernel32.dll (RVA) GetModuleHandleA: 00 00 D0 78 Import lookup table for Kernel32.dll (RVA) ExitProcess: 00 00 D0 8C Import Import Import Import lookup lookup lookup lookup table table table table for for for for User32.dll User32.dll User32.dll User32.dll (RVA) (RVA) (RVA) (RVA) GetDlgItemTextA: MessageBoxA: SetDlgItemTextA: DialogBoxParamA: 00 00 00 00 00 00 00 00 D0 D0 D0 D0 A8 BA C8 DA

Import lookup table for INSERTMSG.DLL (RAV) E33: 00 00 D0 F8 The above RVA address needs to be inserted in reverse order as below

After inserting these bytes, it should be looking in such way:

After the above we must fill IMAGE_IMPORT_DESCRIPTOR. Kernel32.dll OriginalFirstThunk (RVA) TimeDateStamp ForwarderChain Name: FirstThunk (RVA) User32.dll OriginalFirstThunk (RVA) TimeDateStamp ForwarderChain Name FirstThunk (RVA) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D0 50 (RVA of Import Look up table) 00 00 (Not to be use here) 00 00 (Not to be use here) D0 9A (RVA of Kernel32.dll) D0 50 (RVA of Import Look up table) D0 5C (RVA of Import Look up table) 00 00 (Not to be use here) 00 00 (Not to be use here) D0 EC (RVA of User32.dll) D0 70 (RVA of Import Look up table)

InsertMsg.dll OriginalFirstThunk (RVA) TimeDateStamp ForwarderChain Name FirstThunk (RVA)

00 00 00 00 00

00 00 00 00 00

D0 70 (RVA of Import Look up table) 00 00 (Not to be use here) 00 00 (Not to be use here) D0 FE (RVA of InsertMsg.dll) D0 70 (RVA of Import Look up table)

All the above must be filled in reverse order as below.

After filling, the IMAGE_IMPORT_DESCRIPTOR should be looking like below.

Save all the changes in Olly by selecting all these bytes, then Copy to executable file, We have completed filling all required bytes related to Import table Structure. Still we need to change the RVA address and the size of the Import Table. The RVA of Import Directory should be located at: Offset of PE Header + 80 = C8 + 80 = 148. 00400148 20 20 00 00 3C 00 00 00 (Reverse order) As you can see, the old RVA of Import table is: 00 00 20 20 Change it to the New RVA of Import Table should be: 00 00 D0 00 Old RVA for Import table size: 00 00 00 3C Change it to the New Size of import table should be: 4 x 5 x 4 = 50 (00 00 00 50) Save the changes in Olly, and then re-open it again. Jumping to RVA D050, you will noticed that the pointers to the names of the APIs where substituted by the addresses of the APIs by the Windows loader as you can see below

If we run the application now, it will crash as we should divert all the calls and jumps to the address above. If we open the virgin file, we can find out the following: DWORD DWORD DWORD DWORD DWORD DWORD PTR PTR PTR PTR PTR PTR DS:[402004] will lead to kernel32.ExitProcess DS:[402000] will lead to kernel32.GetModuleHandleA DS:[402018] will lead to user32.DialogBoxParamA DS:[40200C] will lead to user32.GetDlgItemTextA DS:[402010] will lead to user32.MessageBoxA DS:[402014] will lead to user32.SetDlgItemTextA

Lets change these addresses to the real one: DWORD DWORD DWORD DWORD DWORD DWORD PTR PTR PTR PTR PTR PTR DS:[402004] must be change to DWORD PTR DS:[40D054] DS:[402000] must be change to DWORD PTR DS:[40D050] DS:[402018] must be change to DWORD PTR DS:[40D068] DS:[40200C] must be change to DWORD PTR DS:[40D05C] DS:[402010] must be change to DWORD PTR DS:[40D060] DS:[402014] must be change to DWORD PTR DS:[40D064]

After entering these bytes, it should be looking like below:

Save the changes in Olly. Run it, and it should be working fine. I have demonstrated in this tutorial how to re-build the IAT table manually. Now, if you are interested to inject the function E33 from insertMsg.Dll, all you have to do the following change. Jump to any free space in IAT Section and write these codes: CALL InsertMsg.DLL MOV EAX, 04001000 (old EIP) Jmp EAX

Greetings & Thanks ARTeam & Tuts4you for providing useful and valuable tutorials. Goppit | Kao | Nacho_dj | tonyweb | deepzero |

You might also like