exe注入程序完整代码:
#include "stdafx.h" #include <tlhelp32.h> #include <stdio.h> int EnableDebugPriv(const char * name) { HANDLE hToken; TOKEN_PRIVILEGES tp; LUID luid; //打开进程令牌环 if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken) ) { printf("OpenProcessToken error "); return 1; } //获得进程本地唯一ID if(!LookupPrivilegeValue(NULL,name,&luid)) { printf("LookupPrivilege error! "); } 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! "); return 1; } return 0; } BOOL InjectDll(const char *DllFullPath, const DWORD dwRemoteProcessId) { HANDLE hRemoteProcess; //获得调试权限 if(EnableDebugPriv(SE_DEBUG_NAME)) { printf("add privilege error"); return FALSE; } //打开目标进程 if((hRemoteProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwRemoteProcessId))==NULL) { printf("OpenProcess error "); return FALSE; } char *pszLibFileRemote; //申请存放dll文件名的路径 pszLibFileRemote=(char *)VirtualAllocEx( hRemoteProcess, NULL, lstrlen(DllFullPath)+1, MEM_COMMIT, PAGE_READWRITE); if(pszLibFileRemote==NULL) { printf("VirtualAllocEx error "); return FALSE; } //把dll的完整路径写入到内存, if(WriteProcessMemory(hRemoteProcess, pszLibFileRemote,(void *)DllFullPath,lstrlen(DllFullPath)+1,NULL) == 0) { printf("WriteProcessMemory error "); return FALSE; } //得到LoadLibraryA函数地址 PTHREAD_START_ROUTINE pfnStartAddr=(PTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"LoadLibraryA"); if(pfnStartAddr == NULL) { printf("GetProcAddress error "); return FALSE; } HANDLE hRemoteThread; //启动远程线程 if( (hRemoteThread = CreateRemoteThread(hRemoteProcess,NULL,0, pfnStartAddr,pszLibFileRemote,0,NULL))==NULL) { printf("CreateRemoteThread error "); return FALSE; } return TRUE; } DWORD GetProcessID(char *ProcessName) { PROCESSENTRY32 pe32; pe32.dwSize=sizeof(pe32); //获得系统内所有进程快照 HANDLE hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if(hProcessSnap==INVALID_HANDLE_VALUE) { printf("CreateToolhelp32Snapshot error"); return 0; } //枚举列表中的第一个进程 BOOL bProcess=Process32First(hProcessSnap,&pe32); while(bProcess) { //比较找到的进程名和我们要查找的进程名,一样则返回进程id if(strcmp(strupr(pe32.szExeFile),strupr(ProcessName))==0) return pe32.th32ProcessID; //继续查找 bProcess=Process32Next(hProcessSnap,&pe32); } CloseHandle(hProcessSnap); return 0; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char SelfPath[256]; char SysPath[256]; GetCurrentDirectory(256,SelfPath); strcat(SelfPath,"\SimpleHook.dll"); GetSystemDirectory(SysPath,256); strcat(SysPath,"\SimpleHook.dll"); CopyFile(SelfPath,SysPath,FALSE); DWORD Pid=GetProcessID("taskmgr.exe"); InjectDll("SimpleHook.dll",Pid); return 0; }
DLL程序完整代码:
// SimpleHook.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" DWORD* lpAddr; PROC OldProc; BOOL __stdcall MyTerminateProcess(HANDLE hProcess,UINT uExitCode) { MessageBox(NULL,"没法结束进程了吧","API HOOK",0); return 0; } int ApiHook(char *DllName,//DLL文件名 PROC OldFunAddr,//要HOOK的函数地址 PROC NewFunAddr//我们够造的函数地址 ) { //得到函数进程模块基地址,也就是与我们上节课的 // LPVOID lpBase=MapViewOfFile(hMap,FILE_MAP_READ,0,0,0); 返回内存文件映射句柄 HMODULE lpBase = GetModuleHandle(NULL); IMAGE_DOS_HEADER *dosHeader; IMAGE_NT_HEADERS *ntHeader; IMAGE_IMPORT_BY_NAME *ImportName; //定位到DOS头 dosHeader=(IMAGE_DOS_HEADER*)lpBase; //定位到PE头 ntHeader=(IMAGE_NT_HEADERS32*)((BYTE*)lpBase+dosHeader->e_lfanew); //定位到导入表 IMAGE_IMPORT_DESCRIPTOR *pImportDesc=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)lpBase+ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); //循环遍历IMAGE_IMPORT_DESCRIPTOR机构数组 while(pImportDesc->FirstThunk) { //得到DLL文件名 char* pszDllName = (char*)((BYTE*)lpBase + pImportDesc->Name); //比较得到的DLL文件名是否和要HOOK函数所在的DLL相同 if(lstrcmpiA(pszDllName, DllName) == 0) { break; } pImportDesc++; } //定位到FirstThunk参数指向的IMAGE_THUNK_DATA,此时这个结构已经是函数入口点地址了 IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*) ((BYTE*)lpBase + pImportDesc->FirstThunk); //遍历这部分IAT表 while(pThunk->u1.Function) { lpAddr = (DWORD*)&(pThunk->u1.Function);//获得我们要HOOK 的api函数的入口点地址在IAT表中的内存地址 //比较函数地址是否相同 if(*lpAddr == (DWORD)OldFunAddr) { DWORD dwOldProtect; //修改内存包含属性 VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect); //API函数的入口点地址改成我们构造的函数的地址 WriteProcessMemory(GetCurrentProcess(),lpAddr, &NewFunAddr, sizeof(DWORD), NULL); } pThunk++; } return 0; } BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: //得到TerminateProcess函数地址 OldProc = (PROC)TerminateProcess; //定位,修改IAT表 ApiHook("kernel32.dll",OldProc,(PROC)MyTerminateProcess); break; case DLL_PROCESS_DETACH: //恢复IAT表中API函数的入口点地址 WriteProcessMemory(GetCurrentProcess(),lpAddr, &OldProc, sizeof(DWORD), NULL); break; } return TRUE; }