看了滴水3期视频中的加密壳然后开始动手
流程:
PE文件整个加密->壳新增节->将加密数据放入壳的新增节中->加密完成
解密:
获取壳的PE文件->取出加密数据进行解密->以挂起的方式创建进程->获取Context线程数据->使用 NtUnmapViewOfSection将卸载进程->在进程中申请内存VirtualAllocEx->解密数据拉伸进内存->将oep 和 imageBase 写入Context->恢复线程->完成
加密流程比较简单就说了 说解密流程几个重点地方
首先我这使用LoadLibrary来获取在内存中的指针 也就是ImageBuff
[C++] 纯文本查看 复制代码 //获取内存中的拉伸指针
HINSTANCE hImageBuff = LoadLibrary("decode.exe");
if (hImageBuff == NULL)
{
return 0;
}
然后以挂起的方式创建进程
[C++] 纯文本查看 复制代码 STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO));//初始化si在内存块中的值(详见memset函数)
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(STARTUPINFO);
ZeroMemory(&pi, sizeof(pi));
CreateProcess(TEXT("PETool 1.0.0.5.exe"),
NULL,
NULL,
NULL,
FALSE,
CREATE_SUSPENDED,
NULL,
NULL,
&si,
&pi
);
获取Context 将创建的进程进行卸载 Context.Ebx + 8的地方就是PE的 imageBase
[C++] 纯文本查看 复制代码 CONTEXT Context;
Context.ContextFlags = CONTEXT_FULL;
GetThreadContext(pi.hThread, &Context);
DWORD dwVictimBaseAddr = 0;
if (ReadProcessMemory(pi.hProcess, (LPCVOID)(Context.Ebx + 8), &dwVictimBaseAddr, sizeof(PVOID), NULL) == 0)
{
return -1;
}
ZwOfSection zw;
zw = (ZwOfSection)GetProcAddress(LoadLibrary("ntdll.dll"), "NtUnmapViewOfSection");
NTSTATUS nt = zw(pi.hProcess, (PVOID)dwVictimBaseAddr);
在挂起进程中申请内存
[C++] 纯文本查看 复制代码 char* Address = (char*)VirtualAllocEx(pi.hProcess, (PVOID)g_image_optional.optional32.ImageBase, g_image_optional.optional32.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
将数据拉伸后修复一下Context 就可以开始跑了
[Asm] 纯文本查看 复制代码 DWORD dwImageBase = g_image_optional.optional32.ImageBase;
WriteProcessMemory(pi.hProcess, (LPVOID)(Context.Ebx + 8), &dwImageBase, sizeof(PVOID), NULL);
//恢复
Context.Eax = dwImageBase + g_image_optional.optional32.AddressOfEntryPoint;
int a = SetThreadContext(pi.hThread, &Context);
a = ResumeThread(pi.hThread);
PS:还有一个问题 视频中说是以挂起的方式创建自己的进程 但是我创建自己进程后,恢复就会报c0005的错误 这个有没有大佬知道原因呢
|