Windows Dll注入与API HOOK
DLL注入:
1. 使用注册表注入dll
HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Windows\AppInit_DLLs
AppInit_Dlls中设置待注入的dll绝对路径
LoadAppInit_Dlls值设为1
2. 使用Windows挂钩注入dll
需要使用SetWindowsHookEx函数,MSDN定义如下:
HHOOK WINAPI SetWindowsHookEx(
_In_ int idHook,
_In_ HOOKPROC lpfn,
_In_ HINSTANCE hMod,
_In_ DWORD dwThreadId
);
第一个参数为挂钩类型;
第二个参数为一个函数地址,即挂钩类型事件发生时,系统应该调用的函数;
第三个参数标识一个dll,这个dll中包含第二个参数表示的函数;
第四个参数表示要给哪个线程挂钩,0表示所有运行线程
以下给出一个示例:
HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL;
static HHOOK hhookSysMsg;
hinstDLL = LoadLibrary(TEXT("c:\\myapp\\sysmsg.dll"));
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc");
hhookSysMsg = SetWindowsHookEx(
WH_SYSMSGFILTER,
hkprcSysMsg,
hinstDLL,
0);
可以使用UnhookWindowsHookEx取消挂钩:
BOOL WINAPI UnhookWindowsHookEx(
_In_ HHOOK hhk
);
3. 使用远程线程注入dll
Dll注入的本质即让目标进程中的一个线程通过LoadLibrary()加载待注入dll文件。
通常情况下,无法控制目标进程线程,此时可以创建一个线程了实现上述目的,CreateRemoteThread便提供了此功能。
HANDLE WINAPI CreateRemoteThread(
_In_ HANDLE hProcess,
_In_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_ LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_ LPDWORD lpThreadId
);
hProcess表示待注入的目标进程;
lpStartAddress表示线程函数,此处设置为LoadLibrary();
lpParameter表示传递给线程函数的参数,此时设置为待注入的dll文件绝对路径。
使用CreateRemoteThread具体注入过程如下:
(1) 使用VirtualAllocEx在远程进程中申请一块内存空间;
(2) 使用WriteProcessMemory将Dll路径名复制到(1)中申请的地址;
(3) 使用GetProcAddress获取LoadLibraryW或LoadLibraryA的实际地址;
(4) 使用CreateRemoteThread在远程进程中创建新的线程,新线程调用LoadLibrary,并在参数中传入(1)中申请的内存地址,此时dll文件已经注入到远程线程,DllMain将执行我们设计的代码。
此时远程线程中保留一块申请的内存空间,需要对其进行释放:
(5) 使用VirtualFreeEx释放(1)中申请的内存;
(6) 使用GetProcAddress获取FreeLibrary函数实际地址;
(7) 使用CreateRemoteThread创建新的线程,调用FreeLibrary,参数传入已注入Dll的HMODULE.
4. 使用木马dll注入dll
将进程需要加载的dll文件替换掉,实现dll劫持。
例如,进程需要使用lpk.dll,通过伪造lpk.dll文件,利用windows应用程序加载dll的顺序,让其优先加载伪造的lpk.dll文件。
5. 把dll作为调试器注入
(1) DebugActiveProcess(pid)附加进程;
(2) Debug循环函数:WaitForDebugEvent等待调试事件,针对不同类型进行处理;
(3) ReadProcessMemory, WriteProcessMemory操作目标进程,钩取指定API
6. 使用CreateProcess注入代码
该方法用于向子进程注入代码:
(1) 创建子进程并挂起;
(2) 获取主线程内存地址;
(3) 保存主线程起始地址指令;
(4) 插入指令,调用LoadLibrary加载dll
(5) 子进程恢复运行;
(6) 执行插入的指令;
(7) 恢复原指令,按照原来的逻辑继续执行。
API 拦截:
1. 通过覆盖代码拦截API
(1) 获取待拦截函数地址;
(2) 保存该函数初始几个字节指令;
(3) 使用JMP替换这些指令,让其跳转到自定义的函数中,需要注意的是,自定义函数需与原函数具有相同的签名,相同的参数,相同的返回值,相同的调用约定;
(4) 程序调用被拦截函数时,将跳转到自定义函数中执行;
(5) 执行完毕后,将保存的原指令恢复到起始地址,调用函数让其按照原来的逻辑执行。
2. 通过修改IAT拦截API
每一个导入的dll文件对应一个IMAGE_IMPORT_DESCRIPTOR结构:
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
} DUMMYUNIONNAME;
DWORD TimeDateStamp; // 0 if not bound,
// -1 if bound, and real date\time stamp
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)
DWORD ForwarderChain; // -1 if no forwarders
DWORD Name;
DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
其中成员变量FirstThunk指向一个IMAGE_THUNK_DATA结构体数组,数组中每一项对应一个导入函数:
typedef struct _IMAGE_THUNK_DATA32 {
union {
DWORD ForwarderString; // PBYTE
DWORD Function; // PDWORD
DWORD Ordinal;
DWORD AddressOfData; // PIMAGE_IMPORT_BY_NAME
} u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA;
typedef PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA;
因此,IAT HOOK的主要思路为:
(1) 遍历IMAGE_IMPORT_DESCRIPTOR数组,找到name为需要hook的dll;
(2) 遍历FirstThunk指向的IMAGE_THUNK_DATA,判断Function是否为待hook的API,若是,则替换为新的API.
以下是《Windows核心编程》中作者给出的实现函数:
void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, //被调模块
PROC pfnCurrent, //待HOOK原函数
PROC pfnNew, //替换新函数
HMODULE hmodCaller //调用新函数的模块
) {
// Get the address of the module's import section
ULONG ulSize;
// An exception was triggered by Explorer (when browsing the content of
// a folder) into imagehlp.dll. It looks like one module was unloaded...
// Maybe some threading problem: the list of modules from Toolhelp might
// not be accurate if FreeLibrary is called during the enumeration.
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = NULL;
__try {
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData(
hmodCaller, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
}
__except (InvalidReadExceptionFilter(GetExceptionInformation())) {
// Nothing to do in here, thread continues to run normally
// with NULL for pImportDesc
}
if (pImportDesc == NULL)
return; // This module has no import section or is no longer loaded
// Find the import descriptor containing references to callee's functions
for (; pImportDesc->Name; pImportDesc++) {
PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name);
if (lstrcmpiA(pszModName, pszCalleeModName) == 0) {
// Get caller's import address table (IAT) for the callee's functions
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)
((PBYTE) hmodCaller + pImportDesc->FirstThunk);
// Replace current function address with new function address
for (; pThunk->u1.Function; pThunk++) {
// Get the address of the function address
PROC* ppfn = (PROC*) &pThunk->u1.Function;
// Is this the function we're looking for?
BOOL bFound = (*ppfn == pfnCurrent);
if (bFound) {
if (!WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,
sizeof(pfnNew), NULL) && (ERROR_NOACCESS == GetLastError())) {
DWORD dwOldProtect;
if (VirtualProtect(ppfn, sizeof(pfnNew), PAGE_WRITECOPY,
&dwOldProtect)) {
WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,
sizeof(pfnNew), NULL);
VirtualProtect(ppfn, sizeof(pfnNew), dwOldProtect,
&dwOldProtect);
}
}
return; // We did it, get out
}
}
} // Each import section is parsed until the right entry is found and patched
}
}
Windows Dll注入与API HOOK相关推荐
- Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术
catalogue 1. 引言 2. 使用注册表注入DLL 3. 使用Windows挂钩来注入DLL 4. 使用远程线程来注入DLL 5. 使用木马DLL来注入DLL 6. 把DLL作为调试器来注入 ...
- CFF Explorer实现Windows 7下API HOOK
关于API HOOK,就是截获API调用的技术,在对一个API调用之前先执行自己设定的函数,根据需要可以再执行缺省的API或者进行其他处理,假设如果想截获一个进程对网络的访问,一般是几个socket ...
- redistemplate注入为null_Windows DLL 注入技术
Windows DLL 注入技术 本文主要介绍四种常见的 Windows DLL 注入技术. 分别为全局钩子.远线程钩子.突破 SESSION 0 隔离的远线程注入和 APC 注入. 全局钩子注入 W ...
- API hook原理和实例快速入门(inline hook),以dll线程注入方式使用(win7-64bit)
一个完整的hook,如果hook程序是以dll形式生成的,是分两步:1.完成dll本身的设计和生成,2.完成dll注入程序的设计和生成 本文完成第一步. 第二步在http://blog.csdn.ne ...
- 2020-11-23(Windows系统的dll注入 )
一.什么是dll注入 在Windows操作系统中,运行的每一个进程都生活在自己的程序空间中(保护模式),每一个进程都认为自己拥有整个机器的控制权,每个进程都认为自己拥有计算机的整个内存空间,这些假象都 ...
- Windows核心编程_远线程方式实现Dll注入
之前有介绍过HOOK的方式注入,这次介绍以其它方式注入,而无须HOOK,要知道在Windows这个浩荡的海洋里,API就是宝藏,找到足够多的宝藏那么你就是海贼王~! 实现思路如下: 首先打开一个进程的 ...
- DELPHI 键盘HOOK,DLL注入,带窗口DLL注入及释放
-----------DLL的创建退出过程---------- 新建的DLL内 procedure DllEnterProc(reason:integer); begin case reason of ...
- Windows注入与拦截(3) -- 使用钩子方式完成DLL注入
一. 钩子技术介绍 前面介绍了< Windows注入与拦截(2) – 使用注册表方式完成DLL注入>,本文介绍使用钩子的方式将DLL注入到进程的地址空间中. Windows提供了3个API ...
- Windows 钩子,基本的dll注入
Windows操作系统是基于钩子完成的消息传递与用户交互,它以事件驱动的方式运行.每一个窗口都拥有自己的消息队列,当外部设备触发消息时,消息被发送到系统消息队列,再有操作系统安排将消息发送到特定进程上 ...
最新文章
- Sharding-Jdbc 实现读写分离 + 分库分表,写得太好了!
- 5G改变物联网解决方案的6种方式
- mysql实战33 | 我查这么多数据,会不会把数据库内存打爆?
- yum 安装 phpmyadmin
- gojs 部分功能实现
- 区域卫生数据用于临床疗效分析的可用性研究
- C语言以数据块的形式读写文件
- 第四周 项目中的白盒测试
- mysql如何从两个表取出内容_如何从mysql中的两个表中获取数据?
- java如何防止sql注入
- 利用DirectoryEntry获取域内计算机以及共享资源
- Linux基础知识练习题
- Vista 自动激活工具(最新 最权威 所有版本 可升级)
- maya中英文对照_maya2011中英文对照表
- ESP32设备驱动-MicroSD Card驱动
- 10a大电流稳压芯片_高压dc48v降12v10a大电流降压ic详解
- 阀门定位器的三种维护方式
- fk算法绘制层状介质理论地震图
- Unitary matrix 幺正矩阵
- erp5开源制造业erp主要业务会计分录处理
热门文章
- 【SQL开发实战技巧】系列(九):一个update误把其他列数据更新成空了?Merge改写update!给你五种删除重复数据的写法!
- GCC编译器——GCC编译器的简介
- 解决:pip 下载太慢以及超时(timeout)
- ArcGIS Engine怎样快速合并一个图层的所有线面要素
- python字典对象的方法返回字典的值列表_python对象转字典的两种实现方式示例
- Linux下gcc交叉编译工具链制作实例详细总结(附下载地址)
- 蚂蚁课堂史上最全SpringBoot视频教程
- 常见代码审计工具,代码审计为什么不能只用工具?
- 大学c语言程序设计期末试题,北京理工大学《C语言程序设计》期末试题.pdf
- 深入浅出MFC-学习笔记 Day 2