📄 unit1.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "PortableExecutable.h"
using namespace PE;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void MakeLong (DWORD dwLong, unsigned char *data)
{
data[0] = (char)(dwLong & 0xFF);
data[1] = (char)((dwLong >> 8) & 0xFF);
data[2] = (char)((dwLong >> 16) & 0xFF);
data[3] = (char)((dwLong >> 24) & 0xFF);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
IMAGE_NT_HEADERS hdrNt;
DWORD dwProgBase;
DWORD dwEntryPoint;
if (1)
{
CPortableExecutable pe;
PE_ERROR pe_err;
DeleteFile ("d:\\out.exe");
Memo1->Lines->Add ("Opening file...");
pe_err = pe.Load("d:\\in.exe");
if (pe_err == PE_NONE)
{
IMAGE_SECTION_HEADER newsectionhdr;
CSection newsection;
CSection *pnewsection;
unsigned char newsectiondata[0x1000];
unsigned char encryption_key[0xF00];
Memo1->Lines->Add ("Getting header info...");
pe.m_Headers.GetNt(hdrNt);
dwProgBase = hdrNt.OptionalHeader.ImageBase;
dwEntryPoint = hdrNt.OptionalHeader.AddressOfEntryPoint + dwProgBase;
Memo1->Lines->Add ("Creating new section...");
strncpy ((char *)newsectionhdr.Name, ".scoobles ", 8);
newsectionhdr.Misc.VirtualSize = 0x1000;
newsectionhdr.VirtualAddress = 0;
newsectionhdr.SizeOfRawData = 0x1000;
newsectionhdr.PointerToRawData = 0;
newsectionhdr.PointerToRelocations = 0;
newsectionhdr.PointerToLinenumbers = 0;
newsectionhdr.NumberOfRelocations = 0;
newsectionhdr.NumberOfLinenumbers = 0;
newsectionhdr.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE;
newsection.SetHeader(newsectionhdr);
pe.AddSection(&newsection);
Memo1->Lines->Add ("Processing");
pnewsection = pe.GetLastSectionInFile();
pnewsection -> GetHeader(newsectionhdr);
// encrypt section pointed to by entry point
CSection *pEntryPointSection = pe.GetSectionByVA(dwEntryPoint);
IMAGE_SECTION_HEADER EntryPointSecHdr;
pEntryPointSection->GetHeader (EntryPointSecHdr);
// generate encryption key
randomize();
for (int lp = 0; lp < 0xF00; lp ++)
{
unsigned char RandVal = rand() % 255;
while (!RandVal) RandVal = rand() % 255;
encryption_key[lp] = RandVal;
}
// get the original code
char *OrigData = (char *)malloc (EntryPointSecHdr.SizeOfRawData);
pEntryPointSection->GetData(OrigData);
// Check we don't overwrite anything important like import tables or tls...
DWORD MaxToEncrypt = EntryPointSecHdr.SizeOfRawData;
for (int lp = 0; lp < 16; lp ++)
if ((hdrNt.OptionalHeader.DataDirectory[lp].VirtualAddress >= EntryPointSecHdr.VirtualAddress) &&
(hdrNt.OptionalHeader.DataDirectory[lp].VirtualAddress < EntryPointSecHdr.VirtualAddress+MaxToEncrypt))
{
Memo1->Lines->Add ("DD ["+IntToStr(lp)+"] inside of encrypted section.");
MaxToEncrypt = (hdrNt.OptionalHeader.DataDirectory[lp].VirtualAddress -
EntryPointSecHdr.VirtualAddress) - 1;
Memo1->Lines->Add ("Encrypted section reduced to "+IntToStr(MaxToEncrypt)+" bytes.");
}
// encrypt it !
int enc_pos = 0;
char encbyte = encryption_key[0];
for (int lp = 0; lp < MaxToEncrypt; lp ++)
{
OrigData[lp] ^= encbyte;
encbyte <<= 1;
if (!encbyte)
{
enc_pos ++;
if (enc_pos == 0xF00) enc_pos = 0;
encbyte = encryption_key[enc_pos];
}
}
// put the encrypted data back over the original
pEntryPointSection->SetData(OrigData, EntryPointSecHdr.SizeOfRawData);
EntryPointSecHdr.Characteristics |= 0x80000000; // make section writable
pEntryPointSection->SetHeader (EntryPointSecHdr);
// set up our own section
for (int lp = 0; lp < 0x1000; lp ++)
newsectiondata[lp] = rand() % 255;
// for start of section, offset 0
unsigned char myasm[] = { 0xe9, 0x68, 0xCE, 0xFA, 0xAD, 0xDE, 0x5A, 0xB9, 0x00, 0x02, 0x00, 0x00, 0xBE, 0x00, 0x10,
0x40, 0x00, 0xBF, 0xFF, 0x40, 0x40, 0x00, 0x8A, 0x07, 0x30, 0x06, 0x46, 0xD1, 0xCA, 0xD0,
0xE0, 0x75, 0x15, 0x47, 0x81, 0xFF, 0x00, 0x50, 0x40, 0x00, 0x75, 0x05, 0xBF, 0xFF, 0x40,
0x40, 0x00, 0x33, 0xD6, 0x49, 0x75, 0xE2, 0xEB, 0x06, 0x26, 0x49, 0x85, 0xC9, 0x75, 0xDC,
0xEB, 0x39 };
// for ep, offset = 0x42
unsigned char myasm2[] = { 0x60, 0xE8, 0x2B, 0x00, 0x00, 0x00 };
// for calling OEP, offset = 0x77
unsigned char myasm3[] = { 0x58, 0x33, 0xD0, 0xBF, 0x91, 0x40, 0x40, 0x00, 0x89, 0x17, 0x61, 0xFF, 0x35, 0x91,
0x40, 0x40, 0x00, 0xE9, 0x73, 0xCF, 0xFF, 0xFF };
for (int lp = 0; lp < 62; lp++ ) newsectiondata[0x00+lp] = myasm[lp];
for (int lp = 0; lp < 6 ; lp++ ) newsectiondata[0x42+lp] = myasm2[lp];
for (int lp = 0; lp < 22; lp++ ) newsectiondata[0x77+lp] = myasm3[lp];
newsectiondata[0x71] = 0xca; // hide the JMP below
newsectiondata[0x72] = 0xeb;
newsectiondata[0x73] = 0xEB; // JMP 404001
newsectiondata[0x74] = 0x8C;
newsectiondata[0x75] = 0xca; // hide oep code from obvious view
newsectiondata[0x76] = 0xeb;
// Now patch it up... (relocate)
MakeLong (MaxToEncrypt, &newsectiondata[8]);
MakeLong (dwProgBase + EntryPointSecHdr.VirtualAddress, &newsectiondata[0x0d]);
MakeLong (newsectionhdr.VirtualAddress + dwProgBase + 0xFF, &newsectiondata[0x12]);
MakeLong (newsectionhdr.VirtualAddress + dwProgBase + 0xFFF, &newsectiondata[0x24]);
MakeLong (newsectionhdr.VirtualAddress + dwProgBase + 0xFF, &newsectiondata[0x2b]);
MakeLong (newsectionhdr.VirtualAddress + dwProgBase + 0x91, &newsectiondata[0x7b]);
MakeLong (newsectionhdr.VirtualAddress + dwProgBase + 0x91, &newsectiondata[0x84]);
newsectiondata[0x88] = 0x68; // PUSH original entry point onto stack
MakeLong (dwEntryPoint, &newsectiondata[0x89]);
newsectiondata[0x8D] = 0xC3; // RET to execute original code
// put encryption key into the new section
for (int lp = 0; lp < 0xF00; lp ++)
newsectiondata[0xFF + lp] = encryption_key[lp];
pnewsection->SetData(newsectiondata, 0x1000);
// change entry point to our code
Memo1->Lines->Add ("Setting header info...");
pe.m_Headers.GetNt(hdrNt);
hdrNt.OptionalHeader.AddressOfEntryPoint = newsectionhdr.VirtualAddress + 0x42;
pe.m_Headers.SetNt(hdrNt);
// rename all sections
Memo1->Lines->Add ("Rename all sections...");
int NumSections = pe.GetNumSections();
for (int lp=0; lp < NumSections; lp ++)
{
IMAGE_SECTION_HEADER CurrSect;
CSection *CSect;
CSect = pe.GetSectionByIndex(lp);
CSect->GetHeader(CurrSect);
strncpy (CurrSect.Name, ".scooble", 8);
CSect->SetHeader(CurrSect);
}
// Change base of code to us
pe.m_Headers.GetNt(hdrNt);
hdrNt.OptionalHeader.BaseOfCode = newsectionhdr.VirtualAddress;
pe.m_Headers.SetNt(hdrNt);
Memo1->Lines->Add ("Saving new file...");
pe.Write ("d:\\out.exe", 1);
Memo1->Lines->Add ("All done");
}
}
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -