RenderDoc 启动原理
RenderDoc 会通过注入的方式,在所有Graphics API调用之前,在目标进程挂载 renderdoc.dll。这个dll挂载的时候会 wrap 所有的 Graphics API接口(与 壳 FAKER 的做法类似),然后在进程调用 Graphics API 的时候,进行需要的操作,例如:记录所有 API 调用时候的参数,从而完成对每帧数据的记录。 不同的 Graphics API 采用不同的 FAKER,例如:Vulkan 采取加载 RenderDoc 自定义的验证层的方式。
一些特殊的项目会对RenderDoc这样的工具进行检测,从而防止截帧。我们可以采取一些逆向的方案绕过检测,从而达到截帧的目的。
项目工程:/MagicRDC
Windows 平台 Android 模拟器环境
启动过程
Windows 平台上的 Android 模拟器在运行时,会首先加载 d3d11.dll。
可以通过制造一个 Fake d3d11.dll 的方式,在加载系统的 d3d11.dll 之后,接着加载 renderdoc.dll 即可。
LoadLibrary 加载 dll 的搜索路径是:
1.应用程序所在的目录
2.系统目录
3.当前工作目录
4.path变量中的目录
需要保证模拟器先加载 FAKER 。
以 Mumu 模拟器为例,进行说明。
Ps:模拟器注意需要下载 64 bit 版本,很多游戏已经不再支持32位了。
FAKER d3d11.dll
Fake dll 制作,参考开源库:
BOOL APIENTRY DllMain(HMODULE h_module, DWORD ul_reason_for_call, LPVOID lp_reserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
return dll::on_process_attach(h_module, lp_reserved);
break;
........................................................
inline BOOL on_process_attach(HMODULE h_module, LPVOID lp_reserved)
{
d3d11::hook_exports();
WRAPPER_ON_PROCESS_ATTACH_GLOBAL_NS(h_module, lp_reserved);
return TRUE;
}
修改
BOOL IsWow64()
{
typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process = nullptr;
BOOL bIsWow64 = FALSE;
//IsWow64Process is not available on all supported versions of Windows.
//Use GetModuleHandle to get a handle to the DLL that contains the function
//and GetProcAddress to get a pointer to the function if available.
fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
if (NULL != fnIsWow64Process)
{
if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
{
//handle error
}
}
return bIsWow64;
}
void hook_exports()
{
if (IsWow64())
{
chain = LoadLibrary("C:\Windows\SysWOW64\d3d11.dll");
}
else
{
chain = LoadLibrary("C:\Windows\System32\d3d11.dll");
}
........................................................................
加载d3d.dll之后,接着加载 renderdoc.dll ,具体的地址根据各自的项目而定(这里使用了绝对路径)。
void hook_exports()
{
.................................................................................
std::string rdcpath = "D:\RenderDoc\RenderDoc1.14\renderdoc.dll";
HMODULE renderdoc = LoadLibrary(rdcpath.c_str());
if (!renderdoc) {
MessageBox(NULL, "Unable to locate renderdoc (or compatible library to chain)", "ERROR: Failed to load original d3d11.dll", NULL);
exit(0);
}
}
编译得到d3d11.dll(fake) ,把生成的d3d11.dll(fake)放到 emulatornemudevice 文件夹下,(如果写的是相对路径,则renderdoc.dll拷贝到 emulatornemudevice 文件夹的相对路径下)
启动RDC
运行mumu模拟器,左上角应该会renderdoc 的信息
打开renderdoc,attach到进程上,点击:File->Attach to Running Instance 之后可以在界面中Capture了 。
文章来源: 博客园
- 还没有人评论,欢迎说说您的想法!