In-depth parsing of PE file structure and obtaining an export table

Source: Internet
Author: User

The new weather for the new semester is generally the beginning of the primary school composition.

Recently, I have had time to take a closer look at the structure of the PE file. In the past, when I encountered such a problem, I always split the east wall to make up the west wall. I have not learned well enough. After several days of research, I will share with you.

The file structure of PE starts from the DOS header. The main function of PE is to output a sentence in the DOS environment. Another function is to find the position of the PE File Header, which is of concern to us. This article only focuses on the problem to be concerned-exporting tables. And some details that are hard to find on the Internet, as detailed in the overall PE Structure online information.

First of all, the loading principle of PE files is not mentioned here. The whole complicated process is completed by the PE Loader. The process is not clear in one or two sentences, here we only need to pay attention to one detail. The PE Loader maps PE files from the disk to the memory by file ing. When ing is performed, the start position of the PE file being loaded to the memory is called the base address, which is represented by lpimagebase. First, we need to know how to load a PE file to the memory and obtain the base address.

Handle hfile = createfile ("C: \ example.exe", generic_read | generic_write, file_share_read, null, open_existing, file_attribute_normal, null); If (hfile = invalid_handle_value) {printf ("Create File failed. \ n "); return;} Handle hfilemapping = createfilemapping (hfile, null, page_readonly, 0, 0, null); If (hfilemapping = NULL | hfilemapping = invalid_handle_value) {printf ("cocould not create file mapping object (% d ). \ n ", getlasterror (); return;} // base address of the memory ing file lpbyte lpbaseaddress = (lpbyte) mapviewoffile (hfilemapping, file_map_read, 0, 0 ); if (lpbaseaddress = NULL) {printf ("cocould not map view of file (% d ). \ n ", getlasterror (); return ;}'

Here, we need to care about a structure named image_optional_header. The Chinese name is "Optional Image Header", which is optional. In fact, it is very important. This structure is in the image_nt_herders structure and is the second member variable.

Typedef struct image_nt_herders {signature dd ?; Fileheader image_file_header <>; optionalheader image_optional_header; // The following structure is image_optional_header}

Image_nt_herders address acquisition:

Pimage_dos_header pdosheader = (pimage_dos_header) lpbaseaddress;

Pimage_nt_headers pntheaders = (pimage_nt_headers) (lpbaseaddress + pdosheader-> e_lfanew );

/Optional image header typedef struct _ character {word magic; byte majorlinkerversion; byte minorlinkerversion; DWORD sizeofcode; DWORD character; DWORD baseofcode; DWORD baseofdata; DWORD imagebase; DWORD merge; Word majorimageversion; Word minorimageversion; Word majorsubsystemversion; Word minorsubsystemversion; DWORD win32versionvalue; DWORD sizeofimage; DWORD merge; DWORD checksum; Word subsystem; word sequence; DWORD sizeofstackreserve; DWORD sizeofstackcommit; DWORD sequence; DWORD loaderflags; DWORD sequence; // The member size is the number of the following Arrays: image_data_directory datadirectory [sequence]; // here is the following image_data_directory} image_optional_header, * pimage_optional_header;

Image_optional_header:

Pntheaders-> optionalheader;

Then we need to pay attention to the image_data_directory array. This array usually has 15 elements, each of which records the important data structure of this PE file. Let's take a look at the content of each element in this array.

Isn't it surprising? With this array, it is very easy to obtain some PE information. Generally, we or computer viruses are concerned with the export table (EAT), import table (IAT), table, these are the 0th and 12th elements of the array. This method is different from some eat IAT address retrieval methods on the Internet. It is very convenient.

While pntheader-> optionalheader. datadirectory [0] is a struct, which is defined as follows:

Typedef struct _ image_data_directory {DWORD virtualaddress; // point to the RVA address (relative address) DWORD size of the export table;} image_data_directory, * pimage_data_directory;

Here we should obtain the address of the eat table as follows:

Pntheader-> optionalheader. datadirectory [0]. virtualaddress

 

 

Now we have found the relative address of the exported table of the PE file (RVA). The question is, how can we get the export function information stored in the exported table.

Let's first look at what the export table is like:

// Import Address Table typedef struct _ image_export_directory {DWORD characteristics; DWORD timedatestamp; Word majorversion; Word minorversion; DWORD name; DWORD base; DWORD numberoffunctions; DWORD numberofnames; DWORD indexes; // function rva dword addressofnames; // function name rva dword addressofnameordinals; // function index number RVA} image_export_directory, * pimage_export_directory;

It is not hard to see addressofnames; it is an array RVA that stores the export function. But there is a small problem here. I spent half a day on this issue. In addressofnames;, it is indeed an RVA (relative address), but instead of pointing directly to the Function Array, it points to an array with a storage address, that is, a DWORD array, each element of this array stores an RVA of the export function, which is a bit backward. We already have an illustration:

 

This has caused some trouble for cainiao like me. The basic syntax is still very important...

Therefore, you need to obtain the address in this way (the base address lpimagebase is added here, which will be explained later)

DWORD * k = (DWORD *) (pexport-> addressofnames + lpbaseaddress); // RVA contains ·
Char * functionname = (char *) (* k + lpbaseaddress );

 

 

Well, we have all the addresses, so it is not difficult for the program. The following shows the core code. I think this method of getting an address is much simpler than that of common methods (cainiao himself thinks this way ):

#include "windows.h"#include "stdio.h"void Doshow(char * place){int i=0;HANDLE hfile = CreateFile(place, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if(hfile==INVALID_HANDLE_VALUE){printf("Create File Failed.\n");return ;}HANDLE hFileMapping=CreateFileMapping(hfile,NULL,PAGE_READONLY,0,0,NULL);if (hFileMapping==NULL||hFileMapping==INVALID_HANDLE_VALUE) { printf("Could not create file mapping object (%d).\n", GetLastError());return ;}//ÄÚ´æÓ³ÉäÎļþµÄ»ùÖ·LPBYTE lpBaseAddress=(LPBYTE)MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0);if (lpBaseAddress == NULL) { printf("Could not map view of file (%d).\n", GetLastError()); return ;}PIMAGE_DOS_HEADER pDosHeader=(PIMAGE_DOS_HEADER)lpBaseAddress;PIMAGE_NT_HEADERS pNtHeaders=(PIMAGE_NT_HEADERS)(lpBaseAddress + pDosHeader->e_lfanew);PIMAGE_EXPORT_DIRECTORY pExport=(PIMAGE_EXPORT_DIRECTORY)(pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress+lpBaseAddress);int Num=pExport->NumberOfNames;printf("DLLÊÇ%s\n",pExport->Name+lpBaseAddress);printf("¹²ÓÐ%d¸öº¯Êý\n",pExport->NumberOfNames);printf("º¯ÊýÐòºÅ        º¯ÊýÃû\n");for (i;i<Num;i++){DWORD * k=(DWORD *)(pExport->AddressOfNames+lpBaseAddress+4*i);    //RVAÊý×éÊ×µØÖ·char * functionName=(char *)(*k+lpBaseAddress);printf("%d             %s\n",i+1,functionName);}UnmapViewOfFile(lpBaseAddress);CloseHandle(hFileMapping);CloseHandle(hfile);}int main(){char p[20];printf("ÇëÊäÈëÎļþλÖãº\n");scanf("%s",p);Doshow(p);return 1;}

In addition, I also wrote the interface to show it to you.

 

 

 

 

The following task is to try more difficult IAT table rewriting, such as inserting DLL and implementing basic functions of PE virus. If possible, I will share my "achievements" with you ".

 

Cainiao's remarks are for entertainment only.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.