Win32滴水项目---进程监控

进程监控–项目练习

项目要求:
在这里插入图片描述

特别说明

注意:此次项目在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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值