进程监控–项目练习
项目要求:
特别说明
注意:此次项目在Win XP下编写,Win10上没有尝试。还有,监控程序(Hacker.exe)需拥有重定位表,就是DEBUG版
- 使用内存写入的方式,实现模块隐藏.
- IAT表中有的API使用IAT Hook实现 不在IAT表的使用Inline Hook实现
- 将监控的API参数写入到文件中
- 进程间通信方式自己选择,有创新最好
- 所有的HOOK能够正常卸载,不能导致进程意外结束
我采用的是内存写入的方式注入(将当前进程代码重定位写入远程进程,在远程进程中修复IAT表),Hook只用了IAT Hook,可以再加上Inline Hook,进程通信采用的是共享内存。
结果图:
远程监控有两种状态,开启监控和关闭监控
当我开启监控后,Dialog再调用函数时就会在C盘创建一个Export.txt的文档,里面会存储各函数的参数。
当我关闭监控时,Dialog调用各类函数就不会将参数写到文件中。
同时,我也可以远程调用Dialog的各类函数。
这项目其实就是将前面的知识进行了汇总利用,而这项目难点也在于进程通信。
我采用的通信方式–共享内存
- 在自己进程(Hacker)创建共享内存
- 注入的代码里面同样创建共享内存
- 利用远程线程将注入的代码执行
- 设计“关闭监控”、“开启监控”、“远程调用”等功能思路
- 我将共享内存的第一块称为“监控位”,当每次点按钮时就将“监控位”设置为对应的值
- 将2-4块设置为三个“开启监控”的“标志位”。当标志位为1,则执行"开启监控",即安装Hook。当标志位为0,就卸载Hook
- 将5-7块设置为三个”远程调用“的”标志位“。也可以不用,因为”远程调用“没有两种状态
- 每次执行完功能,都把“监控位”设置为0,保证功能只执行一次(因为我远程线程函数里面会把功能写在一个while循环里面)
- 这样,我通过本进程对共享内存写入就可以监控、调用远程进程的函数了
代码如下
Hacker.cpp主程序—本模块:
// Hacker.cpp : Defines the entry point for the application.
//
#include "tools.h"
using std::cout;
using std::endl;
extern DWORD ExitCode;
HWND g_hDlg;
HINSTANCE g_hInstance;
HANDLE g_hFileMap;
LPVOID lpHacker;
BOOL Inject;
//用于退出线程
HANDLE g_hProcess;
DWORD g_ImageBase;
LPVOID g_pszProBuffer;
//线程函数
DWORD WINAPI MainThread(LPVOID lparam);
DWORD WINAPI ThreadInject(LPVOID lparam);
//对话框回调函数
BOOL CALLBACK DialogFunc(HWND hDlg,UINT uMessage,WPARAM wParam,LPARAM lParam)
{
switch(uMessage)
{
case WM_INITDIALOG:
{
g_hDlg = hDlg;
HANDLE hThread1 = NULL;
hThread1 = CreateThread(NULL,0,MainThread,(LPVOID)1,0,NULL);
CloseHandle(hThread1);
return TRUE;
}
case WM_CLOSE:
{
EndDialog(hDlg,0);
return TRUE;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_BUTTON1:
{
HANDLE hThread2 = NULL;
hThread2 = CreateThread(NULL,0,MainThread,(LPVOID)2,0,NULL);
CloseHandle(hThread2);
return TRUE;
}
case IDOK:
{
HANDLE hThread3 = NULL;
hThread3 = CreateThread(NULL,0,MainThread,(LPVOID)3,0,NULL);
CloseHandle(hThread3);
return TRUE;
}
case IDOK3:
{
HANDLE hThread4 = NULL;
hThread4 = CreateThread(NULL,0,MainThread,(LPVOID)4,0,NULL);
CloseHandle(hThread4);
return TRUE;
}
case IDOK5:
{
HANDLE hThread5 = NULL;
hThread5 = CreateThread(NULL,0,MainThread,(LPVOID)5,0,NULL);
CloseHandle(hThread5);
return TRUE;
}
case IDOK2:
{
HANDLE hThread1001 = NULL;
hThread1001 = CreateThread(NULL,0,MainThread,(LPVOID)1001,0,NULL);
CloseHandle(hThread1001);
return TRUE;
}
case IDOK4:
{
HANDLE hThread1002 = NULL;
hThread1002 = CreateThread(NULL,0,MainThread,(LPVOID)1002,0,NULL);
CloseHandle(hThread1002);
return TRUE;
}
case IDOK6:
{
HANDLE hThread1003 = NULL;
hThread1003 = CreateThread(NULL,0,MainThread,(LPVOID)1003,0,NULL);
CloseHandle(hThread1003);
return TRUE;
}
case IDC_BUTTON2:
{
HANDLE hThread1003 = NULL;
hThread1003 = CreateThread(NULL,0,MainThread,(LPVOID)1004,0,NULL);
CloseHandle(hThread1003);
return TRUE;
}
case IDC_BUTTON3:
{
if(!Inject)
{
MessageBox(NULL,"没有注入","没有注入",0);
return TRUE;
}
DWORD CodeAddr = (DWORD)&ExitCode - (DWORD)g_ImageBase + (DWORD)g_pszProBuffer;
DWORD Code = 1;
DWORD size;
if(!WriteProcessMemory(g_hProcess,(LPVOID)CodeAddr,(LPVOID)&Code,4,&size))
{
MessageBox(NULL,"写入远程进程失败","Error",0);
return TRUE;
}
//远程释放会崩
//VirtualFreeEx(hProcess,pszProBuffer,SizeOfImage,MEM_DECOMMIT);
}
}
}
}
return FALSE;
}
//****************************注入******************************
DWORD WINAPI ThreadInject(LPVOID dwPid)
{
//获取当前模块句柄
HANDLE hCurrentProcess = NULL;
hCurrentProcess = ::GetModuleHandle(NULL);
if(hCurrentProcess==NULL)
{
MessageBox(NULL,"获取当前模块句柄失败","Error",0);
return 0;
}
//得到自己的SizeOfImage和ImageBase
DWORD EntryPoint = 0;
DWORD ImageBase = 0;
DWORD SizeOfImage = GetSizeOfImage((LPVOID)(DWORD)hCurrentProcess,ImageBase,EntryPoint);
//当前空间申请空间存放自身代码
LPVOID pszBuffer = malloc(SizeOfImage);
if(pszBuffer==NULL)
{
MessageBox(NULL,"申请空间失败","Error",0);
return 0;
}
ZeroMemory(pszBuffer,SizeOfImage);
//空间存放自身代码
memcpy(pszBuffer,(LPVOID)ImageBase,SizeOfImage);
//获取要注入的进程A句柄
HANDLE hProcess = NULL;
hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,(DWORD)dwPid);
if(hProcess==NULL)
{
//MessageBox(NULL,"获取进程A句柄失败","Error",0);
return 0;
}
//在远程进程A中申请空间
LPVOID pszProBuffer = NULL;
pszProBuffer = VirtualAllocEx(hProcess,NULL,SizeOfImage,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(pszProBuffer==NULL)
{
MessageBox(NULL,"远程进程A中申请空间失败","Error",0);
return 0;
}
//修复重定位表
FixRelocation(pszBuffer,(DWORD)pszProBuffer);
//写入远程进程空间
DWORD WriteSize = 0;
if(!WriteProcessMemory(hProcess,pszProBuffer,pszBuffer,SizeOfImage,&WriteSize))
{
MessageBox(NULL,"写入远程进程失败","Error",0);
return 0;
}
//创建远程线程
坑点 给的线程函数地址需要是重定位后的
DWORD dwProcOffset = (DWORD)Entry - (DWORD)ImageBase + (DWORD)pszProBuffer;
坑点
HANDLE hThread = NULL;
hThread = CreateRemoteThread(hProcess,NULL,NULL,(LPTHREAD_START_ROUTINE)dwProcOffset,(LPVOID)pszProBuffer,0,0);
//释放本身内存
free(pszBuffer);
//为退出线程留参数
g_hProcess = hProcess;
g_ImageBase = ImageBase;
g_pszProBuffer= pszProBuffer;
return 0;
}
//****************************注入******************************
//主线程函数
DWORD WINAPI MainThread(LPVOID Ordinal)
{
switch((DWORD)Ordinal)
{
case 1:
{
//调出控制台
//AllocConsole();
//freopen("CONOUT$", "w", stdout);
//加载图标
HICON hIcon = NULL;
hIcon = LoadIcon(g_hInstance,(CHAR*)IDI_ICON1);
SendMessage(g_hDlg, WM_SETICON, ICON_BIG,(DWORD)hIcon);
SendMessage(g_hDlg, WM_SETICON, ICON_SMALL,(DWORD)hIcon);
//创建共享内存
g_hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,0x1000,"Hacker1");
if(g_hFileMap==NULL)
{
MessageBox(NULL,"创建共享内存失败","创建共享内存失败",0);
return TRUE;
}
lpHacker = MapViewOfFile(g_hFileMap,FILE_MAP_ALL_ACCESS,0,0,0x1000);
ZeroMemory(lpHacker,0x1000);
break;
}
case 2:
{
TCHAR lpPid[6] = {0};
GetDlgItemText(g_hDlg,IDC_EDIT1,lpPid,5);
DWORD dwPid = 0;
sscanf(lpPid,"%d",&dwPid);
if(dwPid==0)
{
MessageBox(NULL,"获取ItemText失败","获取ItemText失败",0);
}
HANDLE hThreadInject = NULL;
hThreadInject = CreateThread(NULL,0,ThreadInject,(LPVOID)dwPid,0,NULL);
//WaitForSingleObject(hThreadInject,INFINITE);
if( hThreadInject!=NULL && dwPid!=0)
{
Inject=TRUE;
CloseHandle(hThreadInject);
}
break;
}
case 3:
{
//下面是进程监控
if(Inject)
{
//监控位
PDWORD lpWriteFlag = (PDWORD)lpHacker;
//获取当前监控状态
TCHAR lpMessage[15] = {0};
GetDlgItemText(g_hDlg,IDOK,lpMessage,14);
if(strcmp(lpMessage,"开启监控")==0)
{
SendDlgItemMessage(g_hDlg, IDOK, WM_SETTEXT, 0, (DWORD)"关闭监控");
*lpWriteFlag = 1;
lpWriteFlag[1] = 1;
}
else
{
SendDlgItemMessage(g_hDlg, IDOK, WM_SETTEXT, 0, (DWORD)"开启监控");
*lpWriteFlag = 1;
lpWriteFlag[1] = 0;
}
break;
}
else
{
MessageBox(NULL,"没有注入","没有注入",0);
break;
}
}
case 4:
{
if(Inject)
{
//监控位
PDWORD lpWriteFlag = (PDWORD)lpHacker;
//获取当前监控状态
TCHAR lpMessage[15] = {0};
GetDlgItemText(g_hDlg,IDOK3,lpMessage,14);
if(strcmp(lpMessage,"开启监控")==0)
{
SendDlgItemMessage(g_hDlg, IDOK3, WM_SETTEXT, 0, (DWORD)"关闭监控");
*lpWriteFlag = 2;
lpWriteFlag[2] = 1;
}
else
{
SendDlgItemMessage(g_hDlg, IDOK3, WM_SETTEXT, 0, (DWORD)"开启监控");
*lpWriteFlag = 2;
lpWriteFlag[2] = 0;
}
break;
}
else
{
MessageBox(NULL,"没有注入","没有注入",0);
break;
}
}
case 5:
{
if(Inject)
{
//监控位
PDWORD lpWriteFlag = (PDWORD)lpHacker;
//获取当前监控状态
TCHAR lpMessage[15] = {0};
GetDlgItemText(g_hDlg,IDOK5,lpMessage,14);
if(strcmp(lpMessage,"开启监控")==0)
{
SendDlgItemMessage(g_hDlg, IDOK5, WM_SETTEXT, 0, (DWORD)"关闭监控");
*lpWriteFlag = 3;
lpWriteFlag[3] = 1;
}
else
{
SendDlgItemMessage(g_hDlg, IDOK5, WM_SETTEXT, 0, (DWORD)"开启监控");
*lpWriteFlag = 3;
lpWriteFlag[3] = 0;
}
break;
}
else
{
MessageBox(NULL,"没有注入","没有注入",0);
break;
}
}
//下面是远程调用
case 1001:
{
if(!Inject)MessageBox(NULL,"没有注入","没有注入",0);
PDWORD lpWriteFlag = (PDWORD)lpHacker;
*lpWriteFlag = 4;
lpWriteFlag[4] = 1;
break;
}
case 1002:
{
if(!Inject)MessageBox(NULL,"没有注入","没有注入",0);
PDWORD lpWriteFlag = (PDWORD)lpHacker;
*lpWriteFlag = 5;
lpWriteFlag[5] = 1;
break;
}
case 1003:
{
if(!Inject)MessageBox(NULL,"没有注入","没有注入",0);
PDWORD lpWriteFlag = (PDWORD)lpHacker;
*lpWriteFlag = 6;
lpWriteFlag[6] = 1;
break;
}
case 1004:
{
if(!Inject)MessageBox(NULL,"没有注入","没有注入",0);
PDWORD lpWriteFlag = (PDWORD)lpHacker;
*lpWriteFlag = 7;
lpWriteFlag[7] = 1;
break;
}
default:
break;
}
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
g_hInstance = hInstance;
DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogFunc);
return 0;
}
Tools.cpp程序—远程模块:
#include "tools.h"
using std::cout;
using std::endl;
DWORD ExitCode = 0;
DWORD ImageBase;
DWORD g_Error;
HANDLE g_hImportFile;
//************************************IAT Hook****************************************
DWORD g_ImportAddr;
DWORD g_lpIATMessage;
DWORD g_lpIATCreate;
DWORD g_lpIATProcess;
DWORD g_SourceMessageAddr;
DWORD g_SourceCreateAddr;
DWORD g_SourceProcess;
HANDLE hRemoFile;
HANDLE hRemoProcess;
//多字符MessageBox
int WINAPI PrintMessageA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
//打印MessageBoxA的参数到文件上 \r\n一起是换行
g_hImportFile = CreateFile(TEXT("C:\\Export.txt"),GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
g_Error=GetLastError();
//存在就只打开
if(g_Error!=0)
{
g_hImportFile = CreateFile(TEXT("C:\\Export.txt"),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
g_Error = 0;
}
TCHAR szBuffer[MAX_PATH] = {0};
sprintf(szBuffer,"HWND:%d ,LPCTSTR:%s ,LPCTSTR:%s ,UINT:%d\r\n",(DWORD)hWnd,lpText,lpCaption,(DWORD)uType);
DWORD dwWritten = 0;
SetFilePointer(g_hImportFile, 0, NULL, FILE_END);
WriteFile(g_hImportFile, szBuffer, strlen(szBuffer), &dwWritten, NULL);
CloseHandle(g_hImportFile);
//执行真正的MessageBoxA
HMODULE hUser32Mod = NULL;
hUser32Mod = LoadLibrary("User32.dll");
if (hUser32Mod == NULL)
{
return 0;
}
typedef int(WINAPI* p)(HWND, LPCTSTR, LPCTSTR, UINT); //WINAPI函数
p func = NULL;
func = (p)GetProcAddress(hUser32Mod, "MessageBoxA");
if (func == NULL)
{
return 0;
}
func(hWnd, lpText, lpCaption, uType);
CloseHandle(hUser32Mod);
return 0;
}
//多字符CreateFile
HANDLE WINAPI PrintCreateA(
LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile )
{
//打印MessageBoxA的参数到文件上 \r\n一起是换行
g_hImportFile = CreateFile(TEXT("C:\\Export.txt"),GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
g_Error=GetLastError();
//存在就只打开
if(g_Error!=0)
{
g_hImportFile = CreateFile(TEXT("C:\\Export.txt"),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
g_Error = 0;
}
TCHAR szBuffer[MAX_PATH] = {0};
sprintf(szBuffer,"FileName:%s\r\n",lpFileName);
DWORD dwWritten = 0;
SetFilePointer(g_hImportFile, 0, NULL, FILE_END);
WriteFile(g_hImportFile, szBuffer, strlen(szBuffer), &dwWritten, NULL);
CloseHandle(g_hImportFile);
//执行真正的CreateFileA
HMODULE hKernel32Mod = NULL;
hKernel32Mod = LoadLibrary("Kernel32.dll");
if (hKernel32Mod == NULL)
{
return 0;
}
typedef HANDLE(WINAPI* p)(LPCTSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE); //WINAPI函数
p func = NULL;
func = (p)GetProcAddress(hKernel32Mod, "CreateFileA");
if (func == NULL)
{
return 0;
}
hRemoFile = func(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
CloseHandle(hKernel32Mod);
return hRemoFile;
}
//多字符OpenProcess
HANDLE WINAPI PrintProcess(DWORD dwDesiredAccess, // access flag
BOOL bInheritHandle, // handle inheritance option
DWORD dwProcessId // process identifier
)
{
//打印OpenProcessA的参数到文件上 \r\n一起是换行
g_hImportFile = CreateFile(TEXT("C:\\Export.txt"),GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
g_Error=GetLastError();
//存在就只打开
if(g_Error!=0)
{
g_hImportFile = CreateFile(TEXT("C:\\Export.txt"),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
g_Error = 0;
}
TCHAR szBuffer[MAX_PATH] = {0};
sprintf(szBuffer,"dwDesiredAccess:%d ,bInheritHandle:%d ,dwProcessId:%d\r\n",dwDesiredAccess,bInheritHandle,dwProcessId);
DWORD dwWritten = 0;
SetFilePointer(g_hImportFile, 0, NULL, FILE_END);
WriteFile(g_hImportFile, szBuffer, strlen(szBuffer), &dwWritten, NULL);
CloseHandle(g_hImportFile);
//执行真正的OpenProcessA
HMODULE hKernel32Mod = NULL;
hKernel32Mod = LoadLibrary("kernel32.dll");
if (hKernel32Mod == NULL)
{
return 0;
}
typedef HANDLE(WINAPI* p)(DWORD, BOOL,DWORD); //WINAPI函数
p func = NULL;
func = (p)GetProcAddress(hKernel32Mod, "OpenProcess");
if (func == NULL)
{
return 0;
}
hRemoProcess = func(dwDesiredAccess,bInheritHandle,dwProcessId);
CloseHandle(hKernel32Mod);
return hRemoProcess;
}
//替换地址,返回原来地址 和 原来地址的存放点 第三个参数为OUT
DWORD ReplaceFuncAddr(char* DllName, char* FuncName, DWORD FuncAddr,OUT DWORD& lpIATaddr)
{
//1、找到对应dll
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)g_ImportAddr;
while (pImport->Name!=0) //最后会留一个空结构,这里就简单用Name判断
{
if (strcmp((char*)(ImageBase + pImport->Name), DllName) == 0)
{
break;
}
pImport++;
}
//2、找到对应dll的IAT表和INT表
PDWORD pIATData = (PDWORD)(ImageBase + pImport->FirstThunk);
PDWORD pINTData = (PDWORD)(ImageBase + pImport->OriginalFirstThunk);
//3、根据名字找到原函数位置(IAT表中的下标)
while (*(PDWORD)pINTData != 0)
{
if ((*pINTData & 0x80000000) == 0x80000000)
{
}
else
{
PIMAGE_IMPORT_BY_NAME pINTName = (PIMAGE_IMPORT_BY_NAME)(ImageBase+*pINTData);
if (strcmp((char*)(pINTName->Name), FuncName) == 0)
{
break;
}
}
pINTData++;
pIATData++;
}
//4、保存原来的地址 和 记录改变的地址
DWORD SourcePrcAddr = *pIATData;
lpIATaddr = (DWORD)pIATData;
//5、替换函数
DWORD oldProtected;
VirtualProtect(pIATData, 0x1000, PAGE_EXECUTE_READWRITE, &oldProtected);
*pIATData = FuncAddr;
VirtualProtect(pIATData, 0x1000, oldProtected, &oldProtected);
//6、返回原来函数地址
return SourcePrcAddr;
}
//卸载HooK
void Unstall(DWORD Addr,DWORD g_lpIATAddr)
{
DWORD oldProtected;
PDWORD addr = (PDWORD)g_lpIATAddr;
VirtualProtect(addr, 0x1000, PAGE_EXECUTE_READWRITE, &oldProtected); //修改内存保护属性
*addr = Addr;
VirtualProtect(addr, 0x1000, oldProtected, &oldProtected); //还原属性
}
//可以先将一些全局变量赋值
void InitParam()
{
//获取当前模块句柄
HANDLE hCurrentProcess = NULL;
hCurrentProcess = ::GetModuleHandle(NULL);
ImageBase = (DWORD)hCurrentProcess;
//得到导入表
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)ImageBase;
if (pDos->e_magic != IMAGE_DOS_SIGNATURE || *(PDWORD)((DWORD)pDos + pDos->e_lfanew) != IMAGE_NT_SIGNATURE)
{
return;
}
PIMAGE_FILE_HEADER pFile = (PIMAGE_FILE_HEADER)((DWORD)pDos + pDos->e_lfanew + 4);
PIMAGE_OPTIONAL_HEADER32 pOptionalFile = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFile + IMAGE_SIZEOF_FILE_HEADER);
g_ImportAddr = ((DWORD)ImageBase + pOptionalFile->DataDirectory[1].VirtualAddress);
}
//************************************IAT Hook****************************************
//得到Image_base SizeOfImage EntryPoint
DWORD GetSizeOfImage(IN LPVOID FileBuffer,OUT DWORD& ImageBase,OUT DWORD& EntryPoint)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)FileBuffer;
PIMAGE_FILE_HEADER pFile = (PIMAGE_FILE_HEADER)((DWORD)FileBuffer + pDos->e_lfanew + 0x4);
PIMAGE_OPTIONAL_HEADER32 pOption = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFile+IMAGE_SIZEOF_FILE_HEADER);
PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((DWORD)pOption+IMAGE_SIZEOF_NT_OPTIONAL32_HEADER);
ImageBase = pOption->ImageBase;
EntryPoint = pOption->AddressOfEntryPoint;
//防止ImageSize不准,靠最后一个节来得到ImageSize
DWORD Last_idex = pFile->NumberOfSections-1;
DWORD real_ImageSize = pSection[Last_idex].VirtualAddress+pSection[Last_idex].SizeOfRawData;
return real_ImageSize;
}
//修复重定位表
void FixRelocation(IN LPVOID Buffer,IN DWORD FixImageBase)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)Buffer;
if (pDos->e_magic != IMAGE_DOS_SIGNATURE || *(PDWORD)((DWORD)pDos + pDos->e_lfanew) != IMAGE_NT_SIGNATURE)
{
cout<<"NOT MZ"<<endl;
return ;
}
PIMAGE_FILE_HEADER pFile = (PIMAGE_FILE_HEADER)((DWORD)pDos + pDos->e_lfanew + 4);
PIMAGE_OPTIONAL_HEADER32 pOptionalFile = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFile + IMAGE_SIZEOF_FILE_HEADER);
PIMAGE_BASE_RELOCATION pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)Buffer+pOptionalFile->DataDirectory[5].VirtualAddress);
//保存原本值 更改ImageBase
DWORD Imagebase=pOptionalFile->ImageBase;
pOptionalFile->ImageBase = FixImageBase;
//修复重定位表
PWORD pDataAddr=(PWORD)((DWORD)pRelocation+8);
DWORD Block = pRelocation->SizeOfBlock;
DWORD VitualAddr = pRelocation->VirtualAddress;
PDWORD Replace = NULL;
DWORD Rva = 0;
while(Block!=0 && VitualAddr!=0)
{
for(DWORD i = 0;i<(Block-8)/2;i++)
{
// 高四位值为3 代表的是需要修改的数据
if((*(pDataAddr+i) & 0xF000) == 0x3000)
{
Rva = (*(pDataAddr+i) & 0x0FFF)+VitualAddr;
Replace = (PDWORD)((DWORD)Buffer + Rva);
*Replace = *Replace - Imagebase + FixImageBase;
}
}
pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocation+Block);
Block = pRelocation->SizeOfBlock;
VitualAddr = pRelocation->VirtualAddress;
pDataAddr=(PWORD)((DWORD)pRelocation+8);
}
}
//要执行的函数 线程函数格式
DWORD WINAPI Entry( LPVOID lpParameter)
{
/修复IAT表 Win10上不行,不知道什么原因//
LPVOID Buffer = lpParameter;
//得到导入表
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)Buffer;
if (pDos->e_magic != IMAGE_DOS_SIGNATURE || *(PDWORD)((DWORD)pDos + pDos->e_lfanew) != IMAGE_NT_SIGNATURE)
{
return 0;
}
PIMAGE_FILE_HEADER pFile = (PIMAGE_FILE_HEADER)((DWORD)pDos + pDos->e_lfanew + 4);
PIMAGE_OPTIONAL_HEADER32 pOptionalFile = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFile + IMAGE_SIZEOF_FILE_HEADER);
DWORD ImportSec = ((DWORD)Buffer + pOptionalFile->DataDirectory[1].VirtualAddress);
//导入表
PIMAGE_IMPORT_DESCRIPTOR ImportAddr = (PIMAGE_IMPORT_DESCRIPTOR)ImportSec;
while (ImportAddr->Name!=0) //最后会留一个空结构,这里就简单用Name判断
{
TCHAR* Name = (char*)((DWORD)Buffer + ImportAddr->Name);
//找到对应模块的IAT表和INT表
PDWORD pIATData = (PDWORD)((DWORD)Buffer + ImportAddr->FirstThunk);
PDWORD pINTData = (PDWORD)((DWORD)Buffer + ImportAddr->OriginalFirstThunk);
//根据序号或名字修复IAT表
while (*(PDWORD)pINTData != 0)
{
if ((*pINTData & 0x80000000) == 0x80000000)
{
*pIATData = (DWORD)GetProcAddress(LoadLibrary(Name),(TCHAR*)(*pINTData & 0x7fffffff));
}
else
{
PIMAGE_IMPORT_BY_NAME pINTName = (PIMAGE_IMPORT_BY_NAME)((DWORD)Buffer +*pINTData);
*pIATData = (DWORD)GetProcAddress(LoadLibrary(Name),(TCHAR*)(pINTName->Name));
}
pIATData++;
pINTData++;
}
ImportAddr++;
}
/修复IAT表//
//创建共享内存
HANDLE tohFileMap = NULL;
LPVOID lpHackerBuffer;
tohFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,0x1000,"Hacker1");
lpHackerBuffer = MapViewOfFile(tohFileMap,FILE_MAP_ALL_ACCESS,0,0,0x1000);
PDWORD lpReadBuffer = (PDWORD)lpHackerBuffer;
//可以先将一些全局变量赋值
InitParam();
//程序代码
while(1)
{
if(ExitCode)
{
//取消映射
UnmapViewOfFile(tohFileMap);
CloseHandle(tohFileMap);
lpHackerBuffer=NULL;
ExitCode = 0;
g_ImportAddr = 0;
ImageBase = 0;
g_lpIATMessage = 0;
g_lpIATCreate = 0;
g_SourceMessageAddr = 0;
g_SourceCreateAddr = 0;
g_Error = 0;
//退出线程
MessageBox(NULL,"已退出","Success",0);
ExitThread(1);
break;
}
switch(lpReadBuffer[0])
{
case 1:
{
if(lpReadBuffer[1]==1)
{
MessageBox(NULL,"Message开启","Message开启",0);
//替换地址 //安装Hook IAT Hook
char DllName[20] = "USER32.dll";
char FuncName[30] = "MessageBoxA";
g_SourceMessageAddr = ReplaceFuncAddr(DllName,FuncName,(DWORD)PrintMessageA,g_lpIATMessage);
lpReadBuffer[0]=0;
}
else
{
MessageBox(NULL,"Message关闭","Message关闭",0);
//卸载Hook
Unstall(g_SourceMessageAddr,g_lpIATMessage);
lpReadBuffer[0]=0;
}
break;
}
case 2:
{
if(lpReadBuffer[2]==1)
{
MessageBox(NULL,"CreateFile开启","CreateFile开启",0);
//IAT Hook
char DllName[20] = "KERNEL32.dll";
char FuncName[30] = "CreateFileA";
g_SourceCreateAddr = ReplaceFuncAddr(DllName,FuncName,(DWORD)PrintCreateA,g_lpIATCreate);
lpReadBuffer[0]=0;
}
else
{
MessageBox(NULL,"CreateFile关闭","CreateFile关闭",0);
//卸载Hook
Unstall(g_SourceCreateAddr,g_lpIATCreate);
lpReadBuffer[0]=0;
}
break;
}
case 3:
{
//安装Hook
if(lpReadBuffer[3]==1)
{
MessageBox(NULL,"OpenProcess开启","OpenProcess开启",0);
//IAT Hook
char DllName[20] = "KERNEL32.dll";
char FuncName[30] = "OpenProcess";
g_SourceProcess = ReplaceFuncAddr(DllName,FuncName,(DWORD)PrintProcess,g_lpIATProcess);
lpReadBuffer[0]=0;
}
//卸载HooK
else
{
MessageBox(NULL,"OpenProcess关闭","OpenProcess关闭",0);
Unstall(g_SourceProcess,g_lpIATProcess);
lpReadBuffer[0]=0;
}
break;
}
case 4:
{
DWORD addr = 0x401000;
__asm{
call addr
}
lpReadBuffer[0]=0;
break;
}
case 5:
{
DWORD addr = 0x401080;
__asm{
call addr
}
lpReadBuffer[0]=0;
break;
}
case 6:
{
DWORD addr = 0x4011f0;
__asm{
call addr
}
lpReadBuffer[0]=0;
break;
}
case 7:
{
DWORD addr = 0x401120;
__asm{
call addr
}
lpReadBuffer[0]=0;
break;
}
default:
break;
}
Sleep(1000);
}
return 0;
}
tools.h–头文件
#if !defined(TOOLS_H)
#define TOOLS_H
#include "resource.h"
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
//得到Image_base SizeOfImage EntryPoint
DWORD GetSizeOfImage(IN LPVOID FileBuffer,OUT DWORD& ImageBase,OUT DWORD& EntryPoint);
//修复重定位表
void FixRelocation(IN LPVOID Buffer,IN DWORD FixImageBase);
//可以先将一些全局变量赋值
void InitParam();
// 提权函数:提升为DEBUG权限
BOOL EnableDebugPrivilege();
//***********IAT Hook*********
DWORD ReplaceFuncAddr(char* DllName, char* FuncName, DWORD FuncAddr,OUT DWORD& lpIATaddr);
void Unstall(DWORD Addr,DWORD g_lpIATAddr);
void InitParam();
int WINAPI PrintMessageA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
//***********IAT Hook*********
//要执行的函数 线程函数格式
DWORD WINAPI Entry( LPVOID lpParameter);
#endif
resource.h --资源头文件
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by resource.rc
//
#define IDOK2 3
#define IDOK3 7
#define IDOK4 8
#define IDOK5 9
#define IDOK6 10
#define IDD_DIALOG1 101
#define IDI_ICON1 102
#define IDC_BUTTON1 1000
#define IDC_EDIT1 1001
#define IDC_STATIC2 1002
#define IDC_STATIC3 1003
#define IDC_BUTTON2 1007
#define IDC_BUTTON3 1008
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1008
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif