JIURL PE study summary format (two) - the output function of the PE file: JIURL Home: http://jiurl.yeah.net/ Date: 2003-4-24
Generally, the output function is in the DLL. We will detail the various structures of the output function, and the output function and its related structure are placed in the PE file by one example. And how to find these things in the PE file. A found function in the file. 1.1 Get the location of Pe Header in the file. You can determine the location of the PE Header in the file through the member E_LFANew of the DOS HEADER structure. 1.2 Get the number of documents. Determine the location of the PE Header in the file, you can determine the position of the members FileHeader and member OptionalHeader in the PE header in the file. Depending on the value of member Numberofsections in FileHead, the number of files world segments can be determined, that is, the number of elements in the chart array. 1.3 Get the location of the section table in the file. PE Header can get the start position of the section table in the file in the location of the PE Header structure in the location of the file. The size of the PE Header structure can be determined by the size of Signature plus the size of the FileHeader plus the sizeOfoptionalHeade in the FileHeader. In fact, SIZEOFOPTIONALHEADE is also the size of the Optional HEADER, which is also fixed, so the size of the entire PE Header structure is also fixed. However, in order to ensure the size of the FileHeader with the size of Signature, add the SizeOfOptionalHeade in FileHeader to determine comparison insurance. 1.4 Get the location where the output function is in the file. In step 1.2, we identified the number of files in the file, and we determined the position of the section table in the file in step 1.3. Now determine the location where the output function is in the file. Take the first item in the DataDirectory array in the Optional header in Pe Header, that is, the output function item. Each of the DataDirectory [] array is an Image_Data_directory structure, which is defined as follows. Typedef struct _image_data_directory; dword size;} image_data_directory, * pimage_data_directory; obtains the value of the member VirtualAddress in the first item in the DataDirectory array. This value is RVA in the resource section in memory. If the value of this RVA is 0 indicates that there is no output function in this PE file. Then, according to the number of the festival, traversal table array. That is, every section item from 0 to (the number of tables - 1). Each section of the RVA in memory is starting from the value of the member VirtualAddress field of the section entry (including this value), and the value of VirtualAddress Misc.virtualsize ends (excluding this value). We traverse the entire section table, see the RVA of the output function we have acquired, which section is within the RVA range of the RVA. If you are within the scope, you find the section table item where the output function is located. The value in the PointertorawData in this section is the location where the output function is located in the file. The value in the VirtualAddress in this section is the RVA in the memory where the output function is located. If the RVA of the output function subtracts the RVA in which the output function is located, the output function can be obtained in this section. Use this offset to add the position in the file in the file, you can get the location of the output function in the file. That is, DATADIRECTORY [Image_Directory_Entry_Export] .virtualAddress - SectionTable [i] .virtualAddress SectionTable [i] .pointertorawData. This way we get the location where the output function starts in the file. Output functions in the second PE file. The output function is used to use other programs.
Other programs If you know the entry address of an output function (that is, you start with the code that implements this function function), you can go there to perform it. In a PE file, if there is an output function, it is generally not one. So there is an array to save the entry address of each output function. In the PE file, two methods are provided to find an entry address of an output function. The first method is to pass the number of inlet address array, that is, knowing is the first element in the inlet address array, so that the inlet address inside can be obtained. The second method is to obtain the entry address of the corresponding function of the function name by the comparison function name, then obtain the serial number of the entrance address array of the entry address of the function name. In order to be able to obtain a serial number through a function name, some related structures are needed. Tell the details. Some of the output function portions of the PE file is always. We have got a location where the output function portion starts in the file is the first place in the output function section. It is an image_export_directory structure that provides many important information. This structure is followed by an array of output functions inlet address. Output function Inlet address array is followed by an array of output functions. The array of the output function name is followed by the array of sequence numbers corresponding to the output function name. The array of output function names is followed by the number of DLL names and output functions. Note that they are next to each other. And the order is an array of image_export_directory, an array of output function entry addresses, an array of a pointer to the output function name, and an array of the serial number corresponding to the function name. Finally, the String of the DLL name and string of those output function names. First look at the image_export_directory structure, defined in Winnt.h as follows. typedef struct _IMAGE_EXPORT_DIRECTORY {DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames; DWORD AddressOfFunctions; // RVA from base of imageDWORD AddressOfNames; // RVA from base of imageDWORD AddressOfNameOrdinals; / / RVA from base of image} image_export_directory, * pimage_export_directory; This structure is 40 bytes, a total of 11 fields. The various fields have the following: Characteristics: A reserved field, currently 0. TIMEDATESTAMP: The time generated. Majorversion: MINORVERSION: NAME: A RVA, pointing to the ASCII string of the name of a DLL. Base: The starting sequence number of the output function. Usually 1. Numberoffunctions: Outputs the number of elements in the array of function entry addresses. NumberOfNames: The number of elements in the array of pointers of the function name is also the number of elements in the array of the sequence number corresponding to the output function name. Addressoffunctions: An array of RVA, pointing to the output function entry address. AddressOfNames: An array of pointers that point to the output function name. AddressOfnameRinals: An array of serial numbers corresponding to the output function name.
The array of output function entry addresses, this array is a DWORD array, each element is a RVA, pointing to an entry address of an output function, and 4 bytes per element. The array of pointers of the output function name, this array is a DWORD array, each element is a RVA, pointing to an output function name ASCII string, and 4 bytes per element. The array of output function names corresponds, this array is a Word array, each element is an index corresponding to an output function name function. This index is an index of an array of output functions (already subtracted by serial number). The serial number), this element is 2 bytes long. DLL name strings and output function name strings are ASCII strings to end. A next next to one. The address of the DLL name string exists in the Name of Image_Export_Directory. The address of the output function name string exists in the array of pointers of the output function name. It is also important to note that the array of output function entry addresses contains the entry point address of the output function, and a serial number subtracts the start number (start number is the base in Image_export_Directory) to index this array. For example, the start number is 1, the entry address of the function of the serial number is 1, then the entry address of the function is the output function entry address array [0] (0 is calculated from 1-1) No. 3 function. The entry address is an output function inlet address array [2] (2 is calculated from 3-1). When the loader wants to correct the call of a function, this function is input with the serial number, the loader will subtract the starting sequence number with the serial number to obtain an index of the array of output function inlet addresses. When the loader is to correct the call, the function is input by the function name, the device name each element is referred to, for example, in the third element, Find the same. The loader obtains the serial number of the function from the value of the third element of the array of the sequence number corresponding to the output function name. Use this serial number to get the entry address as the serial number as before. The argument of the argument of the pointer of the output function name and the array of the sequence number corresponding to the output function name have the same element (NumberOfNames in Image_export_Directory). And it is associated, the number of the first element of the function name pointer array, in the ninth element of the sequence number array. The array of the argument of the pointer of the output function name and the array of output function names are separated into two arrays, rather than incorporating an array of structures (the first member of this structure is a pointer, and the second member is serial number) Because it is because one element of the array is 6 bytes, which is not conducive to alignment. Let's take an example to look at the content described above. Our example is the DLL file RouteTab.dll in Win2K. In order to prevent the version from being different, this PE file is included in this article. The method of looking for the location of the output section in the file is started to find the location of the output portion in the file is 00001460h. Since the first structure image_export_directory is relatively long, the one-line party is not lower, so the three lines, the different members of the structure are used / separated. Everyone is a structure. You can open the included RouteTab.dll with a 16-binding editor. Let's count the location of Name, Addressoffunctions, AddressOfNames, AddressOfNameordinals in the file. The start RVA of the output portion (obtained by DataDirectory [1]) is 1E60H. The position of the output portion in the file is 1460 h.
Name is RVA (value can be seen from the structure, if you don't understand why 0001eec instead of EC1E0000, please see "JIURL PE format learning summary (1) About BIG-Endian and Little-Endian introduction) The offset at the beginning of the output portion is 1EEC-1E60 with respect to the output portion. The position of Name in the file is the position of the file in the file in the offset starting with respect to the output portion. So the location of Name in the file is 1EEC-1E60 1460 = 14 ECH. Similar approach We can calculate, Addressoffunctions: 1e88-1E60 1460 = 1488. AddressOfnames: 1eb0-1e60 1460 = 14b0. AddressOfnameOrdinals: 1ed8-1e60 1460 = 14d8. From the structure, you can also see the 0000000A (decimal 10) output function. 00001460: {00 00 00 00 / dc 5b ec 37/00 00/00 00 / ec 1e 00 00/00001470: 01 00 00 00 / 0a 00 00 00 / 0a 00 00 00/88 1e 00 00/00001480: b0 1e 00 00 00 00 00} (we enclose the parentheses, the image_export_directory structure, the length is 40 bytes) 00001488: 41 1A 00 00 00 00 (RVA of the function entry point, length 4 bytes) 0000148C: 64 1A 00 00 00 00 001494: 02 18 00 00 001498: 71 16 00 00 00149c: 07 16 00 000014A0: 26 18 00 00 0014A4: 84 1A 00 000014A8: 06 17 00 000014AC: 5B 19 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000014B0: F9 1e 00 00 (Function name pointer, length 4 bytes, pointing 1EF9-1E60 1460 = 14f9) 000014B4: 02 1F 00 000014B8: 0E 1F 00 000014BC: 21 1F 00 000014C0: 30 1F 00 00 000014C4: 42 1f 00 00 000014C8: 4d 1f 00 00 000014CC: 5b 1f 00 00 000014D0: 6c 1f 00 00 000014D4: 81 1f 00 00 000014D8: 00 00 (indexes, functions described a function name, the entry address Address array [0]) (not the 0th element value of each PE file number array is 0, the first element value is 1, NTDLL.DLL is not)