如何在c ++中使用Detours扩展程序内函数而不进入无限循环?

时间:2013-06-08 10:15:01

标签: c++ detours

我正在努力学习使用绕道来修改和扩展程序中的功能。在这种情况下,我试图修改Windows记事本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 个答案:

答案 0 :(得分: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出错。