看雪有很多讲war3全图的例子,还有很多大神讲了思路。比如写os的大神(bitt,还写过2个汉化教程,很赞)最早说的VEH + 硬件断点,现在还能用,问题的关键在于内存隐藏。而关于这一点v校讲过,不过大神的思路(那张图已经很清楚了)需要仔细体会才有收获的。这篇算是这段时间学习笔记吧,还有很多忘了说的和没完成的,就不想弄了。注意看完了基本也不一定能写全图,需要自己调试一下,你懂的。
1, Achillis(似乎叫黑月教主)说过“对付API就用抹链,对付抹链就用暴搜,对付暴搜就把PE头抹了,对付抹PE头就ZwQueryVirtualMemory,对付QueryMemory 就自己做Loader或ReloadandRun然后再抹一抹就只有a piece of code了,但是还是占了一块内存。我在想怎么改VAD把内存 占用也隐藏掉~~”,还说过Load的时候不用CreateFileMapping,二用ReadFile,就不会被PsLoadImageNotifyRoutine发现了。不过似乎还是比较难写的。隐藏的前面几步有个非常好的Jboy的贴子,想不通为什么不加精,,可是是delphi的,可能看的不习惯我改成c了,原理就是Load ,保存一份,Free,把备份的粘贴回来,就断链了,这样做的好处是方便。断链也是可以的。
VOID LockAllModules()
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(
TH32CS_SNAPMODULE, GetCurrentProcessId());
if (hSnapshot != INVALID_HANDLE_VALUE) {
MODULEENTRY32 me = {sizeof(me)};
BOOL fOk = Module32First(hSnapshot, &me);
for (fOk = Module32Next(hSnapshot, &me); fOk; fOk = Module32Next(hSnapshot, &me)){ //跳过第一个;
LoadLibrary(me.szModule);
}
}
}
BOOL CopycatAndHide(HMODULE hDll)
{
IMAGE_DOS_HEADER * pDosHeader;
IMAGE_NT_HEADERS * pNtHeader;
IMAGE_OPTIONAL_HEADER * pOptionalHeader;
LPVOID lpBackMem = 0;
DWORD dwOldProtect;
DWORD dwCount = 30;
pDosHeader = (IMAGE_DOS_HEADER *)hDll;
pNtHeader = (IMAGE_NT_HEADERS *)(pDosHeader->e_lfanew + (DWORD)hDll);
pOptionalHeader = (IMAGE_OPTIONAL_HEADER *)&pNtHeader->OptionalHeader;
LockAllModules();
lpBackMem = VirtualAlloc(0 ,pOptionalHeader->SizeOfImage ,MEM_COMMIT|MEM_RESERVE ,PAGE_EXECUTE_READWRITE);
if(!lpBackMem)
return FALSE;
if(!VirtualProtect((LPVOID)hDll ,pOptionalHeader->SizeOfImage ,PAGE_EXECUTE_READWRITE ,&dwOldProtect))
return FALSE;
g_dwImageSize = pOptionalHeader->SizeOfImage;
memcpy(lpBackMem ,(LPVOID)hDll ,g_dwImageSize );
memset(lpBackMem , 0 ,0x200);
*((PBYTE)hDll + pOptionalHeader->AddressOfEntryPoint) = (BYTE)0xc3;
// DWORD dwRet =0;
do{
dwCount --;
}while(FreeLibrary(hDll) && dwCount);
g_lpNewImage = VirtualAlloc((LPVOID)hDll ,g_dwImageSize ,MEM_COMMIT|MEM_RESERVE ,PAGE_EXECUTE_READWRITE);
if(g_lpNewImage != (LPVOID)hDll)
return FALSE;
memcpy(g_lpNewImage , lpBackMem , g_dwImageSize);
VirtualFree(lpBackMem , 0, MEM_RELEASE);
return TRUE ;
}
typedef ULONG WIN32_PROTECTION_MASK ;
NTSTATUS
MyNtProtectVirtualMemory(
__in HANDLE ProcessHandle,
__inout PVOID *BaseAddress,
__inout PSIZE_T RegionSize,
__in WIN32_PROTECTION_MASK NewProtectWin32,
__out PULONG OldProtect
)
{
typedef NTSTATUS
(* PtrNtProtectVirtualMemory)(
__in HANDLE ProcessHandle,
__inout PVOID *BaseAddress,
__inout PSIZE_T RegionSize,
__in WIN32_PROTECTION_MASK NewProtectWin32,
__out PULONG OldProtect
);
NTSTATUS NtStatus = STATUS_SUCCESS;
PCHAR ProcessName ;
ProcessName = (PCHAR)PsGetProcessImageFileName(PsGetCurrentProcess());
if(GameModule &&
(ULONG)GameModule <= (ULONG)BaseAddress &&
(ULONG)GameModule + GameModuleSize > (ULONG)BaseAddress)
{
if(NewProtectWin32 != PAGE_READONLY)
return STATUS_SUCCESS;
}
if(MhDllModule &&
(ULONG)MhDllModule <= (ULONG)BaseAddress &&
(ULONG)MhDllModule + MhDllModuleSize > (ULONG)BaseAddress)
{
// return ERROR_INVALID_ADDRESS;
return 487L;
}
if(FakeModule &&
(ULONG)FakeModule <= (ULONG)BaseAddress &&
(ULONG)FakeModule + FakeModuleSize > (ULONG)BaseAddress)
{
return 487L;
}
}
if(OldServiceAddressTable[0x0D7])
NtStatus = ((PtrNtProtectVirtualMemory)OldServiceAddressTable[0x0D7])(ProcessHandle ,BaseAddress ,RegionSize ,NewProtectWin32 ,OldProtect);
return NtStatus;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)