MiniDumpWriteDump杂记

暂无图片

为什么叫杂记主要是我词穷了好久没写博客了随便水水,因为一些原因需要临时写一个绕过AV dump lsass,直接用系统调用这种方法就不用说了,这种方法对于R3 HOOK还行。对于采用降权操作的AV来说这招没用

我们需要用到的东西有某哈游驱动,ReactOS,VS,思路是我们通过直接重写整个MiniDumpWriteDump函数(包括MiniDumpWriteDump内部调用的函数),替换整个dump过程中所有使用ReadProcessMemory函数的地方,将ReadProcessMemory函数换成我们自己用驱动实现的进程内存读取

为了方便可以使用这个项目中的部分代码https://github.com/w1u0u1/minidump
这个项目已经照着ReactOS重写了MiniDumpWriteDump函数的部分代码并且他部分函数如ReadProcessMemory,OpenProcess等等都使用了系统调用的方式重写,不过这对我们来说没什么用可以忽略直接改回正常的就行,因为他MiniDumpWriteDump函数重写的不完全,所以我们要做的就是补全剩下所有的函数并且将所有调用ReadProcessMemory函数的地方替换成我们自己用驱动实现的ReadProcessMemory

具体举个例子
比如原作者重写了fetch_modules_info函数但是fetch_modules_info函数里调用的EnumerateLoadedModulesW64函数他就没有重写而我们就得重写因为这个函数里有别的函数调用了ReadProcessMemory

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
BOOL WINAPI my_EnumerateLoadedModulesW64(HANDLE hProcess,PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback,PVOID UserContext)
{
HMODULE* hMods;
WCHAR baseW[256], modW[256];
DWORD i, sz;
MODULEINFO mi;

hMods = (HMODULE*)HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(hMods[0]));
if (!hMods) return FALSE;

if (!my_EnumProcessModules(hProcess, hMods, 256 * sizeof(hMods[0]), &sz))
{
/* hProcess should also be a valid process handle !! */
printf("If this happens, bump the number in mod\n");
HeapFree(GetProcessHeap(), 0, hMods);
return FALSE;
}
sz /= sizeof(HMODULE);
for (i = 0; i < sz; i++)
{
if (!myGetModuleInformation(hProcess, hMods[i], &mi, sizeof(mi)) ||
!myGetModuleBaseNameW(hProcess, hMods[i], baseW, ARRAY_SIZE(baseW)))
continue;
module_fill_module(baseW, modW, ARRAY_SIZE(modW));
EnumLoadedModulesCallback(modW, (DWORD_PTR)mi.lpBaseOfDll, mi.SizeOfImage,
UserContext);
}
HeapFree(GetProcessHeap(), 0, hMods);

return sz != 0 && i == sz;
}

需要注意的因为EnumerateLoadedModulesW64函数内部调用了EnumProcessModules,GetModuleInformation,GetModuleBaseNameW这三个函数而这三个函数内部调用了ReadProcessMemory所以这三个函数也要重写

替换如图所示

image.png

稍微要提一下的是这个驱动读内存没有对是否成功进行返回所以我们需要自己通过验证缓冲区值是否改变来以此当作一个判断标准

image.png

这里我就拿卡巴做一下示范

image.png

更多的细节都在源码和驱动中自己去看吧我也实在是懒的继续细写了

https://github.com/WBGlIl/mhydump bin文件在zip里因为是临时写的比较匆忙代码有些乱

最后呢说几句题外话,dump lsass有必要dump全部内存和加载的模块吗,能不能将需要的部分dump下来这样可以大大减少dump文件的体积,这个问题就和mimikatz加载dump文件搜索hash密码相关了。我们重写MiniDumpWriteDump函数的目的是替换ReadVirtualMemory函数那么通过HOOK ReadVirtualMemory也能实现这样就省去了重写的步骤不必那么麻烦,什么时候重写MiniDumpWriteDump比较合适?什么时候HOOK MiniDumpWriteDump比较合适?dump文件头魔数是否有必要写入磁盘避免被部分AV识别到的

顺便补充一点我这里用的是最简单粗暴的方法

相关参考链接

https://reactos.org/

https://github.com/w1u0u1/minidump

https://www.unknowncheats.me/forum/anti-cheat-bypass/419457-mhyprot2-read-process-kernel-memory-valid-signature-driver.html

https://rayanfam.com/topics/reversing-windows-internals-part1/

1613669921178.png