0

好的,我会尽量让它快点。我正在尝试学习如何在另一个进程中注入 DLL。目前,我只是在尝试检测打开计算器时何时输出消息。我编写了以下 DLL:

#include <windows.h>
#include <iostream>

using namespace std;
extern "C"{
    LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
    {       
       cout << "I'M NOT WORKING " << endl;
       // Bunch of code...
       return CallNextHookEx(0, nCode, wParam, lParam);
    } 
    void ASimpleFunc(){
        cout << "DLL WORKING" << endl;
    }
}

这是我的注入器(嗯……它现在只是试图加载 DLL)。

#include <windows.h>
#include <iostream>

using namespace std;
typedef LRESULT (*CBTProc)(int,WPARAM,LPARAM); 
typedef void (*ASimpleFunc)(); 
int main()
{   
    // My two functions... 
    LRESULT _CBTProc;
    ASimpleFunc _ASimpleFunc;

   HMODULE hDll = LoadLibrary("myDLL.dll");
   if(!hDll){
       cout << "DLL FAILED TO LOAD" << endl;
   }else{
       cout << "DLL LOAD SUCCESS" << endl;

       // This one is working
       _ASimpleFunc = (ASimpleFunc)GetProcAddress(hDll, "ASimpleFunc");

       // This one is not working
        _CBTProc = (CBTProc)GetProcAddress(hDll, "CBTProc");
        if(!_ASimpleFunc || !_CBTProc){
            cout << "UNABLE TO CALL HOOK" << endl;
        }else{
            // other code...
        }
    }
   return 1;
} 

有任何想法吗?

编辑:这不是 100% 的代码。我取出了明显的东西,比如 DLLMain 和所有不直接与我的问题交互的东西。

4

3 回答 3

2

CALLBACK宏给出了CBTProcstdcall 调用约定,因此它的名称将使用前导下划线和字节数进行注释(例如,它可能是_CBTProc@12)。您需要GetProcAddress使用导出的确切名称进行调用。可以使用 dumpbin 工具找到该名称。

请注意,您的函数指针也必须带有注释,CALLBACK以便当您通过函数指针调用函数时,使用正确的调用约定。

于 2013-01-03T03:48:11.420 回答
1

您需要实际让 DLL 加载到其他进程中才能正常工作。您可以通过在将加载您的 DLL 的其他进程中创建一个远程线程来执行此操作。

然后你需要在加载的时候执行你的钩子DLLMain来钩住你想要钩住的函数。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx

http://en.wikipedia.org/wiki/DLL_injection

这两个链接应该为您指明正确的方向。

于 2013-01-03T03:44:26.820 回答
0

我不知道为什么其中一个可以在没有这个的情况下工作,但是如果你想从 DLL 中导出一个函数,你必须显式地导出它。有两种方法可以做到这一点:

  1. 通过一些特定于编译器的方式告诉编译器。

    对于Visual C++使用__declspec(dllexport).

  2. 使用模块定义文件。

于 2013-01-03T03:44:51.063 回答