//
// Author: Kill dragon microsoftxiao@163.com
// Description: Based on the PE File Format Principle
// 1. Add the CIDR Block tool based on the PE information Browser
# Include <windows. h>
# Include <iostream>
# Include <sys/STAT. h>
# Include <ctime>
Using namespace STD;
# Define safe_delete (p) {If (p )! = NULL) {Delete (p); (p) = NULL ;}}
Bool insertsection (byte * decbuf, struct _ stat & St, char ** argv); // insert a block
Bool fillzeroarea (File * decfile, ulong virtualsize, ulong virtualaddress); // fill in all 0 regions
Bool helpinfo (char ** argv );
Struct _ stat st;
File * viewdecfile = NULL;
Bool g_bhavesetvsizeaaddress = false; // whether to set the size and address of the inserted segment
// Entry
Int main (INT argc, char ** argv)
{
Helpinfo (argv );
Srand (Time (null ));
If (argc <2 ){
Printf ("welcome to use javas_^ God kill dragon microsoftxiao@163.com \ n ");
} Else {
If (argv [2])
{
Printf ("have vsize and vaddress \ n ");
G_bhavesetvsizeaaddress = true;
} Else {
Printf ("not set vsize and vaddress (default vsize: 4 kb (0x1000) \ n ");
G_bhavesetvsizeaaddress = false;
}
Viewdecfile = fopen (argv [1], "rb ");
Byte * Buf = NULL;
: _ Stat (argv [1], & St );
Buf = new byte [st. st_size];
Fread (BUF, 1, st. st_size, viewdecfile );
Fclose (viewdecfile );
Insertsection (BUF, St, argv );
Safe_delete (BUF );
}
Return 0;
}
// Insert a block
Bool insertsection (byte * decbuf, struct _ stat & St, char ** argv)
{
Cout <"computing block parameters :";
// Insert the block and obtain the OEP first.
Const int offdosstub = 0x3c;
Long off_elfanew = 0; // you can directly read it based on the type.
Char szpehead [5]; // pe00
Word machine = 0; // CPU type
DWORD addressofentrypoint = 0; // program execution entry RVA
DWORD imagebase = 0; // The base address of the program is loaded by default.
Word subsystem = 0; // sub-system, console or other
DWORD sizeofimage = 0; // size of the entire PE image in the memory
Word sizeofoptionalheader = 0; // optional image header size
DWORD sectiontableheadervalue = 0; // The first PE (base) + 0x12 + sizeofoptionalheader of the block table
Word numberofsections = 0; // number of sections
DWORD sectionslength = 0; // block Length
Memcpy (& off_elfanew, & decbuf [offdosstub], sizeof (long ));
// Fwrite (& off_elfanew, 1, sizeof (off_elfanew), test );
Memcpy (szpehead, & decbuf [off_elfanew], sizeof (szpehead ));
// Fwrite (szpehead, 1, sizeof (szpehead)-1, test );
Memcpy (& machine, & decbuf [off_elfanew + 0x4], sizeof (Word ));
If (machine = 0x14c)
Printf ("CPU Intel i386 or later series: % x \ n", machine );
Memcpy (& addressofentrypoint, & decbuf [off_elfanew + 0x28], sizeof (DWORD ));
Printf ("program entry point: 0x0% x \ n", addressofentrypoint );
Memcpy (& imagebase, & decbuf [off_elfanew + 0x34], sizeof (DWORD ));
Printf ("Image Base Address: 0x0% x \ n", imagebase );
Memcpy (& subsystem, & decbuf [off_elfanew + 0x5c], sizeof (Word ));
Switch (subsystem)
{
Case 0:
Printf ("unknown subsystem \ n ");
Break;
Case 1:
Printf ("subsystem not required: 0x0% x \ n", subsystem );
Break;
Case 2:
Printf ("graphical interface subsystem (GUI): 0x0% x \ n", subsystem );
Break;
Case 3:
Printf ("console or DoS or Cui): 0x0% x \ n", subsystem );
Break;
Case 5:
Printf ("OS/2 character subsystem: 0x0% x \ n", subsystem );
Break;
Case 7:
Printf ("POSIX character subsystem: 0x0% x \ n", subsystem );
Break;
Default:
Printf ("unknown subsystem \ n ");
Break;
}
Memcpy (& sizeofimage, & decbuf [off_elfanew + 0x50], sizeof (DWORD ));
Printf ("memory image size: 0x % x \ n", sizeofimage );
Memcpy (& sizeofoptionalheader, & decbuf [off_elfanew + 0x14], sizeof (Word ));
Printf ("Optional image header size: % d bytes (% x) \ n", sizeofoptionalheader, sizeofoptionalheader );
Memcpy (& sectiontableheadervalue, & decbuf [off_elfanew + 0x18 + sizeofoptionalheader], sizeof (DWORD ));
Printf ("Block table first value: % x \ n", sectiontableheadervalue );
Memcpy (& numberofsections, & decbuf [off_elfanew + 0x06], sizeof (Word ));
Printf ("number of segments: % x \ n", numberofsections );
Image_section_header Tish; // block table structure instance
Zeromemory (& Tish, sizeof (Tish ));
Printf ("Block table item structure size: % d byte \ n", sizeof (Tish ));
Int t_totalsectionlength = sizeof (Tish) * numberofsections;
Printf ("total block table length: % d bytes (% x) \ n", t_totalsectionlength, t_totalsectionlength );
Int t_insertposition = 0x18 + sizeofoptionalheader + t_totalsectionlength;
Printf ("Block Table offset position: 0x0% x \ n", t_insertposition );
Char sznewfilename [260];
Sprintf (sznewfilename, "201766620.d_.exe", Rand () % 10000 );
File * test = fopen (sznewfilename, "WB ");
Fwrite (decbuf, 1, st. st_size, test );
// Add a block
If (TEST ){
Strncpy (char *) Tish. Name, ". pediy", sizeof (Tish. Name ));
Tish. Misc. virtualsize = 0x3e000; // 4kb
Tish. sizeofrawdata = 0x3e000;
Tish. virtualaddress = ST. st_size; // The address should be added to an idle zone first, and then changed to the endpoint as the final offset.
Tish. pointertorawdata = ST. st_size; // Number of row numbers in the row number table
If (g_bhavesetvsizeaaddress)
{
Tish. Misc. virtualsize = atoi (argv [2]); // 4kb
Tish. sizeofrawdata = atoi (argv [2]);
}
Tish. pointertorelocations = 0; // used in the OBJ file, relocated offset
Tish. pointertolinenumbers = 0; // offset of the row number table (for trial use)
Tish. numberofrelocations = 0; // used in the OBJ file, number of relocated Projects
Tish. numberoflinenumbers = 0;
Tish. characteristics = 0xe0000020; // a block attribute that contains the code to be executed, read/write, and executable.
Fseek (test, 0, seek_set );
Fseek (test, off_elfanew + t_insertposition, seek_set );
Fwrite (& Tish, 1, sizeof (Tish), test); // write the Block Structure
Fseek (test, off_elfanew + 0x06, seek_set );
Numberofsections ++;
Fwrite (& numberofsections, 1, sizeof (numberofsections), test); // modify the number of blocks
Sizeofimage + = Tish. sizeofrawdata; // What is the size after alignment?
Fseek (test, off_elfanew + 0x50, seek_set); // locate
Fwrite (& sizeofimage, 1, sizeof (sizeofimage), test );
Fillzeroarea (test, Tish. Misc. virtualsize, Tish. virtualaddress); // enter zero after the specified address
}
Fclose (test );
Remove (argv [1]);
Rename (sznewfilename, argv [1]);
Return 0;
}
// Fill the entire zero zone
Bool fillzeroarea (File * decfile, ulong virtualsize, ulong virtualaddress)
{
Fseek (decfile, virtualaddress, seek_set );
Byte * szbuf = NULL;
Szbuf = new byte [virtualsize];
Strncpy (char *) szbuf, "Z", virtualsize );
Fwrite (szbuf, 1, virtualsize, decfile );
Byte TMP = 0;
Fseek (decfile, virtualaddress, seek_set );
Fwrite (& TMP, 1, sizeof (TMP), decfile );
Safe_delete (szbuf );
Return 0;
}
Bool helpinfo (char ** argv)
{
Printf ("Help \ n ");
Printf ("% s target PE file (destination) new block size (virtualsize) new block offset address (virtualaddress) \ n", argv [0]);
Return 0;
}
The code is not allowed to be sent here. In short, you should pay attention to the increase of memory image and the increase of the number of blocks in the PE section.
There are also offset addresses.
Strncpy (char *) Tish. Name, ". pediy", sizeof (Tish. Name ));
Tish. Misc. virtualsize = 0x1000; // 4 kb
Tish. sizeofrawdata = 0x1000;
Tish. virtualaddress = sizeofimage; // The address should be added to an idle zone first, and then the endpoint should be changed to this address as the final offset.
Tish. pointertorawdata = ST. st_size; // Number of row numbers in the row number table
If (g_bhavesetvsizeaaddress)
{
Tish. Misc. virtualsize = atoi (argv [2]); // 4kb
Tish. sizeofrawdata = atoi (argv [2]);
}
Tish. pointertorelocations = 0; // used in the OBJ file, relocated offset
Tish. pointertolinenumbers = 0; // offset of the row number table (for trial use)
Tish. numberofrelocations = 0; // used in the OBJ file, number of relocated Projects
Tish. numberoflinenumbers = 0;
Tish. characteristics = 0xe0000020; // The Block attribute, which indicates that it contains the code to be executed, can be read and written, and can
The CIDR Block adding tool sets the virtualaddress as the offset of the CIDR Block in the memory. Therefore, the address only needs to be the memory image size.
The file offset address pointertorawdata is the file size.
This is why these two values are sometimes different, although the blocks of the memory image are roughly one-to-one correspondence with the disk files. However, the mapped address is still offset. So sometimes the virtualaddress and pointertorawdata can be executed at the same time. Sometimes, errors occur at the same time because of inconsistent loading addresses, that is, consistent addresses,
The address value may have data. If it is loaded again, it is equivalent to overwriting the data of that address. Since the block on the disk is added to the end of the file, the block in the memory is of course the end Of the memory image.