小弟我写了一个钩子的类,用bc6编译和调用的时候遇到点有关问题,用bc2010编译变成了局部钩子,大家帮忙看下,多谢
我写了一个钩子的类,用bc6编译和调用的时候遇到点问题,用bc2010编译变成了局部钩子,大家帮忙看下,谢谢!
这是在头文件声明的THOOK类
下面是动态链接库程序
这是在头文件声明的THOOK类
- C/C++ code
class THOOK { FARPROC fp; FARPROC newfp; HMODULE hModule; BYTE OldCode[5]; BYTE NewCode[5]; DWORD OldFnID; DWORD NewFnID; public: int flag; bool bHook; THOOK *next; THOOK(); void HookOn(); void HookOff(); bool init(char *dllname,char *prname,FARPROC MyP); ~THOOK(); }; THOOK::THOOK() { flag=-1; bHook=false; for(int i=0;i<5;i++) { OldCode[i]=0xe9; NewCode[i]=0; } fp=NULL; newfp=NULL; hModule=NULL; OldFnID=0; NewFnID=0; next=NULL; } THOOK::~THOOK() { flag=-1; if(bHook) HookOff(); delete(OldCode); delete(NewCode); fp=NULL; newfp=NULL; hModule=NULL; //用BC6编译时如果调用出错在这里或是构造函数里任意地方添加空行再编译,调用就会成功 //这也就是我的第一个问题,用BC2010编译就不会出现调用错误; OldFnID=0; NewFnID=0; if(next) { delete(next); next=NULL; } } bool THOOK::init(char *dllname,char *prname,FARPROC MyP) { hModule=GetModuleHandle(dllname); fp=GetProcAddress(hModule,prname); if(fp==NULL) return false; Move(fp,OldCode,5); newfp=MyP; NewCode[0]=0Xe9; DWORD *addr; addr=(DWORD *)(NewCode+1); *addr=DWORD(newfp)-DWORD(fp)-5; NewFnID=GetCurrentProcessId(); OldFnID=NewFnID; HookOn(); return true; } void THOOK::HookOn() { OldFnID=NewFnID; HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,0,OldFnID); VirtualProtectEx(hProc,fp,5,PAGE_READWRITE,&OldFnID); WriteProcessMemory(hProc,fp,NewCode,5,0); VirtualProtectEx(hProc,fp,5,OldFnID,&OldFnID); bHook=true; } void THOOK::HookOff() { OldFnID=NewFnID; HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,0,OldFnID); VirtualProtectEx(hProc,fp,5,PAGE_READWRITE,&OldFnID); WriteProcessMemory(hProc,fp,OldCode,5,0); VirtualProtectEx(hProc,fp,5,OldFnID,&OldFnID); bHook=false; }
下面是动态链接库程序
- C/C++ code
//--------------------------------------- #include <vcl.h> #include <stdio.h> #include <windows.h> #include <winsock2.h> #include "THOOK.h" #pragma hdrstop #pragma argsused HHOOK g_hHook; HINSTANCE g_hinstDll; THOOK *THookHandle; bool bHooked=false; //--------------------------添加函数需修改部分一------------------------------------ const int countP=4; int WINAPI MyRecv(SOCKET s, char FAR* buf, int len, int flags); //---1 int WINAPI MySend(SOCKET s, char FAR* buf, int len, int flags); //---2 int WINAPI MyConnect( SOCKET s, const struct sockaddr FAR* name, int namelen); //---3 int WINAPI MyBind( SOCKET s, const struct sockaddr FAR* name, int namelen); //---4 //-------------------------------------------- LRESULT WINAPI HookProc(int nCode,WPARAM wParam,LPARAM lParam) { return (CallNextHookEx(g_hHook,nCode,wParam,lParam)); } extern "C" bool _declspec(dllexport) _stdcall InstallHook(HWND hWnd) { if(!g_hHook) g_hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)HookProc,g_hinstDll,0); if(!g_hHook) return false; THOOK *p; p=THookHandle; while(p) { if(!p->bHook) { p->HookOn(); } p=p->next; } bHooked=true; return true; } extern "C" bool _declspec(dllexport) _stdcall UninstallHook() { bool result=false; if(g_hHook) { result=UnhookWindowsHookEx(g_hHook); if(bHooked) { THOOK *p; p=THookHandle; while(p) { if(p->bHook) p->HookOff(); p=p->next; } bHooked=false; } SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,0); } g_hHook=NULL; return result; } void WINAPI checksum(char FAR* buf ) { int size=20; unsigned long cksum=0; while(size >1) { cksum+=*buf++; size -=sizeof(USHORT); } if(size ) cksum += *(UCHAR*)buf; cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); cksum=~cksum; buf[10]=char(cksum&0x00ff); buf[11]=char(cksum>>8); } //--------------------------添加函数需修改部分二------------------------------------ int WINAPI MyRecv(SOCKET s, char FAR* buf, int len, int flags) { int res; THOOK *p; p=THookHandle; while(p&&p->flag!=1) { p=p->next; } p->HookOff(); res=recv(s,buf,len,flags); p->HookOn(); return res; } int WINAPI MySend(SOCKET s, char FAR* buf, int len, int flags) { int res; THOOK *p; p=THookHandle; while(p&&p->flag!=2) { p=p->next; } p->HookOff(); res=send(s,buf,len,flags); p->HookOn(); return res; } int WINAPI MyConnect( SOCKET s, const struct sockaddr FAR* name,int namelen) { int res; THOOK *p; p=THookHandle; while(p&&p->flag!=3) { p=p->next; } SOCKADDR_IN Newsin; memcpy(&Newsin,name,namelen); Newsin.sin_family=AF_INET; sendiphdr.destIP=0x0701a8c0; Newsin.sin_port=htons(10026); //for(int i=0;i<8;i++) Newsin.sin_zero[i]=0;这里如果用0填充,端口就会变成10791,ip修改没问题 p->HookOff(); res=connect(s,(LPSOCKADDR)&Newsin, namelen); p->HookOn(); if(res<0) { int err=WSAGetLastError(); String rlt=IntToStr(err); MessageBoxA(NULL,rlt.c_str(),"ERRO",MB_OK); } return res; } int WINAPI MyBind( SOCKET s, const struct sockaddr FAR* name, int namelen) { int res; THOOK *p; p=THookHandle; while(p&&p->flag!=4) { p=p->next; } p->HookOff(); res=MyBind(s,name,namelen); p->HookOn(); MessageBoxA(NULL,"挂钩bind成功!","OK",MB_OK); return res; } //------------------------------------------- #pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { g_hinstDll=hinst; THOOK *p; switch(reason) { case DLL_PROCESS_ATTACH: { bool hooked[countP]; p=THookHandle; int countnow=0; while(!p&&countnow<countP) { countnow++; if(!THookHandle) { THookHandle=new(THOOK); p=THookHandle; } else { p=THookHandle; while(p->next) { p=p->next; } p->next=new(THOOK); p=p->next; } switch(countnow) { //--------------------------添加函数需修改部分三------------------------------------ case 1: hooked[countnow-1]=p->init("ws2_32.dll","recv",(FARPROC )MyRecv); break; case 2: hooked[countnow-1]=p->init("ws2_32.dll","send",(FARPROC )MySend); break; case 3: hooked[countnow-1]=p->init("ws2_32.dll","connect",(FARPROC )MyConnect); break; case 4: hooked[countnow-1]=p->init("ws2_32.dll","bind",(FARPROC )MyBind); break; //----------------------------------------------- } if(hooked[countnow-1]) { p->flag=countnow; } if(p->flag<countP) p=p->next; //MessageBoxA(NULL,"成功!","OK",MB_OK); } for(int i=0;i<countP;i++) { hooked[0]=hooked[0]&&hooked[i]; hooked[countP-1]=hooked[countP-1]|hooked[i]; } if(!hooked[countP-1]) { MessageBoxA(NULL,"初始化函数错误!","ERROR",MB_OK); return (false); } if(!hooked[0]) { MessageBoxA(NULL,"部分函数无法初始化!","ERROR",MB_OK); return (false); } } break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: if(bHooked&&THookHandle) { delete(THookHandle); } break; } return true; } //---------------------------------------