如何在 C++ 中使用 Detours 扩展程序内函数而不进入无限循环?
Posted
技术标签:
【中文标题】如何在 C++ 中使用 Detours 扩展程序内函数而不进入无限循环?【英文标题】:How to extend an in-program function using Detours in c++ without going in an infinite loop? 【发布时间】:2013-06-08 10:15:00 【问题描述】:我正在尝试学习使用弯路来修改和扩展程序中的功能。在这种情况下,我正在尝试修改 Windows Notepad 32 位中的 InsertDateTime 函数。
我正在使用 Winject 注入我创建的用于修改函数的 dll。 DLL 被正确注入,函数被绕道到我指定的新函数。但是,我绕行 InsertDateTime() 的新函数应该在名为 MyInsertDateTime() 的新函数末尾调用 原始函数 InsertDateTime()。
但是,问题是,当新函数被调用并最终尝试调用旧函数时。当然,这一个也会在无限循环中依次被重定向/绕行。所以原函数永远无法调用!
不知何故,我想我需要分离新函数才能调用旧函数。但是当我这样做时,我得到了错误?然而,这可能是一些根本性的错误。我应该如何正确地做到这一点?
代码如下:
#include <iostream>
#include <windows.h>
#include "detours.h"
#pragma comment(lib, "detours.lib")
//
using namespace std;
static int(__stdcall* InsertDateTime)(int);
int MyInsertDateTime(int x) //Our function
MessageBox(NULL, TEXT("Detoured Function Call"), TEXT("Min funktion"), MB_OK);
return InsertDateTime(x); //Return the origional function
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
InsertDateTime = (int(__stdcall*)(int))(reinterpret_cast<DWORD>(GetModuleHandleA("notepad.exe")) + 0x978A);
switch (ul_reason_for_call) //Decide what to do
case DLL_PROCESS_ATTACH: //On dll attach
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach((PVOID*)(&InsertDateTime), (PVOID)MyInsertDateTime);
DetourTransactionCommit();
break;
case DLL_THREAD_ATTACH: //On thread attach
break;
case DLL_THREAD_DETACH: //On thread detach
break;
case DLL_PROCESS_DETACH: //on process detach
DetourDetach((PVOID*)(reinterpret_cast<DWORD>(GetModuleHandleA("notepad.exe")) + 0x978A), InsertDateTime);
break;
return TRUE;
最后是修改后的 MyInsertDateTime() ,我尝试在其中分离绕道。 分离时我可能做错了什么?
int MyInsertDateTime(int x) //Our function
//Messagebox
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach((PVOID*)(reinterpret_cast<DWORD>(GetModuleHandleA("notepad.exe")) + 0x978A), InsertDateTime);
DetourTransactionCommit();
MessageBox(NULL, TEXT("InsertDateTime Just Got Called"), TEXT("Min funktion"), MB_OK);
return InsertDateTime(x); //Return the origional function
【问题讨论】:
【参考方案1】:您应该只在卸载 DLL 时删除 DllMain 中的 Detour。
DetourAttach() 为您提供指向原始函数的函数指针。
看这里:
http://www.codeproject.com/Articles/30140/API-Hooking-with-MS-Detours
DetourAttach(&(PVOID&)pSend, MySend);
int WINAPI MySend(SOCKET s, const char* buf, int len, int flags)
fopen_s(&pSendLogFile, "C:\\SendLog.txt", "a+");
fprintf(pSendLogFile, "%s\n", buf);
fclose(pSendLogFile);
return pSend(s, buf, len, flags); // Calling original function obtained via the DetourAttach call, this will NOT cause MySend to be called again.
您可能会遇到问题,因为:
InsertDateTime = (int(__stdcall*)(int))(reinterpret_cast<DWORD>(GetModuleHandleA("notepad.exe")) + 0x978A);
可能是“错误”地址导致 jmp 位于错误位置。
【讨论】:
我认为地址应该是正确的。从 IDA Pro 我看到 InsertDateTime()+0 "0100978A" 的以下 andres。从这里我删除了我发现是 01000000 的图像库,它产生了“0x978A”。还是我错了?如果地址错误,我会在那种情况下看到任何消息框吗? 很难说,我只能假设它可能不是第一条指令,或者调用约定/参数不正确。 既然这已经被接受了,结果是你的问题吗? 好吧,不,程序还在无限循环中运行。 IE。当我尝试调用原始函数时,似乎一直在调用迂回函数。但是,至少你回答了我认为导致问题的是否应该分离迂回功能的问题。 我最终找到了问题...指针 InsertDateTime = (int(__stdcall*)(int))(reinterpret_cast以上是关于如何在 C++ 中使用 Detours 扩展程序内函数而不进入无限循环?的主要内容,如果未能解决你的问题,请参考以下文章
C++——Detours(Win32 API劫持)——劫持类方法
C++——Detours(Win32 API劫持)——劫持类方法