/*
*
* Hook Api Dll 文件
*
* 实现进程的Api Hook操作
*
* Made By Adly
*
* Email: Adly369046978@163.com
*
* 2008-7-22
*
*/
#include <stdio.h>
#include <windows.h>
#include "HookApiDll.h"
HANDLE hHookThread = NULL;
DWORD dwThreadId = 0;
//---------------------------------------
//函数声明
//
//---------------------------------------
//卸载已Hook的Api
void UnHookApi();
//得到需要动态获得的Api地址
BOOL LookupApiAddress();
//---------------------------------------
//引用外部函数声明
//---------------------------------------
//HOOK API 入口函数
extern void HookApi();
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//DLL主函数
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, //Dll模块句柄
DWORD fdwReason, //调用原因
LPVOID lpvReserved //保留
)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH: //进程加载Dll
//------------------------------------------------------------------
//利用 CreateThread 创建新线程来进行 API HOOK
//
// 注意:
// 所有用到的API(除了kernel32库中的API)都要用动态获取技术
// 先用GetModuleHandle,如果失败,再用LoadLibraryA加载相应的dll文件
// 然后利用GetProcAddress得到API地址
//得到需要动态获得的Api地址
if(!GetApiAddress())
{
//获取Api地址失败
return FALSE;
}
hHookThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HookApi, NULL, 0, &dwThreadId);
break;
case DLL_THREAD_ATTACH: //线程加载Dll
break;
case DLL_THREAD_DETACH: //线程卸载Dll
break;
case DLL_PROCESS_DETACH: //进程卸载Dll
//------------------------------------------------------------------
//利用 TerminateThread 结束新创建的线程
//再卸载已HOOK的API
//
// 注意:
// 所有用到的API(除了kernel32库中的API)都要用动态获取技术
// 先用GetModuleHandle,如果失败,再用LoadLibraryA加载相应的dll文件
// 然后利用GetProcAddress得到API地址
::TerminateThread(hHookThread, 0); //终止HOOK线程
UnHookApi(); //卸载已HOOK的API
break;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////
////////// 注意: ////////////
////////// 所有用到的API(除Kernel32)都要用动态获取技术 ////////////
////////// 先用GetModuleHandle,如果失败,再用LoadLibraryA加载相应的dll文件 //////
////////// 然后利用GetProcAddress得到API地址 ////////////
/////////////////////////////////////////////////////////////////////////////////////
//--------------------------------------------------------------------
//通用HOOK API接口的构造
//
// 将所有HOOK了的API信息构造成一个链表
//
//--------------------------------------------------------------------
// 这里添加链表管理操作函数
//
// Add Here ...
pHookApiInfo pHookApiInfoHead = NULL; //链表头指针
//将结点添加到链表
BOOL InsertHookApiInfoList(pHookApiInfo pHookApiInfoNode)
{
if(!pHookApiInfoNode)
{
//要插入的结点为空
return FALSE;
}
if(pHookApiInfoHead) //不为空链
{
//将新加入的结点作为链表头
pHookApiInfoNode->Next = pHookApiInfoHead; //链表头放到新加入结点的Next处
pHookApiInfoHead = pHookApiInfoNode; //重新将链表头指向刚加入的结点
}
else //链表头为空
{
//将头指针指向新加入的结点
pHookApiInfoNode->Next = NULL;
pHookApiInfoHead = pHookApiInfoNode;
}
return TRUE;
}
//移除所有已Hook成功的Api
BOOL RemoveAllHookApi()
{
pHookApiInfo pHAIH;
pHAIH = pHookApiInfoHead; //链表头
while(pHAIH) //如果链中还存在结点
{
//卸载Hook了的Api
HookOnOrOff(pHAIH->pfApiAddress, pHAIH->OldApiMachineCode, 5);
pHookApiInfo pTemp;
//pTemp指向头结点
pTemp = pHAIH;
//头结点后移
pHAIH = pHAIH->Next;
//释放已卸载了的结点
free(pTemp);
}
return TRUE;
}
//通过Api名得到所在结点
pHookApiInfo GetNodeByApi(char *szApiName)
{
pHookApiInfo pHAIH;
pHAIH = pHookApiInfoHead; //链表头
while(pHAIH) //如果链中还存在结点
{
if(!strcmp(pHAIH->szApiName, szApiName))
{
//找到该结点
return pHAIH;
}
pHAIH = pHAIH->Next; //指向下一个结点
}
return NULL;
}
//*********************************************************************
//HOOK/UNHOOK API所需要的函数
//
// IN
// lpfFunctionAddress - 要HOOK的API地址
// ucFunctionJmpCode - 要修改为的跳转机器码
// dwModifyLen - 要修改的字节长度
//
// OUT
// BOOL - 成功返回TRUE,否则返回FALSE
//
BOOL HookOnOrOff(LPVOID lpfFunctionAddress, UCHAR *ucFunctionJmpCode, DWORD dwModifyLen)
{
HANDLE hProc;
DWORD dwCurrentPid;
DWORD dwOldProtect;
//得到当前进程PID
dwCurrentPid = ::GetCurrentProcessId();
//打开当前进程
hProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwCurrentPid);
if(!hProc)
{
//OpenProcess失败
return FALSE;
}
//修改将要HOOK的API的前dwModifyLen个字节的属性为可读写
::VirtualProtectEx(hProc, lpfFunctionAddress, dwModifyLen, \
PAGE_READWRITE, &dwOldProtect);
//将要HOOK的API的前dwModifyLen个字节替换为跳转指令机器码
::WriteProcessMemory(hProc, lpfFunctionAddress, \
ucFunctionJmpCode, dwModifyLen, NULL);
//还原原属性
::VirtualProtectEx(hProc, lpfFunctionAddress, dwModifyLen, \
dwOldProtect, &dwOldProtect);
//关闭打开的进程句柄
::CloseHandle(hProc);
return TRUE;
}
//*********************************************************************
//初始化Hook操作
BOOL InitHook(char *szLibModuleName/*库名*/, \
char *szLibDllModuleName/*库的Dll名*/, \
char *szApiName/*Api名*/, \
DWORD NewFunctionAddress/*替换函数地址*/ \
)
{
HMODULE hMod = NULL;
FARPROC fpApiAddress = NULL;
UCHAR OldApiMachineCode[5]; //原始Api的前5个字节机器码
UCHAR NewJmpMachineCode[5]; //新构造的JMP机器码(5字节)
//判断该进程内以前有没有加载该API库
hMod = ::GetModuleHandle(szLibModuleName);
if(!hMod)
{
//以前没有加载过
hMod = ::LoadLibrary(szLibDllModuleName);
if(!hMod)
{
//加载库失败
return FALSE;
}
}
fpApiAddress = ::GetProcAddress(hMod, szApiName);
if(!fpApiAddress)
{
//得到 MessageBoxA 地址失败
return FALSE;
}
//替换原API的前5个字节为跳转指令
//使其先执行新函数
__asm
{
//; 保存原API前5字节
lea edi, OldApiMachineCode ;
mov esi, fpApiAddress ;
cld ;
movsd ;
movsb ;
//; 构造跳转机器码
//; NewMessageBoxACode[0] = 0xE9; // JMP 指令机器码
mov byte ptr [NewJmpMachineCode], 0E9h ;
//构造跳转指令中的相对地址
mov eax, NewFunctionAddress ;
mov ebx, fpApiAddress ;
sub eax, ebx ;
sub eax, 5 ;
mov dword ptr [NewJmpMachineCode+1], eax ;
}
//----------------------------------------
//这里不用释放该库
// 1.如果此API库在此前已加载, GetModuleHandle 就会成功
// 2.如果此API库在此前没加载, 而此时调用 LoadLibrary 加载它
// 此时不用释放,这样,如果后面使用动态加载该API库
// 则此动作也将被Hook
//
// ::FreeLibrary(hMod);
//开始Hook
if(!HookOnOrOff(fpApiAddress, NewJmpMachineCode, 5))
{
//Hook 失败
// Do Something here
//
return FALSE;
}
//------------------------------------
//这里将Hook后的Api信息添加到链表中
//
// Add Here ...
//分配新结点空间
pHookApiInfo pNewNode = (pHookApiInfo)malloc(sizeof(HookApiInfo));
if(!pNewNode)
{
//分配内存失败
return FALSE;
}
memset(pNewNode, 0, sizeof(HookApiInfo));
//填充结点信息
strcpy(pNewNode->szLibModuleName, szLibModuleName);
pNewNode->szLibModuleName[sizeof(pNewNode->szLibModuleName)-1] = '\0';
strcpy(pNewNode->szLibDllModuleName, szLibDllModuleName);
pNewNode->szLibDllModuleName[sizeof(pNewNode->szLibDllModuleName)-1] = '\0';
strcpy(pNewNode->szApiName, szApiName);
pNewNode->szApiName[sizeof(pNewNode->szApiName)-1] = '\
nvip
- 粉丝: 109
- 资源: 60
最新资源
- 多微网优化模型matlab 采用粒子群算法分析两个微网的优化调度,得到蓄电池,发电机以及微网间功率传输,程序有参考资料
- 潮流计算程序matlab 牛拉法 采用matlab对9节点进行潮流计算,采用牛拉法,程序运行可靠
- 微网优化调度matlab 采用matlab+yalmip编制含分布式和储能的微网优化模型,程序采用15分钟为采集节点,利用cplex求解,程序考虑发电机的启停约束,程序运行可靠
- PMSM永磁同步电机仿真三电平SVPWM矢量控制matlab PMSM双环矢量控制传统三电平
- 路径规划人工势场法以及改进人工势场法matlab代码,包含了
- MobaXterm 是一款功能强大且实用的终端仿真器软件.docx
- 三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,支持脉冲输出与定位指令(包括PLSY PWM PLSR PLSV DRVI DRVA 等指令
- Oracle Database Gateways for Win32-11gR2
- python071基于RSA加密算法软件的研究设计
- 成熟量产低压无刷伺服驱动 方案 全套软硬件资料 源码 原理图 需要的直接拿 基于28035平台
- 欧姆龙PLC ST语言6轴伺服RS232C通讯板CP1W-C IF0 真实项目程序,ST语言写的FB块 PLC用是两台CP1H-X40DT-D配置4块RS232C通讯板CP1W-CIF01 触摸屏是N
- 欧姆龙CP1H与力士乐VFC-x610变频器通讯程序功能:原创程序,可直接用于现场程序 欧姆龙CP1H的CIF11通讯板,实现对力士乐VFC-x610变频器 设定频率,控制正反转,读取实际频率,读取
- 级联型电力电子变压器,高压直流MMC控制系统,级联数可选,调 制方式有移相载波,nlm及混合调制,拥有冒泡排序,递归排序等方法,可控制三相不平衡与环流
- 西门子PLC双轴定位算法电池焊接控制程序-S7-1200 +威纶通触摸屏 S7-1200PLC做的电池焊接程序,电池包里面有n*m行列个电池 程序设计灵活SCL语言+梯形图,采用了位置试教与定位路径规
- 变压器副边突然短路simulink仿真
- MATLAB代码:基于模型预测控制的楼宇负荷需求响应研究 关键词:楼宇负荷 空调 模型预测控制 需求响应 仿真平台:MATLAB+CVX平台 主要内容:代码主要做的是一个建筑楼宇的需求响应问题,首
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