Rebuild Manually The IAT & Inject DLL in A Portable Executable File
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.
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.
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.
OriginalFirstThunk: It points to the first thunk, IMAGE_THUNK_DATA, the thunk holds the
address of the Hint and the Function name.
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.
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 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)
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)
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]
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 |