PE file structure (III)
Reference
Book: encryption and decryption
Video: Little Turtle decryption series video
Input table
Input Function, indicating that the code is called by the program, but its code is not in the program code, and the function in the DLL. For these functions, the executable files on the disk only retain the relevant function information, such as the function name and DLL file name. Before running the program, the program does not save the address of these functions in the memory. When the program runs, the Windows loader loads the related DLL into the memory and associates the input function commands with the addresses in the memory. The input table (import table) is used to save information about these functions.
The datadirectory [16] array in image_optional_header stores the RVA and size of the input table. You can use the RVA program to find the input table through imagebase + RVA, or use RVA to calculate the file offset address, view the executable files on the disk, and find the input table through the file offset address.
The input table starts with an image_import_descriptor (IID) array. Each DLL that is implicitly linked to the PE file has an IID, And the last unit of the IID array is represented by null.
Image_import_descriptor structure:
typedef struct _IMAGE_IMPORT_DESCRIPTOR {_ANONYMOUS_UNION union { //00hDWORD Characteristics;DWORD OriginalFirstThunk; } DUMMYUNIONNAME;DWORD TimeDateStamp; //04hDWORD ForwarderChain; //08hDWORD Name; //0ChDWORD FirstThunk; //10h} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
Here, name is the pointer to the DLL name. Originalfirstthunk points to an image_thunk_data array. The input name table Import Name table (INT) is used to save the function. The firstthunk also points to the image_thunk_data array which is called the input Address Table import Address Table (IAT ).
Image_thunk_data structure:
typedef struct _IMAGE_THUNK_DATA32 {union {DWORD ForwarderString;DWORD Function;DWORD Ordinal;DWORD AddressOfData;} u1;} IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32;
When the maximum value of image_thunk_data is 1, it indicates that the function is input in sequence number mode. At this time, 31 is regarded as the function number. When the maximum bit is 0, it indicates that the function is input in the form of a string function name. At this time, the value of image_thunk_data is the RVA that points to the structure of image_import_by_name.
typedef struct _IMAGE_IMPORT_BY_NAME {WORD Hint;BYTE Name[1];} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
Hint indicates the serial number of the output table where the function resides in the DLL. It is not required.
Name indicates the function name. It is an ASCII string ending with 0 and its size is not fixed.
Int stores the function information that this program imports into this DLL. It is fixed and will not be modified. However, IAt will be overwritten when the program is loaded. When the program is loaded, it will be rewritten by the PE Loader as the real address of these functions in the memory. That is, change the original image_import_by_name to the real address of the function.
So why do we need two image_thunk_data arrays?
When a program is loaded, IAt will be overwritten by the PE Loader. The PE Loader first searches for int, And the PE Loader iteratively searches for each pointer in the int array, find the real address of the function in the image_import_by_name structure pointed to by the int in the memory, and replace it with the value in the original IAT. After the process is completed, int is useless, and the program can run normally only through IAT.
As shown in the figure below, this is when the executable program is in the disk:
This is when the program is loaded:
Instance analysis:
First, find the input table RVA, and use the last item image_data_directory in image_optional_header to know that the offset between the input table and the PE file header is 80 h. Then, you can find the input expression RVA.
Image 1
But this is RVA, not the file offset address. You can see through the conversion that the input table's file offset address is 850 H,
Check 850 H, that is, IID. You can see that this program has two IIDS, that is, two DLL links. If you see an IID, you can know that its originalfirstthunk is 2098 H firstthunk, the converted file offset addresses are 898 H and 80 CH, respectively.
Image 2 IID Array
Check originalfirstthunk and firstthunk. We can find that int and IAT are the same content. First, let's look at the information of the first function. Because the first one is 1, 00002122 h indicates RVA of image_import_by_name, converted to file offset 922 H
Image 3 int and IAT
Check the function name for 922 H.
Figure 4:
We can see from the above that the int and IAT content of the program in the disk are the same, all point to image_import_by_name. Use od to load the program and view the int and IAT Contents
Image 5 Int
Image 6 IAT
It can be found that the int has not changed. IAT is changed to 77d3c702h, and RVA in IAT is changed to the real address of the function.
Check 77d3c702h and you will see this function.
Image 7
PE file structure (III)