写了个Dll,名字是"InfuseDll.dll",DllMain里LoadLibrary钩子dll并安装钩子,钩子dll用来捕获按键,是前几天写的,测过了没问题.正常LoadLibrary("InfuseDll.dll")也没问题,钩子能正常用,可是将该dll注入到其它进程时钩子就不起作用了,不知道为什么.代码如下:// 注入部分的代码,写在一个Exe程序中,目的将"InfuseDll.dll"注入"Hou2Server.exe"进程.跟踪发现函数执行都正常.
HANDLE hRemoteProcess;
// 得到一个进程的ID
DWORD dwRemoteProcessId = FindTarget("Hou2Server.exe");
// 打开远程进程
hRemoteProcess = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE, FALSE, dwRemoteProcessId);
if(NULL == hRemoteProcess)
{
AfxMessageBox("打开远程进程失败!");
return;
} PWSTR pszLibFileRemote = NULL;
int iReturnCode;  
    WCHAR pszLibFileName[MAX_PATH]={0}; char szPathName[MAX_PATH];
memset(szPathName, 0, sizeof(szPathName));
GetCurrentDirectory(MAX_PATH, szPathName);
strcat(szPathName, "\\InfuseDll.dll");
// 将DLL文件全路径的ANSI码转换成UNICODE码
iReturnCode = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, szPathName, strlen(szPathName),
pszLibFileName, MAX_PATH);
int cb = (1 + lstrlenW(pszLibFileName)) * sizeof(WCHAR);  pszLibFileRemote = (PWSTR)VirtualAllocEx(hRemoteProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if(NULL == pszLibFileRemote)
{
AfxMessageBox("Fun VirtualAllocEx() Err");
return;
} // 将DLL的路径名复制到远程进程的内存空间
iReturnCode = WriteProcessMemory(hRemoteProcess, pszLibFileRemote, (PVOID)pszLibFileName, cb, NULL);
if(0 == iReturnCode)
{
AfxMessageBox("Func WriteProcessMemory() Err");
return;
}
// 计算LoadLibraryW的入口地址
    PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(
GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");

// 启动远程线程,通过远程线程调用用户的DLL文件
    HANDLE hRemoteThread = CreateRemoteThread( hRemoteProcess, NULL, 0, pfnStartAddr, pszLibFileRemote, 0, NULL); 
if(NULL == hRemoteThread)
{
AfxMessageBox("Fun CreateRemoteThread() Err");
return;
}
// 等待远程线程退出
    WaitForSingleObject(hRemoteThread, INFINITE);  // 清场处理
if(pszLibFileRemote != NULL)
{
        VirtualFreeEx(hRemoteProcess, pszLibFileRemote, 0, MEM_RELEASE);
}
    if (hRemoteThread != NULL)
{
CloseHandle(hRemoteThread );
}
    if (hRemoteProcess!= NULL)
{
CloseHandle(hRemoteProcess);
}// Infuse.dll代码如下:
int InitDll()
{
g_hHookDll = LoadLibrary("D:\\Lx\\Dll Infuse\\Debug\\myhook.dll");
if(g_hHookDll == NULL)
{
MessageBox(NULL, "Module=InfuseDll : LoadLibrary fail", "Error", MB_ICONINFORMATION);
return -1;
}
typedef bool (*pFunc)();
pFunc myFunc = (pFunc)GetProcAddress(g_hHookDll, "InStallHook");
if(NULL == myFunc)
{
MessageBox(NULL, "Module=InfuseDll : GetProcAddress fail", "Error", MB_ICONINFORMATION);
return -1;
}
myFunc();

return 0;
}int UnInitDll()
{
if(!FreeLibrary(g_hHookDll)) return -1;
return 0;
}BOOL WINAPI DllMain(/*HANDLE*/HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)    
    {    
    case DLL_PROCESS_ATTACH:
InitDll();
MessageBox( NULL, "DLL_PROCESS_ATTACH", "MESSAGE", MB_ICONINFORMATION ); // 注释掉此句记事本死掉问题解决!
break;
case DLL_PROCESS_DETACH:
UnInitDll();
MessageBox( NULL, "DLL_PROCESS_DETACH", "MESSAGE", MB_ICONINFORMATION );
break;
case DLL_THREAD_ATTACH:
// InitDll();
MessageBox( NULL, "DLL_THREAD_ATTACH", "MESSAGE", MB_ICONINFORMATION );
break;
case DLL_THREAD_DETACH:
// UnInitDll();
MessageBox( NULL, "DLL_THREAD_ATTACH", "MESSAGE", MB_ICONINFORMATION );
break;
}
return true;
}// 钩子dll先不贴了,我觉得问题可能不会出在钩子dll上,如有需要再贴出来.

解决方案 »

  1.   

    估计是OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE那里需要调整为DEBUG状态特权
      

  2.   

    if(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) 
    {
    // 取得特权名称为“SetDebugPrivilege”的LUID
    LUID uID;
    ::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &uID); // 调整特权级别
    TOKEN_PRIVILEGES tp;
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = uID;
    tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
    ::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
    bOk = (::GetLastError() == ERROR_SUCCESS); // 关闭访问令牌句柄
    ::CloseHandle(hToken);
    }
      

  3.   

    在一个DLL中通过LoadLibrary的方式来加载另外一个DLL,这个过程不能在入口点函数中执行,否则系统会死锁,这个现象俗称DLL地狱。 
    用隐式调用吧
      

  4.   

    1.我注入的是我自己写的进程.
    2.g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hDll, 0);这一句执行了,并且g_hHook != NULL,但KeyboardProc函数似乎没执行,无论按什么键都捕获不到.
      

  5.   

    注入了,但KeyboardProc函数没执行,注入的是我自己写的程序,没设什么权限.
      

  6.   

    具体问题是钩子没作用还是目标进程出错?“钩子dll用来捕获按键”是SetWindowsHookEx吗?该函数执行到了吗?
    如果只是要监视某个窗口的键盘消息,直接做个DLL用SetWindowsHookEx钩窗口所属线程即可,不用另做个DLL注入。
      

  7.   

    钩子函数没起作用.SetWindowsHookEx函数执行到了.
      

  8.   

    SetWindowsHookEx的参数怎么给的?在Hook函数中加个MessageBox不会显示是吗?
    另外,这种情况可以用一个DLL来SetWindowsHookEx就可以,不用另外注入一个DLL。
      

  9.   

    如果不注入的话钩子是成功的.但是我现在在学DLL注入,写这个小程序就是想练习DLL注入.LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    char szTmp[100];
    if((HC_ACTION == nCode) && (1 == (lParam >> 31 & 1)))
    {
    if((wParam >= 0x30) && (wParam <= 0x39)) // 0~9
    {
    sprintf(szTmp, "您按下了: %d", wParam - 0x30);
    MessageBox(NULL, szTmp, "INFO", MB_ICONINFORMATION);
    }
    }

    // 让消息继续传递
    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
    }bool __declspec(dllexport)InStallHook()
    {
    g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hDll, 0);
    if(NULL == g_hHook)
    {
    MessageBox(NULL, "Func SetWindowsHookEx fail", "MESSAGE", MB_ICONINFORMATION);
    return false;
    }
    MessageBox(NULL, "Func SetWindowsHookEx Success", "MESSAGE", MB_ICONINFORMATION);
    return true;
    }注入时弹出了"Func SetWindowsHookEx Success"但KeyboardProc函数没执行.
      

  10.   

    关了防毒软件没用的,杀毒软件把你的系统SSDT HOOK了,你无论怎么样也不会注入成功的。你装的是什么杀毒软件?
      

  11.   

    在case DLL_PROCESS_ATTACH: 里用LoadLibrary加载库出问题的可能本来就非常大,
    你把SetWindowsHookEx放在Infuse.dll中就是了,不要再搞个myhook.dll,练习DLL注入这个目的不是也达到了吗
      

  12.   

    调用SetWindowsHookEx的线程不能退出,如果线程退出,键盘钩子就不起作用了。
      

  13.   

    建议在 那个用来注入的dll里面, 在dllmain的DLL_PROCESS_ATTACH自己建立个线程, 在起来的线程里调用SetWindowsHookEx做hook,
    然后这个线程不能退出, 就是放个消息循环上去就可以吧