Revive的inject技术

首先,InjectDLL函数:

bool InjectDLL(HANDLE hProcess, const char *dllPath, int dllPathLength)
{
	LOG("Injecting DLL: %s\n", dllPath);

	HMODULE hModule = GetModuleHandle(L"kernel32.dll");
	LPVOID loadLibraryAddr = (LPVOID)GetProcAddress(hModule, "LoadLibraryA");
	if (loadLibraryAddr == NULL)
	{
		LOG("Unable to locate LoadLibraryA\n");
		return false;
	}
	LOG("LoadLibrary found at address: 0x%x\n", loadLibraryAddr);

	LPVOID loadLibraryArg = (LPVOID)VirtualAllocEx(hProcess, NULL, dllPathLength, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
	if (loadLibraryArg == NULL)
	{
		LOG("Could not allocate memory in process\n");
		return false;
	}

	int n = WriteProcessMemory(hProcess, loadLibraryArg, dllPath, dllPathLength, NULL);
	if (n == 0)
	{
		LOG("Could not write to process's address space\n");
		return false;
	}

	HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddr, loadLibraryArg, NULL, NULL);
	if (hThread == INVALID_HANDLE_VALUE)
	{
		LOG("Failed to create remote thread in process\n");
		return false;
	}

	DWORD waitReturnValue = WaitForSingleObject(hThread, INFINITE);
	if (waitReturnValue != WAIT_OBJECT_0) {
		LOG("Failed to wait for LoadLibrary to exit\n");
		return false;
	}
	DWORD loadLibraryReturnValue;
	GetExitCodeThread(hThread, &loadLibraryReturnValue);
	if (loadLibraryReturnValue == NULL) {
		LOG("LoadLibrary failed to return module handle\n");
		return false;
	}
	return true;
}

GetModuleHandle:获取进程已经加载的模块句柄。

GetProcAddress:取得kernel32.dll的基地址

VirtualAllocEx:在远程进程空间中分配存储dll文件路径名的内存空间

WriteProcessMemory:复制dll文件路径名到远程刚分配的进程空间

CreateRemoteThread:创建远程线程,参数loadLibraryAddr为LoadLibraryA的地址,参数loadLibraryArg为要加载的dll路径名,

WaitForSingleObject:等待线程返回


远程线程进行dll注入流程:

1.取得远程进程的ID号

2.在远程进程空间中分配一段内存,用来存放要注入的dll的完整路径

3.将要注入的dll的路径写到第2步分配的远程进程空间

4.从kernel32.dll中取得LoadLibrary的地址

5.调用CreateRemoteThread函数以从Kernel32.dll中取得LoadLibrary函数的地址,作为线程函数的地址;用需要注入的dll文件名作为参数,创建远程线程

(创建LoadLibraryA线程来启动dll,LoadLibraryA存在系统的kernel32.dll中用来加载dll模块,该函数参数为dll文件的名称,包括路径。由于加载dll操作是在其他进程中进行,因此需要把dll文件名称拷贝到目标进程中的地址空间中)。使用VirtualAllocEx函数为dll文件名在目标进程中分配地址空间,在使用WriteProcessMemory将dll的文件名拷贝到分配的地址中。下一步取得LoadLibraryA函数的入口地址。由于kenrnel32.dll模块是系统的核心模块,因此,该模块中的函数地址在所有进程中都是一样的,LoadLibrary类似于此。

最后,使用CreateRemoteThread函数,将Load LibraryA函数的入口地址以及dll文件名作为参数,创建线程以加载自定义的dll文件,在dll文件中的DLL_PROCESS_ATTACH条件下可写入需要注入的操作。

此处注入了LibRevive64_1.dll或LibRevive32_1.dll 以及 openvr_api.dll文件,并创建它们对应的线程。


总结:

因此可知,Revive 整个流程及其原理大概为:

ReviveOverlay启动控制面板,系统例程中启动ReviveInject.exe并在后添加游戏路径名,以游戏路径名为参数,创建一个挂起子进程,再将LibRevive64_1.dll以及openvr_api.dll注入,再恢复启动该进程,之后,该游戏运行所需要的参数均来自于被注入的两个dll(而此时的LibRevive64_1.dll中的接口内部实现均使用openVR的API),而不再是它本来Oculus接口获取到的数据了。若检测到游戏在加载Oculus自身runtime的LibOVRRT64_1.dll库时(路径:C:\Program Files\Oculus\Support\oculus-runtime),则将其换成LibRevive64_1.dll库。



参考网址1

参考网址2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值