ring3下的API HOOK实现起来要简单的多,但是效果可能不是很好,特别是在多个进程如果同时访问相应的DLL时,自己在练习的时候,做了这个监控程序。毕竟是菜鸟所作,还请大牛些多多包涵。代码直接封装到DLL中了,话不多说,上代码:
代码:
#include <windows.h> #include <Tlhelp32.h> #include <stdio.h> #define DLLEXPORTS /* extern "C" */ __declspec(dllexport) //========================================================================================== HINSTANCE glhInstance=NULL; //DLL实例句柄 BYTE g_OldRegCreateKeyExCode[5] = {0}; //存放函数地址 BYTE g_NewRegCreateKeyExCode[5] = {0}; //存放函数地址 FARPROC FuncAddr = NULL; //函数地址 DWORD PID=0; //进程PID int count=0; HANDLE hProcess; //========================================================================================== typedef struct tagReg_Info //存放 RegCreateKeyEx() 的信息 { HKEY hKey; // handle to an open key LPCTSTR lpSubKey; // address of subkey name DWORD Reserved; // reserved LPTSTR lpClass; // address of class string DWORD dwOptions; // special options flag REGSAM samDesired; // desired security access LPSECURITY_ATTRIBUTES lpSecurityAttributes; // address of key security structure PHKEY phkResult; // address of buffer for opened handle LPDWORD lpdwDisposition; // address of disposition value buffer }Reg_Info; Reg_Info RegInfo; //========================================================================================== #pragma data_seg("mydata") HHOOK hook=NULL; //安装的鼠标勾子句柄 CRITICAL_SECTION cs={0}; #pragma data_seg() #pragma comment(linker,"/SECTION:mydata,RWS") //========================================================================================== bool Inject(); DLLEXPORTS bool SetHook_Inject(); DLLEXPORTS bool UnHook(); bool Init(); LONG MyRegCreateKeyEx( HKEY hKey, // handle to an open key LPCTSTR lpSubKey, // address of subkey name DWORD Reserved, // reserved LPTSTR lpClass, // address of class string DWORD dwOptions, // special options flag REGSAM samDesired, // desired security access LPSECURITY_ATTRIBUTES lpSecurityAttributes, // address of key security structure PHKEY phkResult, // address of buffer for opened handle LPDWORD lpdwDisposition // address of disposition value buffer ); LONG HookOff(); LRESULT CALLBACK CallWndRetProc( int nCode, // hook code WPARAM wParam, // event-specific information LPARAM lParam // event-specific information ); //========================================================================================== //========================================================================================== BOOL WINAPI DllMain( HINSTANCE hinstDLL, // handle to DLL module DWORD fdwReason, // reason for calling function LPVOID lpvReserved // reserved ) { glhInstance=hinstDLL; return 1; } //========================================================================================== bool Inject() { Init(); //hProcess = OpenProcess(PROCESS_ALL_ACCESS,0, PID); if(hProcess == NULL) { return false; } EnterCriticalSection(&cs); DWORD PROTECT=0; VirtualProtectEx(hProcess, FuncAddr, 5, PAGE_READWRITE, &PROTECT); //申请CreateWindowExA地址处的写权限, WriteProcessMemory(hProcess, FuncAddr, g_NewRegCreateKeyExCode, 5, NULL); //然后写入跳转代码,然后恢复权限 VirtualProtectEx(hProcess, FuncAddr, 5, PROTECT, &PROTECT); LeaveCriticalSection(&cs); CloseHandle(hProcess); return true; } //========================================================================================== DLLEXPORTS bool SetHook_Inject() { hook=SetWindowsHookEx(WH_CALLWNDPROCRET,CallWndRetProc,glhInstance,0); if(NULL==hook) { ::MessageBox(NULL,"SetWindowsHookEx!","Error!",MB_ICONERROR); return false; } return true; } //========================================================================================== //========================================================================================== DLLEXPORTS bool UnHook() { bool ret=false; if(hook) { ret=UnhookWindowsHookEx(hook); if(!ret) { ::MessageBox(NULL,"UnhookWindowsHookEx!","Error!",MB_ICONERROR); return false; } return true; } return false; } LRESULT CALLBACK CallWndRetProc(int nCode, WPARAM wParam,LPARAM lParam) { if(nCode==HC_ACTION) // HOOK的目的只在于映射进DLL,这里后面的处理也可以, { PID=GetCurrentProcessId(); // 但是这里只做API注入,就不用了 hProcess = OpenProcess(PROCESS_ALL_ACCESS,0, PID); Init(); Inject(); } return CallNextHookEx(hook,nCode,wParam,lParam); } //================================================================================== //================================================================================== LONG MyRegCreateKeyEx( HKEY hKey, // handle to an open key LPCTSTR lpSubKey, // address of subkey name DWORD Reserved, // reserved LPTSTR lpClass, // address of class string DWORD dwOptions, // special options flag REGSAM samDesired, // desired security access LPSECURITY_ATTRIBUTES lpSecurityAttributes, // address of key security structure PHKEY phkResult, // address of buffer for opened handle LPDWORD lpdwDisposition // address of disposition value buffer ) { char str[1000]={0}; if(HKEY_LOCAL_MACHINE==hKey) { sprintf(str,"注册表位置: HKEY_LOCAL_MACHINE\\%s \nRegedit is being Created !",lpSubKey); } if(HKEY_USERS==hKey) { sprintf(str,"注册表位置: HKEY_USERS\\%s \nRegedit is being Created !",lpSubKey); } if(HKEY_CLASSES_ROOT==hKey) { sprintf(str,"注册表位置: HKEY_CLASSES_ROOT\\%s \nRegedit is being Created !",lpSubKey); } if(HKEY_CURRENT_CONFIG==hKey) { sprintf(str,"注册表位置: HKEY_CURRENT_CONFIG\\%s \nRegedit is being Created !",lpSubKey); } /**/else // if(HKEY_CURRENT_USER==hKey) ((HKEY) (ULONG_PTR)((LONG)0x80000001)) { sprintf(str,"注册表位置: HKEY_CURRENT_USER\\%s \nRegedit is being Created !\nPID: %ld",lpSubKey,PID); } if(count<1) { ::MessageBox(NULL,str,"warning",MB_ICONWARNING); } count++; /* HANDLE hFile=CreateFile("C:\\RegLog.txt",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile) { ::MessageBox(NULL,"CreateFile Error","warning",MB_ICONWARNING); } if(SetFilePointer(hFile,0,NULL,FILE_END)==0xFFFFFFFF) { ::MessageBox(NULL,"SetFilePointer Error","warning",MB_ICONWARNING); } OVERLAPPED olp; olp.hEvent=NULL; olp.OffsetHigh=0; if(!WriteFileEx(hFile,str,strlen(str)+1,&olp,NULL)) { ::MessageBox(NULL,"SetFilePointer Error","warning",MB_ICONWARNING); } */ ZeroMemory(&RegInfo,sizeof(RegInfo)); RegInfo.dwOptions=dwOptions; // 保存传入的信息: RegInfo.hKey=hKey; RegInfo.lpClass=lpClass; RegInfo.lpdwDisposition=lpdwDisposition; RegInfo.lpSecurityAttributes=lpSecurityAttributes; RegInfo.lpSubKey=lpSubKey; RegInfo.phkResult=phkResult; RegInfo.Reserved=Reserved; RegInfo.samDesired=samDesired; HookOff(); Sleep(200); LONG ret=RegCreateKeyEx(RegInfo.hKey, RegInfo.lpSubKey, RegInfo.Reserved, RegInfo.lpClass, RegInfo.dwOptions, RegInfo.samDesired, RegInfo.lpSecurityAttributes, RegInfo.phkResult, RegInfo.lpdwDisposition); Sleep(200); Inject(); return ret; } //================================================================================== LONG HookOff() { //hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, PID); if(hProcess == NULL) { return (LONG)1; } //写入原CreateWindowExA的5个字节代码 EnterCriticalSection(&cs); DWORD PROTECT=0; VirtualProtectEx(hProcess, FuncAddr, 5, PAGE_READWRITE, &PROTECT); WriteProcessMemory(hProcess, FuncAddr, g_OldRegCreateKeyExCode, 5, NULL); VirtualProtectEx(hProcess, FuncAddr, 5, PROTECT, &PROTECT); LeaveCriticalSection(&cs); return (LONG)1; } bool Init() { //FuncAddr = GetProcAddress(LoadLibrary("Advapi32.dll"),"RegCreateKeyExW"); //FuncAddr = GetProcAddress(LoadLibrary("Advapi32.dll"),"RegCreateKeyExA"); FuncAddr = GetProcAddress(LoadLibrary("Advapi32.dll"),"RegCreateKey"); if(NULL==FuncAddr) return false; InitializeCriticalSection(&cs); EnterCriticalSection(&cs); _asm { lea edi, g_OldRegCreateKeyExCode mov esi, FuncAddr cld movsd //将CreateWindowExA地址起始的4个字节(dword)写入g_OldCreateWindowExACode movsb //将CreateWindowExA+4地址起始处的1个字节(byte)写入g_OldCreateWindowExACode+4 } //jmp xxxxxxxx的机器码为e9xxxxxxxx,其中e9后的xxxxxxxx为相对跳转偏移,共5个字节 g_NewRegCreateKeyExCode[0] = 0xe9; //g_NewRegCreateKeyExCode[0] = 0xe8; //不能改成 call 指令----------0xE8 _asm { lea eax, MyRegCreateKeyEx // mov ebx, FuncAddr sub eax, ebx sub eax, 5 //获得相对跳转偏移 //偏移地址 = 我们函数的地址 - 原API函数的地址 - 5 mov dword ptr [g_NewRegCreateKeyExCode + 1], eax } LeaveCriticalSection(&cs); }