我有一段代码,就是写在程序中用来防止全局钩子的教程在这里:http://hi.baidu.com/walfer/blog/item/2118932f28ccc8391e308949.html在我机器里编译,调试,运行都没有问题,但是在部分同事的机器上,vc编译可以通过,但是debug的时候,就在GBlockHookDll函数的VirtualProtect这个地方崩溃了
不知道是什么原因,麻烦熟悉的达人告诉我一下。我和我同事的机器都是windows 2003 server Enterprise edition sp2,为啥结果不一样?代码如下: #include <Psapi.h>
#pragma comment(lib,"psapi.lib")
class GBlockHookDll
{
public:
GBlockHookDll()
{
MODULEINFO user32ModInfo = {0};
GetModuleInformation(GetCurrentProcess(),GetModuleHandle("user32.dll"),&user32ModInfo,sizeof(user32ModInfo));
m_dwUser32Low = (DWORD)user32ModInfo.lpBaseOfDll;
m_dwUser32Hi = (DWORD)user32ModInfo.lpBaseOfDll+user32ModInfo.SizeOfImage;
} void PatchLoadLibrary()
{
//LoadLibraryExW
//7C801AF1 6A 34                push        34h
//7C801AF3 68 88 E2 80 7C       push        7C80E288h LPVOID* pfnRaw = (LPVOID*)&rawLoadLibraryExW;
LPVOID fnNew = (LPVOID)newLoadLibraryExW; BYTE* fnRaw = (BYTE*)*pfnRaw; //1 save the first 7 bytes
const int nFirstBytes = 7;
BYTE* fnFake = (BYTE*)fakeLoadLibraryExW;
memcpy(fnFake,*pfnRaw,nFirstBytes);
fnFake[nFirstBytes] = 0xE9; //jmp to rawAddr+nFirstBytes
*(UINT32*)(fnFake + nFirstBytes+1) = (UINT32)fnRaw+nFirstBytes - (UINT32)(fnFake + nFirstBytes + 5); //2 modify the raw to jmp to fnNew
DWORD dwOldProtect = 0;
VirtualProtect(fnRaw,nFirstBytes,PAGE_READWRITE,&dwOldProtect); //Ð޸ĸôúÂë¶ÎµÄÊôÐÔΪ¿Éд
*fnRaw = 0xE9;
*(UINT32*)(fnRaw+1) = (UINT32)fnNew - (UINT32)(fnRaw + 5);
VirtualProtect(fnRaw,nFirstBytes,dwOldProtect,0); //3 change the rawPointer
*pfnRaw = fnFake; }
private:
static HMODULE WINAPI newLoadLibraryExW(LPCWSTR lpLibFileName,HANDLE hFile,DWORD dwFlags)
{
//get the return address
DWORD dwCaller;
__asm push dword ptr [ebp+4]
__asm pop  dword ptr [dwCaller] if(dwCaller > m_dwUser32Low && dwCaller < m_dwUser32Hi)
{
#ifdef _DEBUG
UINT uLenWide = lstrlenW(lpLibFileName);
char* pNewChar = new char[uLenWide + 1];
memset(pNewChar,0,uLenWide+1);
WideCharToMultiByte(CP_ACP,0,lpLibFileName,-1,pNewChar,uLenWide,NULL,NULL);
TRACE2(".......................LoadLibrary:return addr 0x%x,%s ",dwCaller,pNewChar);
TRACE("Blocked.......................\n");
delete []pNewChar;
#endif
return 0;
} return rawLoadLibraryExW(lpLibFileName,hFile,dwFlags);
}private:
static DWORD m_dwUser32Low; //user32.dll µÄ¼ÓÔØ»ùÖ·
static DWORD m_dwUser32Hi; //user32.dll µÄ¼ÓÔØ»ùÖ·£«ImageSize
static BYTE  fakeLoadLibraryExW[12]; //save first bytes of the raw function,and jmp back to that function //±£´æLoadLibraryExWµÄÖ¸Õ룬ȻºóÐÞ¸ÄΪfakeLoadLibraryExW
static HMODULE (WINAPI *rawLoadLibraryExW)( LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags );
};DWORD GBlockHookDll::m_dwUser32Low = 0;
DWORD GBlockHookDll::m_dwUser32Hi  = 0;
BYTE GBlockHookDll::fakeLoadLibraryExW[12] = {0};
HMODULE (WINAPI *GBlockHookDll::rawLoadLibraryExW)(LPCWSTR lpLibFileName,HANDLE hFile,DWORD dwFlags) = LoadLibraryExW;

解决方案 »

  1.   

    具体错误信息是什么?
    把rawLoadLibraryExW改成用GetProcAddress获取地址试试。
      

  2.   


    就是debug到virtualproect的时候,程序崩溃,提示该内存不能为written...,可是在我机器上运行,一点问题都没有,奇怪希望得到大侠的指点您说的改成GetProcAddress我不太会,这段代码我都是复制粘贴过来的,对这块本身也不太理解,希望得到你的帮助
      

  3.   


    //这里修改为
    VirtualProtect(fnRaw,nFirstBytes,PAGE_EXECUTE_READWRITE,&dwOldProtect); //Ð޸ĸôúÂë¶ÎµÄÊôÐÔΪ¿Éд 
    *fnRaw = 0xE9; 
    *(UINT32*)(fnRaw+1) = (UINT32)fnNew - (UINT32)(fnRaw + 5); 
    //去掉这句
    //VirtualProtect(fnRaw,nFirstBytes,dwOldProtect,0); //我是这样用的
    DWORD oldp;
    VirtualProtect((void*)mappStruct,WRITE_PAGE_SIZE,PAGE_EXECUTE_READWRITE,&oldp);
    //修改好了。就不要恢复了。
    //保留原来的execute标记
      

  4.   

    这样我试了一下,调试这句通过了,但是在接下来的调用对话框的时候,domodal的时候还是出错,但是在我机器上依然是没有问题GBlockDll.PatchLoadLibrary();

    CBlockHookDllDlg dlg;
    m_pMainWnd = &dlg;
    int nResponse = dlg.DoModal();楼上的大侠,我可否把代码发给你,您帮我调试一下?多谢了,很简单的一段代码