现在的位置: 首页 > 综合 > 正文

HOOK API公共模块

2013年10月26日 ⁄ 综合 ⁄ 共 7220字 ⁄ 字号 评论关闭

这个只是API HOOK中的公共模块(需要加入xde32反汇编功能)

HOOK.H

#ifndef _MY_HOOK_API_
#define _MY_HOOK_API_
#define MAX_HOOK_NUM   128

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <tchar.h>
#include "xde32/xde.h"

#define LOWBYTE 0x000000FF

extern DWORD SleepTime;
#define SLEEP_JMP(a) { __asm jmp eax }

#define NAKED  __declspec(naked)

BOOL HookProc(LPCTSTR DllName, LPCSTR ProcName, PVOID MyProcName);

DWORD WINAPI GetNewAddress(PVOID MyAddr);

typedef struct _FunAddress 
{
	DWORD MyFunAddr;   // 处理hook函数地址
	DWORD NewMalloc;   // 复制出来的首地址函数地址
}FunAddress, *PFunAddress;

#endif // _MY_HOOK_API_

 

// HOOK.cpp

#include "Hook.h"

FunAddress Function[MAX_HOOK_NUM] = {0};
DWORD NowFunNum = 0;

// 分发函数
DWORD WINAPI GetNewAddress(PVOID MyAddr)
{
	DWORD MyFunAddr = (DWORD)MyAddr;
	for (DWORD i=0; i<NowFunNum; i++)
	{
		if (Function[i].MyFunAddr == MyFunAddr)
		{
			return Function[i].NewMalloc;
		}
	}
	return NULL;
}



BOOL HookProc(LPCTSTR DllName, LPCSTR ProcName, PVOID MyProcAddr)
{
	BYTE TMP[5] = {0};
	DWORD OldProtect;
	struct xde_instr UnUse;
	BYTE retbuf[] = "\x68\x00\x00\x00\x00\xC3"; // push address , retn
	
	HMODULE Dll = LoadLibrary(DllName);
	if (Dll == NULL)
	{
		return FALSE;
	}
	
	PVOID ProcAddress = (PVOID)GetProcAddress(Dll, ProcName);
	if (ProcAddress == NULL)
	{
		FreeLibrary(Dll);
		return FALSE;
	}
	
	////////////////////////////////////////////////////////////
	DWORD NewAddress = (DWORD)MyProcAddr - (DWORD)ProcAddress - 5;//偏移地址 = 我们函数的地址 - 原API函数的地址 - 5(我们这条指令的长度)
	
	TMP[0]=(BYTE)0xE9;
	TMP[1]=(BYTE)(NewAddress&LOWBYTE);
	TMP[2]=(BYTE)((NewAddress>>8)&LOWBYTE);
	TMP[3]=(BYTE)((NewAddress>>16)&LOWBYTE);
	TMP[4]=(BYTE)((NewAddress>>24)&LOWBYTE);

	DWORD len = 0;
	while(len < 5)
	{
		DWORD i = xde_disasm((unsigned char *)ProcAddress, &UnUse);
		len += i;
		ProcAddress = (PVOID)((DWORD)ProcAddress + i);
	}
	ProcAddress = (PVOID)((DWORD)ProcAddress - len);

	*(DWORD *)(retbuf + 1) = (DWORD)ProcAddress + len;
	BYTE* ProcJmp = new BYTE[len + sizeof(retbuf)]; // 真正使用的大小 len + sizeof(retbuf) - 1
	if (ProcJmp == NULL)
	{
		// 申请内存失败
		return FALSE;
	}

	// 被替换的首部指令
	VirtualProtect(ProcJmp, len+sizeof(retbuf), PAGE_EXECUTE_READWRITE, &OldProtect);
	memcpy(ProcJmp, ProcAddress, len);
	memcpy(ProcJmp+len, retbuf, sizeof(retbuf));

	// 保存原函数——自己处理函数
	Function[NowFunNum].MyFunAddr = (DWORD)MyProcAddr;
	Function[NowFunNum].NewMalloc = (DWORD)ProcJmp;
	NowFunNum++ ;

	// Inline Hook
	VirtualProtect(ProcAddress, len, PAGE_EXECUTE_READWRITE, &OldProtect);
	memcpy(ProcAddress, TMP, 5);
	////////////////////////////////////////////////////////////
	
	return TRUE;
}

