extern "C" __declspec(dllexport) void* __stdcall GetShadowModuleMem(char * ModuleName)
{
MODULEINFO tModuleinfo ;
MEMORY_BASIC_INFORMATION memInfo;
PVOID nSectionBase = NULL;
INT nSectionSize = NULL;
INT nQueryMem = NULL;
char* tMouduleBase = NULL;
HMODULE hMouduleBase = GetModuleHandle(ModuleName); //获取模块句柄_基地址
BOOL tIf = GetModuleInformation(GetCurrentProcess(), hMouduleBase, &tModuleinfo, sizeof(tModuleinfo));
INT nMouduleSize = tModuleinfo.SizeOfImage;
PVOID pMouduleEndSize = (char*)hMouduleBase + nMouduleSize;
if (tIf)
{
PVOID pShadowMoudule = VirtualAlloc(NULL, nMouduleSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);//申请同等大小的内存
if (pShadowMoudule == NULL)
{
return 0;
}
nSectionBase = hMouduleBase;
tMouduleBase = (char*)pShadowMoudule;
do
{
nQueryMem = VirtualQuery(nSectionBase, &memInfo, sizeof(memInfo));
if (nQueryMem==0)
{
break;
}
if (memInfo.Type == MEM_IMAGE)
{
nSectionBase = memInfo.BaseAddress;
nSectionSize = memInfo.RegionSize;
nSectionBase = (char*)nSectionBase + nSectionSize;
if (nSectionBase >= pMouduleEndSize)
{
break;
}
else
{
DWORD dOldProtect = NULL;
if (IsBadReadPtr(memInfo.BaseAddress, memInfo.RegionSize) != 0)
{
if(VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, PAGE_EXECUTE_READWRITE, &dOldProtect))
{
memcpy(tMouduleBase, memInfo.BaseAddress, memInfo.RegionSize); //拷贝模块到申请的内存中
tMouduleBase = (char*)tMouduleBase + memInfo.RegionSize;
VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, dOldProtect, &dOldProtect);
}
else
{
tMouduleBase = (char*)tMouduleBase + memInfo.RegionSize;
}
}
else
{
memcpy(tMouduleBase, memInfo.BaseAddress, memInfo.RegionSize); //拷贝模块到申请的内存中
tMouduleBase = (char*)tMouduleBase + memInfo.RegionSize;
}
}
}
} while (nQueryMem != 0);
return pShadowMoudule;
}
return 0;
/*
INT nMouduleSize = _getModuleBaseAddr(hMouduleBase);//从PEB中获取模块所占内存空间大小
if (nMouduleSize=0)
{
return 0;
}
*/
}
写了一个动态内存中拷贝模块镜像 然后 计算CRC的动态校验.现在有个问题.个别dll 如ntdll 属性啥都对..拉进去就崩溃..修改属性也是没问题的.但是就是拷贝崩溃..有没有大佬知道什么问题..已经动态调试执行过了 ntdll 代码段属性为0 修改属性OK 但是执行还是崩溃..
又调试了下 大概知道问题了..但是还是很好奇.为啥会这么分配..
内存查询属性页又是另一个状态...有没有大佬解释下..
这里是内存页状态.. 理论上来说 内存不都应该是一个块连续一个块么..如果不是.那么 类似这种的我要怎么写..因为是计算crc 内存块大小和节段之间距离需要一致..
------------------------------------------------------------------------------
结贴.不影响模块拷贝.虚块内存也是在里边的.内存模块大小没有错误..感谢楼下老哥 指出错误..一直用VirtualProtect 从未判断过返回..- - 感谢指点..这么写没有问题.. 读出来的模块大小是对了..一直纠结错地方了.. 不用管怎么分配 舍弃不能读的内存就好了..
------------------------------------------------------------------------------------------------------------------------------------------
那么顺便写下关于 VMP 3.2 sdk中的 VMProtectIsValidImageCRC 如何处理.
以我自己加壳的程序为例.随意对校验代码段数据进行 硬件访问断点.找到类似以下伪代码 的地方.
mov reg32,dword ptr ds:[reg32]
mov reg32,dword ptr ds:[reg32+0x4]
add reg32,0x4
test reg32,reg32
je xxxxaddr
@calc_CRC:
movzx reg32,byte ptr ds:[reg32]
xor reg32,reg32
and reg32,0xFF
mov reg32,dword ptr ds:[reg32*4+0xxxxxxx]
shr reg32,0x8
xor reg32,reg32
xor reg32,0xxxxxxxxxxx
dec reg32
jnz calc_CRC
mov reg32,dword ptr ds:[reg32]
mov reg32,dword ptr ds:[reg32+0x4]
add reg32,0x4
test reg32,reg32
je xxxxaddr
@calc_CRC:
movzx reg32,byte ptr ds:[reg32]
xor reg32,reg32
and reg32,0xFF
mov reg32,dword ptr ds:[reg32*4+0xxxxxxx]
shr reg32,0x8
xor reg32,reg32
xor reg32,0xxxxxxxxxxx
dec reg32
jnz calc_CRC
部分代码可能不一样 以实例为准.
已知 :
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-4-10 05:11
被bambooqj编辑
,原因: