发现论坛里面很多用汇编做壳的.现发一个用C++做壳的程序.
壳中只实现了跳转到目标程序,其他什么都没做,大家看看思路就好啦.
使用方法:
Cpacker <in> <out>.
E.g. Cpacker.exe C:\calc.exe C:\calc_.exe
以下用windows的计算器程序做示范.
处理之后:
拷贝壳代码到新段,修改OEP指向壳的代码.
新段的结构:
我定义了一个结构体用来保存目标程序的OEP.
typedef struct _Exchange_Data_
{
DWORD dwBeginFlag;
DWORD dwSize;
DWORD dwVersion;
DWORD dwOEP;
DWORD dwImageBase;
DWORD dwEndFlag;
}ExchangeData, *PExchangeData;
//只关心在Release下的运行结果
//暂不考虑Debug版本,因为编译器的翻译成汇编码时,在Debug下会增加很多额外的代码.
壳代码:
#pragma optimize("", off) //关掉编译器的优化
int __stdcall Loader()
{
DWORD dwOriginalEntryPoint = 0;
DWORD dwCurrentAddr = 0;
DWORD dwEndFlag = 0;
//get current address
__asm{
call lbl_ref1
lbl_ref1:
pop dwCurrentAddr
}
//locate to the ExchangeData
while (dwEndFlag != 0x24681357)
{
dwEndFlag = (DWORD)(*(DWORD *)(--dwCurrentAddr));
}
PExchangeData ped = (PExchangeData)((DWORD)dwCurrentAddr);
//haha. you can do something before the original program run.
//jump to original program
dwOriginalEntryPoint = ped->dwOEP ;
__asm{
call dwOriginalEntryPoint
}
}
int __stdcall Loader_End()
{
return 0;
}
下面是增加段和修改OEP的代码:
//add a new section and change OEP
PIMAGE_SECTION_HEADER CPELibrary::AddCodeSection(char *szName, char *pSecBuff, DWORD dwSecSize, DWORD dwEntryPointOffset)
{
DWORD roffset, rsize, voffset, vsize;
int i = pNtHeader->FileHeader.NumberOfSections;
rsize = PEAlign(dwSecSize, pNtHeader->OptionalHeader.FileAlignment);
vsize = PEAlign(dwSecSize, pNtHeader->OptionalHeader.SectionAlignment);
roffset = PEAlign(pSecHeader[i-1]->PointerToRawData + pSecHeader[i-1]->SizeOfRawData, pNtHeader->OptionalHeader.FileAlignment);
voffset = PEAlign(pSecHeader[i-1]->VirtualAddress + pSecHeader[i-1]->Misc.VirtualSize, pNtHeader->OptionalHeader.SectionAlignment);
memset(pSecHeader[i], 0, sizeof(IMAGE_SECTION_HEADER));
pSecHeader[i]->PointerToRawData = roffset;
pSecHeader[i]->VirtualAddress = voffset;
pSecHeader[i]->SizeOfRawData = rsize;
pSecHeader[i]->Misc.VirtualSize = vsize;
pSecHeader[i]->Characteristics = 0xC0000040;
memcpy(pSecHeader[i]->Name, szName, strlen(szName));
pSecs[i] = new char[rsize];
memset(pSecs[i], 0, rsize);
memcpy(pSecs[i], pSecBuff, dwSecSize);
pNtHeader->FileHeader.NumberOfSections++;
pNtHeader->OptionalHeader.AddressOfEntryPoint = pSecHeader[i]->VirtualAddress + dwEntryPointOffset;
return (PIMAGE_SECTION_HEADER)pSecHeader[i];
}
附件是完整的工程(VS2005).
请指教.
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法