A program simulating the behavior of the PE Loader

Source: Internet
Author: User
Title: [original] A program simulating the behavior of the PE Loader
Author: linxer
Time: 2006-06-10, 00: 50: 49
Chain: http://bbs.pediy.com/showthread.php? T = 27134

[Title] A program simulating the behavior of the PE Loader
[Statement] The level is limited. If not, please enlighten me!

The following procedure assumes that the PE file is legal, so fault tolerance is not provided in many places.

Bool peloader (char * lpstaticpebuff, long lstaticpelen)
{
Long lpesignoffset = * (long *) (lpstaticpebuff + 0x3c );
Image_nt_headers * pinh = (image_nt_headers *) (lpstaticpebuff + lpesignoffset );

// Load the data to the memory in a large or small size.
Long limagesize = pinh-> optionalheader. sizeofimage;
Char * lpdynpebuff = new char [limagesize];
If (lpdynpebuff = NULL)
{
Return false;
}
Memset (lpdynpebuff, 0, limagesize );

// Obtain the number of PE file segments
Long lsectionnum = pinh-> fileheader. numberofsections;

// Calculate the memory occupied by PE Header Information and section table information
Long lpeheadsize = lpesignoffset + sizeof (image_nt_headers) + lsectionnum * sizeof (image_section_header );

// Load the PE Header Information and its section tables
Memcpy (lpdynpebuff, lpstaticpebuff, lpeheadsize );

// Load each section
Long lfilealignmask = pinh-> optionalheader. filealignment-1; // alignmask of each section on the disk
Long lsectionalignmask = pinh-> optionalheader. sectionalignment-1; // The alignmask mask of each section in the memory after loading
Image_section_header * pish = (image_section_header *) (char *) pinh + sizeof (image_nt_headers ));
For (INT nindex = 0; nindex <lsectionnum; nindex ++, pish ++)
{
// Determine the alignment attribute of each section. The attribute is invalid.
If (Pish-> virtualaddress & lsectionalignmask) | (Pish-> sizeofrawdata & lfilealignmask ))
{
// Invalid Section
Delete lpdynpebuff;
Return false;
}

// Load the revised section
Memcpy (lpdynpebuff + Pish-> virtualaddress, lpstaticpebuff + Pish-> pointertorawdata, pish-> sizeofrawdata );
}

// Modify the import table and the API function address used during execution of the import program
If (pinh-> optionalheader. datadirectory [image_directory_entry_import]. size> 0) // if the value is greater than 0, an import table exists.
{
Image_import_descriptor * piid = (image_import_descriptor *) (lpdynpebuff + \
Pinh-> optionalheader. datadirectory [image_directory_entry_import]. virtualaddress );

// Cyclically Scan each DLL with function imports
For (; piid-> name! = NULL; piid ++)
{
/* I have read the ollydump source code. When recreating the import table, the originalfirstthunk field is not initialized,
Therefore, the originalfirstthunk field is not processed here */
Image_thunk_data * pitd = (image_thunk_data *) (lpdynpebuff + piid-> firstthunk );

Hinstance = loadlibrary (lpdynpebuff + piid-> name );
If (hinstance = NULL)
{
// Failed to import the DLL.
Delete lpdynpebuff;
Return false;
}

// Cyclically Scan each imported function in the DLL
For (; pitd-> u1.ordinal! = 0; pitd ++)
{
Farproc fpfun;
If (pitd-> u1.ordinal & image_ordinal_flag32)
{
// The function is imported by serial number.
Fpfun = getprocaddress (hinstance, (lpcstr) (pitd-> u1.ordinal & 0x0000ffff ));
}
Else
{
// The function is imported by name.
Image_import_by_name * piibn = (image_import_by_name *) (lpdynpebuff + pitd-> u1.ordinal );
Fpfun = getprocaddress (hinstance, (lpcstr) piibn-> name );
}

If (fpfun = NULL)
{
// This function fails to be exported.
Delete lpdynpebuff;
Return false;
}

Pitd-> u1.ordinal = (long) fpfun;
}

Freelibrary (hinstance );
}
}

// Relocate
If (pinh-> optionalheader. datadirectory [image_directory_entry_basereloc]. size> 0)
{
// Obtain the first relocation Block
Image_base_relocation * pibr = (image_base_relocation *) (lpdynpebuff + \
Pinh-> optionalheader. datadirectory [image_directory_entry_basereloc]. virtualaddress );

Long ldifference = (long) lpdynpebuff-pinh-> optionalheader. imagebase;

// Loop each relocation Block
For (; pibr-> virtualaddress! = 0 ;)
{
Char * lpmempage = lpdynpebuff + pibr-> virtualaddress;
Long lcount = (pibr-> sizeofblock-sizeof (image_base_relocation)> 1;

// Process each item to be relocated on this page
Short int * prelocationitem = (short int *) (char *) pibr + sizeof (image_base_relocation ));
For (INT nindex = 0; nindex <lcount; nindex ++)
{
Int noffset = prelocationitem [nindex] & 0x0fff;
Int ntype = prelocationitem [nindex]> 12;

// Although windows defines many relocation types, only 0 and 3 types can be seen in the PE file.
If (ntype = 3)
{
* (Long *) (lpdynpebuff + noffset) + = ldifference;
}
Else if (ntype = 0)
{
// Do nothing
}
}

// Point pibr to the next relocation Block
Pibr = (image_base_relocation *) (prelocationitem + lcount );
}

}

Delete lpdynpebuff;

Return true;
}

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.