RenderDoc 启动原理

RenderDoc 会通过注入的方式,在所有Graphics API调用之前,在目标进程挂载 renderdoc.dll。这个dll挂载的时候会 wrap 所有的 Graphics API接口(与 壳 FAKER 的做法类似),然后在进程调用 Graphics API 的时候,进行需要的操作,例如:记录所有 API 调用时候的参数,从而完成对每帧数据的记录。 不同的 Graphics API 采用不同的 FAKER,例如:Vulkan 采取加载 RenderDoc 自定义的验证层的方式。

一些特殊的项目会对RenderDoc这样的工具进行检测,从而防止截帧。我们可以采取一些逆向的方案绕过检测,从而达到截帧的目的。

项目工程:VestLee/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 制作,参考开源库:SeanPesce/d3d11-wrapper

可以使用这个轮子进行修改,使得模拟器可以在加载 FAKER 之后加载 renderdoc.dll

去掉“sp/environment.h”等未找到的头文件,和相关的函数使用,变量声明(对编译没影响)。

在 dllmain.h &cpp 中,dll 入口函数中,DLL_PROCESS_ATTACH 创建线程事件中会触发函数:d3d11::hook_exports(),

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;
}

修改 d3d11::hook_exports() 函数,首先判断当前环境是否是64 bit,从而决定加载对应的d3d11.dll(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了 。

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/vestlee/p/17003036.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!