demo.dll   ------- dll
hook.exe   ------- 注入程序
test.exe   ------- 测试程序运行hook.exe 把demo.dll注入test.exe,使得test里面的MessageBox()函数,运行我的demo.dll里的函数。
这个程序在debug下成功。但是,在release下却没有反应,test.exe仍然运行的是原来的函数。内存的属性页页改过的。
p = VirtualAllocEx(hKernel32, NULL, strlen(pDllName)+1, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hKernel32, p, pDllName, strlen(pDllName)+1, NULL);
pfn = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
CreateRemoteThread(hKernel32, NULL, 0, (LPTHREAD_START_ROUTINE)pfn, p, NULL, 0);就是不知道为什么在release下不成功!
希望各位有经验的人可以指点一下,谢谢大家。
---------------------------
附程序代码//------------------------- test.cpp ------------------------//
#include <stdio.h>
#include <windows.h>void main()
{
while(1)
{
getchar();
MessageBox(NULL, "a", "b", 0);
}
}//------------------------- hook.cpp ------------------------//
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>#pragma comment(lib, "th32.lib")char *pDllName = "Demo.dll";char *pProcess = "Test.exe";int main()
{
HANDLE hSnap;
HANDLE hKernel32;
PROCESSENTRY32 pe;
BOOL bNext;
BOOL bFound = 0;
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID Luid;
LPVOID p;
FARPROC pfn; if(!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
&hToken))
{
printf("OpenProcessToken error!\n");
return 1;
} if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid))
{
printf("LookupPrivilegeValue error!\n");
return 1;
} tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = Luid; if(!AdjustTokenPrivileges(hToken,
0,
&tp,
sizeof(TOKEN_PRIVILEGES),
NULL,
NULL))
{
printf("AdjustTokenPrivileges error!\n");
return 1;
} pe.dwSize = sizeof(pe);
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
bNext = Process32First(hSnap, &pe);
while(bNext)
{
if(!stricmp(pe.szExeFile, pProcess))
{
hKernel32 = OpenProcess(
//PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION,
PROCESS_ALL_ACCESS,
FALSE,
pe.th32ProcessID);
bFound = 1;
break;
}
bNext = Process32Next(hSnap, &pe);
} CloseHandle(hSnap); if(bFound)
{
p = VirtualAllocEx(hKernel32, NULL, strlen(pDllName)+1, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hKernel32, p, pDllName, strlen(pDllName)+1, NULL);
pfn = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
CreateRemoteThread(hKernel32, NULL, 0, (LPTHREAD_START_ROUTINE)pfn, p, NULL, 0);
}
else
printf("Not found the process!\n"); return 0;
}//------------------------- hook.cpp ------------------------//
#include <windows.h>
#include <process.h>
#include <tlhelp32.h>
#include <stdio.h>#pragma comment(lib, "th32.lib")PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS pNTHeaders;
PIMAGE_OPTIONAL_HEADER pOptHeader;
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor;
PIMAGE_THUNK_DATA pThunkData;
PIMAGE_IMPORT_BY_NAME pImportName;
HMODULE hMod;// 定义MessageBoxA函数原型typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);
int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType);int * addr1 = (int *)MessageBox;     //保存函数的入口地址
int * myAddr = (int *)MessageBoxProxy;/*
typedef int (WINAPI *PFNWRITEFILE)(HANDLE hFile,
   LPCVOID lpBuffer,
   DWORD nNumberOfBytesToWrite,
   LPDWORD lpNumberOfBytesWritten,
   LPOVERLAPPED lpOverlapper);int WINAPI MyWriteFile(HANDLE hFile,
   LPCVOID lpBuffer,
   DWORD nNumberOfBytesToWrite,
   LPDWORD lpNumberOfBytesWritten,
   LPOVERLAPPED lpOverlapper);int * Addr = (int *)WriteFile;
int * myAddr = (int *)MyWriteFile;
*/
// 线程函数
void ThreadProc(void *param);BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpReserved)
{
if(fdwReason == DLL_PROCESS_ATTACH)
{
// _beginthread(ThreadProc, 0, NULL);
}

return TRUE;
}void ThreadProc(void *Param)
{
hMod = GetModuleHandle(NULL); pDosHeader = (PIMAGE_DOS_HEADER)hMod;
pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE *)hMod + pDosHeader->e_lfanew);
pOptHeader = (PIMAGE_OPTIONAL_HEADER)&(pNTHeaders->OptionalHeader); pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)hMod + pOptHeader->DataDirectory[1].VirtualAddress);

while(pImportDescriptor->FirstThunk)
{
char* DllName = (char *)((BYTE *)hMod + pImportDescriptor->Name); pThunkData = (PIMAGE_THUNK_DATA)((BYTE *)hMod + pImportDescriptor->OriginalFirstThunk); int no = 1;
while(pThunkData->u1.Function)
{
PDWORD lpAddr = (DWORD *)((BYTE *)hMod + (DWORD)pImportDescriptor->FirstThunk) + (no-1); if((*lpAddr) == (int)addr1)
{
// 修改内存页属性
DWORD dwOld;
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(lpAddr, &mbi, sizeof(mbi));
VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE, &dwOld); WriteProcessMemory(GetCurrentProcess(), lpAddr, &myAddr, sizeof(DWORD), NULL); // 恢复内存页属性
VirtualProtect(lpAddr, sizeof(DWORD), dwOld, 0);
}
no++;
pThunkData++;
}
pImportDescriptor++;
}
}
/*
int WINAPI MyWriteFile(HANDLE hFile,
   LPCVOID lpBuffer,
   DWORD nNumberOfBytesToWrite,
   LPDWORD lpNumberOfBytesWritten,
   LPOVERLAPPED lpOverlapper)
{
MessageBox(NULL, "MyWriteFile", "mywritefile", 0);
return ((PFNWRITEFILE)Addr)(hFile,
lpBuffer,
nNumberOfBytesToWrite,
lpNumberOfBytesWritten,
lpOverlapper);
}
*/int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType)
{
    return       ((PFNMESSAGEBOX)addr1)(NULL, "gxter_test", "gxter_title", 0);
    //这个地方可以写出对这个API函数的处理代码
}

解决方案 »

  1.   

    demo.dll放在哪里了?要放在test.exe所在目录下,或者环境变量path所指定的路径下。
      

  2.   

    MessageBox有MessageBoxA和MessageBoxW两个版本是不是你都拦截了?
    看了你的代码非常的乱条理也不清楚
    你只拦截了MessageBoxA并没有对MessageBoxW进行拦截而且如果目标进程没有输入表的话你是拦截不到的建议你还是用Inline Hook
      

  3.   

    to 2楼:
    demo.dll放在test.exe所在目录下了,是相对test.exe的路径,这个我知道,而且程序在debug下运行正确了。
    谢谢。to 3楼:
    这个程序在debug下可以注入并替换test中的MessageBox的。在release下不行。该怎么解决?
    另外inline hook是什么?还有,如果有类似资料或者代码的话,麻烦给我发一下,[email protected]
    谢谢。
      

  4.   

    windows系统对debug与release申请的堆的管理“好象”不太相同。
      

  5.   

    http://blog.csdn.net/chenhui530/archive/2008/02/02/2079118.aspx
      

  6.   

    TO 5楼:谢谢,我研究一下。
    TO 6楼:应该一样吧。
    TO 7楼:你是指DLL用全路径吗?试过了,没有用。
      

  7.   

    问一下,你是否搞定了这个问题,我现在也碰到这样的问题,DEBUG下没问题,RELEASE下一注入就爆掉!