main.cpp 测试模块。

#include "Hook.h"

#define JMP_BACK(a)  GetNewAddress(a);SLEEP_JMP()


int WINAPI tempA(HWND hWnd,
				LPCSTR lpText,
				LPCSTR lpCaption,
			   UINT uType)
{
	DWORD wBytes;

	HANDLE handle = CreateFile(TEXT("C:\\hello.txt"),
		GENERIC_WRITE|GENERIC_READ,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL,
		OPEN_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		0);
	if ( handle == INVALID_HANDLE_VALUE )
	{
		return 0;
	}
	SetFilePointer(handle, 0, NULL , FILE_END);
	if (lpText != NULL)
	{
		WriteFile(handle, lpText, strlen(lpText), &wBytes, NULL);
		WriteFile(handle, "\r\n", 2, &wBytes, NULL);
	}
	if (lpCaption != NULL)
	{
		WriteFile(handle, lpCaption, strlen(lpCaption), &wBytes, NULL);
		WriteFile(handle, "\r\n", 2, &wBytes, NULL);
	}
	CloseHandle(handle);
	return 0;
}

int WINAPI tempW(HWND hWnd,
				LPCWSTR lpText,
				LPCWSTR lpCaption,
				UINT uType)
{
	DWORD wBytes;
	
	HANDLE handle = CreateFile(TEXT("C:\\hello.txt"),
		GENERIC_WRITE|GENERIC_READ,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL,
		OPEN_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		0);
	if ( handle == INVALID_HANDLE_VALUE )
	{
		return 0;
	}
	SetFilePointer(handle, 0, NULL , FILE_END);
	if (lpText != NULL)
	{
		WriteFile(handle, lpText, wcslen(lpText), &wBytes, NULL);
		WriteFile(handle, L"\r\n", 4, &wBytes, NULL);
	}
	if (lpCaption != NULL)
	{
		WriteFile(handle, lpCaption, wcslen(lpCaption), &wBytes, NULL);
		WriteFile(handle, L"\r\n", 4, &wBytes, NULL);
	}
	CloseHandle(handle);
	return 0;
}

int NAKED MyMessageBoxA(
			   HWND hWnd,          // handle to owner window
			   LPCSTR lpText,     // text in message box
			   LPCSTR lpCaption,  // message box title
			   UINT uType          // message box style
			   )
{
#define CANSGS 4
	__asm {
		push dword ptr[esp+4*CANSGS]
		push dword ptr[esp+4*CANSGS]
		push dword ptr[esp+4*CANSGS]
		push dword ptr[esp+4*CANSGS]
		call tempA
	}
	JMP_BACK(MyMessageBoxA);
}

int NAKED MyMessageBoxW(
						HWND hWnd,          // handle to owner window
						LPCSTR lpText,     // text in message box
						LPCSTR lpCaption,  // message box title
						UINT uType          // message box style
						)
{
#define CANSGS 4
	__asm {
		push dword ptr[esp+4*CANSGS]
		push dword ptr[esp+4*CANSGS]
		push dword ptr[esp+4*CANSGS]
		push dword ptr[esp+4*CANSGS]
		call tempW
	}
	JMP_BACK(MyMessageBoxW);
}


// hook函数
VOID MyHookAll()
{
	HookProc("user32.dll", "MessageBoxA", MyMessageBoxA);
	HookProc("user32.dll", "MessageBoxW", MyMessageBoxW);
}


BOOL APIENTRY DllMain( HANDLE hModule, 
					  DWORD  ul_reason_for_call, 
					  LPVOID lpReserved
					  )
{
	switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			MyHookAll();
			break;
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}

//  注入程序

#include <iostream>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <TlHelp32.h>
#include <tchar.h>

