Write another PE file by the wayArticleThis article introduces the export tables of PE files. Exporting a table is relatively simple. It has only one key structure. Essentially, the export table's dir only indicates the following information, the DLL name and address (ANSI string), how many export functions are available, and the export function has three arrays, which are serial number arrays, function Name (ANSI string) Address array, function entry address (RVA) array. The imported table export table is directly related to the dynamic link technology.
First, we will introduce the unique data structure of the exported table (only list key members ):
(1) image_export_directory:
(1.1)DWORD name;The DLL name (ANSI) string address (RVA ).
(1.2)DWORD base;The Count start value of the serial number array. (Adding the value in the serial number array to the base indicates the final number of the exported function)
(1.3)DWORD numberoffunctions;Number of exported functions.
(1.4)DWORD numberofnames;Number of function names. This value should usually be the same as numberoffunctions (that is, all export functions should have a name ).
(1.5)DWORD addressoffunctions; Array of the function address RVA.
(1.6)DWORD addressofnames;Store the address (RVA) of the array (RVA) of the function name (ANSI) string ).
(1.7)DWORD addressofnameordinals;The address (RVA) of the array storing the function serial number ).
By convention, the following is the structure of the export table:
The following describes how to read the import table.CodeBecause my project properties use Unicode strings, I need to perform a conversion to Unicode before using those ANSI strings:
Code_load_exporttable
// Load export table
Void Cpercviewdlg: loadexporttable (lpbyte lpbaseaddress, pimage_nt_headers pntheaders, dword rva)
{
Int I;
Tchar wcsbuffer [ 256 ], Nodetext [ 256 ];
Htreeitem hitem_export=NULL;
pimage_export_directory pexporttable = (pimage_export_directory) imagervatova (
pntheaders,
lpbaseaddress,
RVA,
null
);
_ stprintf (nodetext, _ T ( " exporttable (fileaddress: % 08x) " ), (DWORD) pexporttable - (DWORD) lpbaseaddress);
hitem_export = m_tree.insertitem (nodetext, tvi_root, tvi_last);
// DLL name (char *)
lpcstr szdllname = (lpcstr) imagervatova (
pntheaders, lpbaseaddress,
pexporttable -> name,
null);
// convert ANSI names to Unicode
:: multibytetowidechar (cp_acp, mb_precomposed, szdllname, - 1 , nodetext, sizeof (nodetext) / sizeof (tchar);
//Append DLL Name Node
Htreeitem hdllname=M_tree.insertitem (nodetext, hitem_export, tvi_last );
//Load each node now
DWORD imagebase=Pntheaders->Optionalheader. imagebase;
// all of the following are RVA. Convert to the VA at the entrance of the array:
pdword pfunctions = (pdword) imagervatova (
pntheaders, lpbaseaddress,
pexporttable -> addressoffunctions,
null);
Pword pordinals=(Pword) imagervatova (
Pntheaders, lpbaseaddress,
Pexporttable->Addressofnameordinals,
Null );
Bool hasnames=(Pexporttable->Addressofnames! = 0);
Pdword pnames=NULL;
If(Hasnames)
{
Pnames=(Pdword) imagervatova (
Pntheaders, lpbaseaddress,
Pexporttable->Addressofnames,
Null );
}
For (I = 0 ; I < Pexporttable -> Numberoffunctions; I ++ )
{
// Function Name
If (Hasnames)
{
Lpcstr szfuncname = (Lpcstr) imagervatova (
Pntheaders, lpbaseaddress,
Pnames [I],
Null );
//Convert to Unicode
: Multibytetowidechar (cp_acp, mb_precomposed, szfuncname,-1, Wcsbuffer,Sizeof(Wcsbuffer)/Sizeof(Tchar ));
}
_ Stprintf (nodetext, _ T ( " Ordinal: % LD % s, VA: % 08x " ),
Pexporttable -> Base + Pordinals [I],
Hasnames ? Wcsbuffer: _ T ( " (Null) " ),
Imagebase + Pfunctions [I]
);
M_tree.insertitem (nodetext, hdllname, tvi_last );
}
}
Finally, the effect of loading the exported function to treectrl is as follows:
[Supplement] About Pragma:
(1) Specify the segment of the content in the OBJ file. For specific usage, refer to msdn (not commonly used). The following are code (function), initialization data, uninitialized data, and constants:
# PragmaCode_seg([[{Push | Pop},] [Identifier,] ["Segment-name"[,"Segment-class"])
# PragmaData_seg([[{Push | Pop},] [Identifier,] ["Segment-name"[,"Segment-class"])
# PragmaBss_seg([[{Push | Pop},] [Identifier,] ["Segment-name"[,"Segment-class"])
# PragmaConst_seg([[{Push | Pop},] [Identifier,] ["Segment-name"[,"Segment-class"])
(2) specify a library to be searched during link in an OBJ file (more common ):
# Pragma comment (Lib, "emapi ")
[References]
(1) reading the essence of the snow Forum 8;
(2) winnt. h;