The PE file structure in the previous article (2) a large array appears at the end of the executable file header, and each item in this array is a specific structure, you can use the rtlimagedirectoryentrytodata function to obtain the items in the array through the function. Each item in datadirectory can be obtained using this function. The function prototype is as follows:
Pvoid ntapi rtlimagedirectoryentrytodata (pvoid base, Boolean mappedasimage, ushort directory, Pulong size );
Base: The base address of the module.
Mappedasimage: whether to map to an image.
Directory: The index of the Data Directory item.
[CPP]View plaincopy
- # Define image_directory_entry_export 0 // export directory
- # Define image_directory_entry_import 1 // import directory
- # Define image_directory_entry_resource 2 // Resource Directory
- # Define image_directory_entry_exception 3 // exception directory
- # Define image_directory_entry_security 4 // security directory
- # Define image_directory_entry_basereloc 5 // base relocation table
- # Define image_directory_entry_debug 6 // DEBUG directory
- // Image_directory_entry_copyright 7 // (x86 usage)
- # Define image_directory_entry_architecture 7 // architecture specific data
- # Define image_directory_entry_globalptr 8 // RVA of GP
- # Define image_directory_entry_tls 9 // TLS directory
- # Define image_directory_entry_load_config 10 // load configuration directory
- # Define image_directory_entry_bound_import 11 // bound import directory in Headers
- # Define image_directory_entry_iat 12 // import Address Table
- # Define image_directory_entry_delay_import 13 // delay load import Descriptors
- # Define image_directory_entry_com_descriptor 14 // com runtime Descriptor
Size: the size of the Data Directory item. For example, if directory is 0, it indicates the size of the exported table.
The return value indicates the starting address of the data directory.
This time, let's take a look at the first item: export the table.
The export table is used to describe the structure of the export function in the module. If a module exports a function, this function will be recorded in the export table, in this way, the address of the function can be dynamically obtained through the getprocaddress function. You can export functions by name or by serial number. The two export methods have different descriptions in the export table. The module export function can be viewed using the dependency Walker tool:
In the red box, the exported function of the module is displayed. Sometimes, the exported function name contains symbols, such as [email protected] @ [email protected] @ Z, this is the function name that exports C ++, And the compiler modifies the name.
Let's take a look at the definition of the exported table:
[CPP]View plaincopy
- 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 Image
- DWORD addressofnames; // RVA from base of Image
- DWORD addressofnameordinals; // RVA from base of Image
- } Image_export_directory, * pimage_export_directory;
The structure is relatively simple. The meaning of each item is as follows:
Characteristics: currently unavailable, generally 0.
Timedatestamp: The timestamp generated by the export table, which is generated by the connector.
Majorversion, minorversion: The name is version, which does not actually seem to be used, and all are 0.
Name: the name of the module.
Base: The base number of the sequence number. The sequence number of the function exported by the sequence number increases from base.
Numberoffunctions: Number of all export functions.
Numberofnames: number of functions exported by name.
Addressoffunctions: An RVA pointing to a DWORD array. Each item in the array is the RVA of an export function. The order is the same as the export sequence number.
Addressofnames: An RVA still points to a DWORD array. Each item in the array is still an RVA and points to a function name.
Addressofnameordinals: An RVA still points to a Word Array. Each item in the array corresponds to each item in addressofnames, indicating the number of the function in addressoffunctions.
The first child shoes that came into contact with this structure were fainted by the five following items. Understanding this structure is more complicated than the structure itself. The text description is obscure in any case, no picture, no truth, direct:
In, addressofnames points to an array, which stores a group of RVA. Each RVA points to a string, which is the name of the exported function, corresponding to this function name is the corresponding item in addressofnameordinals. When getting the export function address, first find the corresponding name in addressofnames, such as func2, which is the second item in addressofnames, and then retrieve the value of the second item from addressofnameordinals. Here is 2, the function entry is saved in the item marked as 2 in the addressoffunctions array, that is, the third item. The value is taken out, and the base address of the module is the address of the export function. If the function is exported by serial number, use the serial number to subtract the base. The obtained value is the subscript of the function in addressoffunctions.
The Code is as follows:
[CPP]View plaincopy
- DWORD * CEAT: searcheat (const char * szname)
- {
- If (is_valid_ptr (m_ptable ))
- {
- Bool bbyordinal = hiword (szname) = 0;
- DWORD * pprocs = (DWORD *) (char *) rva2va (m_ptable-> addressoffunctions ));
- If (bbyordinal)
- {
- DWORD dwordinal = (DWORD) szname;
- If (dwordinal <m_ptable-> numberoffunctions & dwordinal> = m_ptable-> Base)
- {
- Return & pprocs [dwOrdinal-m_pTable-> base];
- }
- }
- Else
- {
- Word * pordinals = (word *) (char *) rva2va (m_ptable-> addressofnameordinals ));
- DWORD * pnames = (DWORD *) (char *) rva2va (m_ptable-> addressofnames ));
- For (unsigned int I = 0; I <m_ptable-> numberofnames; ++ I)
- {
- Char * pnameva = (char *) rva2va (pnames [I]);
- If (strcmp (szname, pnameva )! = 0)
- {
- Continue;
- }
- Return & pprocs [pordinals [I];
- }
- }
- }
- Return NULL;
- }
PE file structure (3) PE export table