DWORD processNameToId(LPCSTR lpszProcessName)//得到进程ID
{
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32 pe;
	pe.dwSize = sizeof(PROCESSENTRY32);

	if (!Process32First(hSnapshot, &pe)) 
	{
		printf("Process32First 调用失败!\n");
		return 0;
	}

	while (Process32Next(hSnapshot, &pe)) {
		if (!stricmp(lpszProcessName, pe.szExeFile)) {
			return pe.th32ProcessID;
		}
	}
	return 0;
}

BOOL EnableDebugPrivilege(BOOL bEnable = TRUE) 
{ 
	
	BOOL fOK = FALSE;
	HANDLE hToken;
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) //打开进程访问令牌
	{ 
		//试图修改“调试”特权
		TOKEN_PRIVILEGES tp;
		tp.PrivilegeCount = 1;
		LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
		tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
		AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
		fOK = (GetLastError() == ERROR_SUCCESS);
		CloseHandle(hToken); 
	} 
	return fOK; 
}

int To_CreateThread(char* FileName, DWORD PID)
{
	char buff[MAX_PATH];
	const DWORD dwThreadSize = MAX_PATH;//远程线程申请大小
	
	if(PID == 0)//进程ID error
	{
		printf("process ID error\n");
		return -1;
	}
	
	buff[0] = '"';
	// 是否是完整路径
	if (FileName[1] != ':')
	{
		GetCurrentDirectory(MAX_PATH, buff);
		strcat(buff, "\\");
		strcat(buff, FileName);
	}
	else
	{
		strcpy(buff, FileName);
	}
//	strcat(buff, "\"");
	printf(buff);

	EnableDebugPrivilege(TRUE);

	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
	
	//远程线程申请内存
	void* pRemoteThread = VirtualAllocEx(hProcess, 0, 
		dwThreadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	if (pRemoteThread == NULL)
	{
		printf("申请远程内存失败! %d\n", GetLastError());
		return -1;
	}
	//把线程体写入宿主进程中
	if (!WriteProcessMemory(hProcess, \
		pRemoteThread, &buff, dwThreadSize, 0)) //注入dll
	{
		printf("写入远程线程数据失败! %d", GetLastError());
		return -1;
	}
	//在宿主进程中创建线程
	PTHREAD_START_ROUTINE pfnStartAddr=(PTHREAD_START_ROUTINE)\
			GetProcAddress(GetModuleHandle(TEXT("Kernel32.dll")),"LoadLibraryA");
	if(pfnStartAddr == NULL)
	{
		printf("得到LoadLibrary 地址失败 %d\n", GetLastError());
		return -1;
	}
	
	if( CreateRemoteThread(hProcess, 
						   NULL,
						   0, 
						   pfnStartAddr, 
						   pRemoteThread, 
						   0, 
						   NULL) == NULL)
	{
		printf("创建远程线程失败: %d\n", GetLastError());
		return -1;
	}
	
	return 0;
}


void usage()
{
	printf("CreateRemoteThread /F DllName [ /P ProcessName | /PID PID ]\n\n");
	printf("  /F   需要注入的DLL文件名\n");
	printf("  /P   被注入的进程名\n");
	printf("  /PID 注入的进程ID\n\n");
	printf("CreateRemoteThread /F Insert.dll /P explorer.exe\n");
	printf("CreateRemoteThread /F Insert.dll /PID 504\n");
}

// process  /f filename [ /p process | /pid processID ]
int main(int argc, char* argv[])
{
	char FileName[MAX_PATH] = {0};
	char ProcessName[MAX_PATH] = {0};
	DWORD PID = 0; 

	if (argc < 5)
	{
		usage();
		return 0;
	}
	for (int i=1; i<argc; i++)
	{
		if (stricmp(argv[i], "/p") == 0)
		{
			strcpy( ProcessName, argv[++i] );
		}
		else if ( stricmp(argv[i], "/pid") == 0 )
		{
			PID = atoi(argv[++i]);
		}
		else if ( stricmp(argv[i], "/f") == 0 )
		{
			strcpy(FileName, argv[++i]);
		}
	}
	if ( PID == 0 )
	{
		PID = processNameToId(ProcessName);
	}
	To_CreateThread(FileName, PID);
	return 0;
}

程序包下载地址:http://ishare.iask.sina.com.cn/f/35080464.html

 

抱歉!评论已关闭.