这几天在做的一个项目需要用到进程状态的监控,结果在网上搜索过程中,发现了一篇不错的文章,特意转载过来,虽然还没完全弄明白,但其中的思路却很有启发,根据这个思路,可以处理拦截其他windows API的功能,如,把createFile改为createProccess,就可以拦截创建进程的API了。 原文如下: // 附录:一个拦截CreateFile函数的简单实现 // #include <stdio.h> #include <windows.h> #include <Psapi.h> #pragma comment(lib, "psapi.lib") #pragma comment(lib, "ws2_32.lib") typedef struct _RemoteParam { DWORD dwCreateFile; DWORD dwMessageBox; DWORD dwGetCurrentProcess; DWORD dwWriteProcessMemory; unsigned char szOldCode[10]; DWORD FunAddr; } RemoteParam, * PRemoteParam; typedef HANDLE (__stdcall * PFN_CREATEFILE)(LPCTSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE); typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD); typedef BOOL (__stdcall * PFN_WRITEPROCESSMEMORY)(HANDLE,LPVOID,LPCVOID,SIZE_T,SIZE_T*); typedef HANDLE (__stdcall * PFN_GETCURRENTPROCESS)(void); #define PROCESSNUM 128 #define MYMESSAGEBOX "MessageBoxW" #define MYCREATEFILE "CreateFileW" void HookCreateFile(LPVOID lParam) { RemoteParam* pRP = (RemoteParam*)lParam; DWORD NextIpAddr = 0; DWORD dwParamaAddr = 0; HANDLE RetFpHdl = INVALID_HANDLE_VALUE; LPCTSTR lpFileName; DWORD dwDesiredAccess; DWORD dwShareMode; LPSECURITY_ATTRIBUTES lpSecurityAttributes; DWORD dwCreationDisposition; DWORD dwFlagsAndAttributes; HANDLE hTemplateFile; PFN_CREATEFILE pfnCreatefile = (PFN_CREATEFILE)pRP->dwCreateFile; __asm { MOV EAX,[EBP+8] MOV [dwParamaAddr], EAX MOV EAX,[EBP+12] MOV [NextIpAddr], EAX MOV EAX,[EBP+16] MOV [lpFileName], EAX MOV EAX,[EBP+20] MOV [dwDesiredAccess],EAX MOV EAX,[EBP+24] MOV [dwShareMode],EAX MOV EAX,[EBP+28] MOV [lpSecurityAttributes],EAX MOV EAX,[EBP+32] MOV [dwCreationDisposition],EAX MOV EAX,[EBP+36] MOV [dwFlagsAndAttributes],EAX MOV EAX,[EBP+40] MOV [hTemplateFile],EAX } PFN_MESSAGEBOX pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox; int allowFlag = pfnMessageBox(NULL, lpFileName, NULL, MB_ICONINFORMATION | MB_YESNO); if(allowFlag == IDYES) { unsigned char szNewCode[10]; int PramaAddr = (int)dwParamaAddr; szNewCode[4] = PramaAddr>>24; szNewCode[3] = (PramaAddr<<8)>>24; szNewCode[2] = (PramaAddr<<16)>>24; szNewCode[1] = (PramaAddr<<24)>>24; szNewCode[0] = 0x68; int funaddr = (int)pRP->FunAddr - (int)pfnCreatefile - 10 ; szNewCode[9] = funaddr>>24; szNewCode[8] = (funaddr<<8)>>24; szNewCode[7] = (funaddr<<16)>>24; szNewCode[6] = (funaddr<<24)>>24; szNewCode[5] = 0xE8; PFN_GETCURRENTPROCESS pfnGetCurrentProcess = (PFN_GETCURRENTPROCESS)pRP->dwGetCurrentProcess; PFN_WRITEPROCESSMEMORY pfnWriteProcessMemory = (PFN_WRITEPROCESSMEMORY)pRP->dwWriteProcessMemory; pfnWriteProcessMemory(pfnGetCurrentProcess(), (LPVOID)pfnCreatefile, (LPCVOID)pRP->szOldCode, 10, NULL); RetFpHdl = pfnCreatefile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); pfnWriteProcessMemory(pfnGetCurrentProcess(), (LPVOID)pfnCreatefile, (LPCVOID)szNewCode, 10, NULL); } __asm {POP EDI POP ESI POP EBX MOV EDX, [NextIpAddr] MOV EAX, [RetFpHdl] MOV ESP, EBP POP EBP ADD ESP, 28H PUSH EDX RET } } BOOL AdjustProcessPrivileges(LPCSTR szPrivilegesName) { HANDLE hToken; TOKEN_PRIVILEGES tkp; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken)) { return FALSE; } if(!LookupPrivilegeValue(NULL,szPrivilegesName, &tkp.Privileges[0].Luid)) { CloseHandle(hToken); return FALSE; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL)) { CloseHandle(hToken); return FALSE; } CloseHandle(hToken); return TRUE; } void printProcessNameByPid( DWORD ProcessId ) { HANDLE pHd; HMODULE pHmod; char ProcessName[MAX_PATH] = "unknown"; DWORD cbNeeded; pHd = OpenProcess( PROCESS_QUERY_INFORMATION |PROCESS_VM_READ, FALSE, ProcessId ); if(pHd == NULL) return; if(!EnumProcessModules( pHd, &pHmod, sizeof(pHmod), &cbNeeded)) return; if(!GetModuleFileNameEx( pHd, pHmod, ProcessName, MAX_PATH)) return; printf( "%d/t%s/n", ProcessId, ProcessName); CloseHandle( pHd ); return; } int main(void) { if(!AdjustProcessPrivileges(SE_DEBUG_NAME)) { printf("AdjustProcessPrivileges Error!/n"); return -1; } DWORD Pids[PROCESSNUM]; DWORD dwProcessNum = 0; if(!EnumProcesses(Pids, sizeof(Pids), &dwProcessNum)) { printf("EnumProcess Error!/n"); return -1; } for( DWORD num = 0; num < (dwProcessNum / sizeof(DWORD)); num++) printProcessNameByPid(Pids[num]); printf("/nAll %d processes running. /n", dwProcessNum / sizeof(DWORD)); DWORD dwPid = 0; printf("/n请输入要拦截的进程id:"); scanf("%d", &dwPid); HANDLE hTargetProcess = OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ, FALSE, dwPid); if(hTargetProcess == NULL) { printf("OpenProcess Error!/n"); return -1; } DWORD dwFunAddr = (DWORD)VirtualAllocEx(hTargetProcess, NULL, 8192, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if((LPVOID)dwFunAddr == NULL) { printf("申请线程内存失败!/n"); CloseHandle(hTargetProcess); return -1; } DWORD dwPramaAddr = (DWORD)VirtualAllocEx(hTargetProcess, NULL, sizeof(RemoteParam), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if((LPVOID)dwPramaAddr == NULL) { printf("申请参数内存失败!/n"); CloseHandle(hTargetProcess); return -1; } printf("/n线程内存地址:%.8x/n" "参数内存地址:%.8x/n", dwFunAddr, dwPramaAddr); RemoteParam RParam; ZeroMemory(&RParam, sizeof(RParam)); HMODULE hKernel32 = LoadLibrary("kernel32.dll"); HMODULE hUser32 = LoadLibrary("user32.dll"); RParam.dwCreateFile = (DWORD)GetProcAddress(hKernel32, MYCREATEFILE); RParam.dwGetCurrentProcess = (DWORD)GetProcAddress(hKernel32, "GetCurrentProcess"); RParam.dwWriteProcessMemory = (DWORD)GetProcAddress(hKernel32, "WriteProcessMemory"); RParam.dwMessageBox = (DWORD)GetProcAddress(hUser32, MYMESSAGEBOX); unsigned char oldcode[10]; unsigned char newcode[10]; int praadd = (int)dwPramaAddr; int threadadd = (int)dwFunAddr; newcode[4] = praadd>>24; newcode[3] = (praadd<<8)>>24; newcode[2] = (praadd<<16)>>24; newcode[1] = (praadd<<24)>>24; newcode[0] = 0x68; int offsetaddr = threadadd - (int)RParam.dwCreateFile - 10 ; newcode[9] = offsetaddr>>24; newcode[8] = (offsetaddr<<8)>>24; newcode[7] = (offsetaddr<<16)>>24; newcode[6] = (offsetaddr<<24)>>24; newcode[5] = 0xE8; printf("NewCode:"); for(int j = 0; j < 10; j++) printf("0x%.2x ",newcode[j]); printf("/n/n"); if(!ReadProcessMemory(GetCurrentProcess(), (LPCVOID)RParam.dwCreateFile, oldcode, 10, &dwPid)) { printf("read error"); CloseHandle(hTargetProcess); FreeLibrary(hKernel32); return -1; } strcat((char*)RParam.szOldCode, (char*)oldcode); RParam.FunAddr = dwFunAddr; printf( "RParam.dwCreateFile:%.8x/n" "RParam.dwMessageBox:%.8x/n" "RParam.dwGetCurrentProcess:%.8x/n" "RParam.dwWriteProcessMemory:%.8x/n" "RParam.FunAddr:%.8x/n", RParam.dwCreateFile, RParam.dwMessageBox, RParam.dwGetCurrentProcess, RParam.dwWriteProcessMemory, RParam.FunAddr); printf("RParam.szOldCode:"); for( int i = 0; i< 10; i++) printf("0x%.2x ", RParam.szOldCode[i]); printf("/n"); if(!WriteProcessMemory(hTargetProcess, (LPVOID)dwFunAddr, (LPVOID)&HookCreateFile, 8192, &dwPid)) { printf("WriteRemoteProcessesMemory Error!/n"); CloseHandle(hTargetProcess); FreeLibrary(hKernel32); return -1; } if(!WriteProcessMemory(hTargetProcess, (LPVOID)dwPramaAddr, (LPVOID)&RParam, sizeof(RemoteParam), &dwPid)) { printf("WriteRemoteProcessesMemory Error!/n"); CloseHandle(hTargetProcess); FreeLibrary(hKernel32); return -1; } if(!WriteProcessMemory(hTargetProcess, (LPVOID)RParam.dwCreateFile, (LPVOID)newcode, 10, &dwPid)) { printf("WriteRemoteProcessesMemory Error!/n"); CloseHandle(hTargetProcess); FreeLibrary(hKernel32); return -1; } printf("/nThat's all, good luck :)/n"); CloseHandle(hTargetProcess); FreeLibrary(hKernel32); return 0; }