【软件安全】API HOOK
2017-04-18 20:51
232 查看
API HOOK 顾名思义是挂钩API函数,拦截,控制某些API函数的调用,用于改变API执行结果的技术。
大致流程:
进入进程->获取相关权限->将我们写的dll写入进程内存->加载kernel32中的LoadLibrary()以调用我们写的dll。
http://blog.csdn.net/junbopengpeng/article/details/28142669一文中有更加详细的讲解,以下代码源自http://blog.chinaunix.net/uid-660282-id-2414901.html,对其做了修正,同时添加了详细注释,实现劫持源程序的MessageBox函数,改变其标题和内容,欢迎质询,一起学习。
源程序(我们劫持的程序):
我们编写的dll:
此处想补充一下dll文件的生成方式:在vc中新建工程Win32 Dynamic-Link Library,再在该工程中新建文件C++ Source File,代码完成后,compile->build即可,我们写的dll存放于该工程目录下的Debug文件夹中。
开始HOOK:
效果截图:
需要注意的是,在hook过程中,原函数不要关闭噢,否则就没有该进程了。
大致流程:
进入进程->获取相关权限->将我们写的dll写入进程内存->加载kernel32中的LoadLibrary()以调用我们写的dll。
http://blog.csdn.net/junbopengpeng/article/details/28142669一文中有更加详细的讲解,以下代码源自http://blog.chinaunix.net/uid-660282-id-2414901.html,对其做了修正,同时添加了详细注释,实现劫持源程序的MessageBox函数,改变其标题和内容,欢迎质询,一起学习。
源程序(我们劫持的程序):
#include #include int main(){ printf("hello world!\n"); while(1){ getchar(); MessageBoxA(NULL, "原函数", "yuan", 0); } return 0; }
我们编写的dll:
#include "windows.h" #include "process.h" #include "tlhelp32.h" #include "stdio.h" #pragma comment(lib,"th32.lib") PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNTHeaders; PIMAGE_OPTIONAL_HEADER pOptHeader; PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor; PIMAGE_THUNK_DATA pThunkData; PIMAGE_IMPORT_BY_NAME pImportByName; HMODULE hMod; // 定义MessageBoxA函数原型 // MessageBox函数原型:int WINAPI MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType); typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType); int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType); int * addr = (int *)MessageBoxA; //保存函数的入口地址 int * myaddr = (int *)MessageBoxProxy; void ThreadProc(void *param);//线程函数 //主函数: BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved){ if(fdwReason==DLL_PROCESS_ATTACH) //进程映射 //每个进程的第一次映射用DLL_PROCESS_ATTACH调用DLL的DllMain函数。 _beginthread(ThreadProc,0,NULL); return TRUE; } //结束进程的函数: void ThreadProc(void *param){ //------------hook api---------------- hMod = GetModuleHandle(NULL); //返回自身应用程序句柄 pDosHeader = (PIMAGE_DOS_HEADER)hMod; pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE *)hMod + pDosHeader->e_lfanew); pOptHeader = (PIMAGE_OPTIONAL_HEADER)&(pNTHeaders->OptionalHeader); //定位Dos头,NT头,可选头 pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)hMod + pOptHeader->DataDirectory[1].VirtualAddress); //导入表ID while(pImportDescriptor->FirstThunk){ //IAT的RVA char * dllname = (char *)((BYTE *)hMod + pImportDescriptor->Name); //被导入的DLL 名称 pThunkData = (PIMAGE_THUNK_DATA)((BYTE *)hMod + pImportDescriptor->OriginalFirstThunk); //IMAGE_THUNK_DATA的RVA int no = 1; while(pThunkData->u1.Function){ //被输入的函数的内存地址 char * funname = (char *)((BYTE *)hMod + (DWORD)pThunkData->u1.AddressOfData + 2); //AddressOfData指向IMAGE_IMPORT_BY_NAME(导入函数名称), //+hMod+2后,到导入的DLL(user32.dll)函数导出表中获取导入函数的地址 PDWORD lpAddr = (DWORD *)((BYTE *)hMod + (DWORD)pImportDescriptor->FirstThunk) +(no-1); //为了下方VirtualQuery穷举每一块内存信息,no++ //修改内存的部分--------------------------------- if((*lpAddr) == (int)addr){ //修改内存页的属性 DWORD dwOLD; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(lpAddr,&mbi,sizeof(mbi)); //获取内存信息 VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE,&dwOLD); //在呼叫处理程序的虚拟位址空间里,变更认可页面区域上的保护, //请求PAGE_READWRITE,保存老的保护方式:dwOLD WriteProcessMemory(GetCurrentProcess(),lpAddr, &myaddr, sizeof(DWORD), NULL); //写入某一进程的内存区域 //恢复内存页的属性---------------------------- VirtualProtect(lpAddr,sizeof(DWORD),dwOLD,0); } no++; pThunkData++; } pImportDescriptor++; } //-------------------HOOK END----------------- } //new messagebox function int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType) { return ((PFNMESSAGEBOX)addr)(NULL, "HOOK成功","success",0); //这个地方可以写出对这个API函数的处理代码 }
此处想补充一下dll文件的生成方式:在vc中新建工程Win32 Dynamic-Link Library,再在该工程中新建文件C++ Source File,代码完成后,compile->build即可,我们写的dll存放于该工程目录下的Debug文件夹中。
开始HOOK:
#include "windows.h" #include "tlhelp32.h" #include #pragma comment(lib,"th32.lib") const char *pkill="dll3.dll";//DLL文件的路径 //这个路径很有意思,这个路径是相对于目标进程的,而不是自身进程。 //所以要嘛写成绝对路径,要嘛写成相对于目标进程的相对路径。 //如果写成相对于自身的路径就要麻烦了,本程序就找不到DLL文件了。 char *prosess="yuan.exe";//要注入的进程名(目标进程名) int main(){ HANDLE hSnap;//获取进程信息 HANDLE hkernel32;//被注入进程的句柄 PROCESSENTRY32 pe;//存放进程信息和调用成员输出进程信息的结构体 BOOL bNext;//是否还有下一个进程 HANDLE hToken; TOKEN_PRIVILEGES tp;//包括LUID和特权的属性的结构体 LUID Luid;//locally unique identifier,保证局部唯一 LPVOID p; FARPROC pfn; if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken)){ //打开与进程相关联的访问令牌 return 1; } if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&Luid)){ //查看系统权限的特权值:SE_DEBUG_NAME,存在Luid中 return 1; } tp.PrivilegeCount = 1; //指定特权数组的个数:1 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //特权数组的类型:特权启用 tp.Privileges[0].Luid = Luid; //局部唯一 if (!AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL)){ //该函数启用或禁止指定访问令牌的特权 return 1; } pe.dwSize = sizeof(pe); //结构体大小 hSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //通过获取进程信息为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程建立一个快照 bNext=Process32First(hSnap, &pe); //获得第一个进程的句柄 while(bNext) { if(!stricmp(pe.szExeFile,prosess)){ //该进程的可执行文件名称是否是我们需要的 process hkernel32=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION,1,pe.th32ProcessID); //如果两者一样,打开该进程 break; } bNext=Process32Next(hSnap, &pe); //不一样则寻找下一个 } CloseHandle(hSnap); p=VirtualAllocEx(hkernel32,NULL,strlen(pkill),MEM_COMMIT,PAGE_R 4000 EADWRITE); //在指定进程的虚拟空间保留或提交内存区域 WriteProcessMemory(hkernel32,p,pkill,strlen(pkill),NULL); //将我们的dll写入该进程内存 pfn=GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"); //获取 kernel32.dll中的 LoadLibraryA(),用以加载我们的dll CreateRemoteThread(hkernel32,NULL,0,(LPTHREAD_START_ROUTINE)pfn,p,NULL,0); //pfn在CreateRemoteThread类型为:LPTHREAD_START_ROUTINE return 0; }
效果截图:
需要注意的是,在hook过程中,原函数不要关闭噢,否则就没有该进程了。
相关文章推荐
- RH413企业安全加固 第3章 管理软件包安装
- 月光博客: 个人用户如何安全地选择软件
- 数据库 软件安全测试之SQL注入
- CWS(美国国土安全部下属的软件保证项目)与SANS(权威安全培训组织)联合编制的最危险的25个编程错误
- 公共场所安全蹭网andwifi热点软件构建安全网络!
- 安全软件的短信拦截
- 软件安全测试系列视频
- 软件漏洞---安全问题的根源
- Symbian 应用软件开发、测试与 S60 平台安全常见问题问答
- Ubuntu 软件安装、查找、卸载--apt-get、apt-cache命令安全
- Android软件安全开发实践(下)
- 重构:提升软件质量,单元测试:为重构提供安全保障
- 安全即时通信软件简介
- 宽带卫士2.0|电信出安全软件
- 飞速文件安全同步软件的实时加密技术
- 安全软件和互联网应用软件的监管
- 对Windows安全软件的思考
- 关于常用IM 即时通讯软件的安全问题
- 微软软件实现技术授课系列内容之四:编写安全的软件
- Seafile 是一款安全、高性能的开源网盘(云存储)软件