您的位置: 首页> 知识 > 正文

驱动开发:内核LoadLibrary实现DLL注入

2023-06-13 09:33:26 来源:博客园

远程线程注入是最常用的一种注入技术,在应用层注入是通过CreateRemoteThread这个函数实现的,该函数通过创建线程并调用 LoadLibrary动态载入指定的DLL来实现注入,而在内核层同样存在一个类似的内核函数RtlCreateUserThread,但需要注意的是此函数未被公开,RtlCreateUserThread其实是对NtCreateThreadEx的包装,但最终会调用ZwCreateThread来实现注入,RtlCreateUserThreadCreateRemoteThread的底层实现。

基于LoadLibrary实现的注入原理可以具体分为如下几步;

1.调用AllocMemory,在对端应用层开辟空间,函数封装来源于《内核远程堆分配与销毁》章节;2.调用MDLWriteMemory,将DLL路径字符串写出到对端内存,函数封装来源于《内核MDL读写进程内存》章节;3.调用GetUserModuleAddress,获取到kernel32.dll模块基址,函数封装来源于《内核远程线程实现DLL注入》章节;4.调用GetModuleExportAddress,获取到LoadLibraryW函数的内存地址,函数封装来源于《内核远程线程实现DLL注入》章节;5.最后调用本章封装函数MyCreateRemoteThread,将应用层DLL动态转载到进程内,实现DLL注入;

总结起来就是首先在目标进程申请一块空间,空间里面写入要注入的DLL的路径字符串或者是一段ShellCode,找到该内存中LoadLibrary的基址并传入到RtlCreateUserThread中,此时进程自动加载我们指定路径下的DLL文件。


(资料图片)

注入依赖于RtlCreateUserThread这个未到处内核函数,该内核函数中最需要关心的参数是ProcessHandle用于接收进程句柄,StartAddress接收一个函数地址,StartParameter用于对函数传递参数,具体的函数原型如下所示;

typedef DWORD(WINAPI* pRtlCreateUserThread)(    IN HANDLE                    ProcessHandle,          // 进程句柄    IN PSECURITY_DESCRIPTOR      SecurityDescriptor,    IN BOOL                      CreateSuspended,    IN ULONG                     StackZeroBits,    IN OUT PULONG                StackReserved,    IN OUT PULONG                StackCommit,    IN LPVOID                    StartAddress,          // 执行函数地址 LoadLibraryW    IN LPVOID                    StartParameter,        // 参数传递    OUT HANDLE                   ThreadHandle,          // 线程句柄    OUT LPVOID                   ClientID    );

由于我们加载DLL使用的是LoadLibraryW函数,此函数在运行时只需要一个参数,我们可以将DLL的路径传递进去,并调用LoadLibraryW以此来将特定模块拉起,该函数的定义规范如下所示;

HMODULE LoadLibraryW(  [in] LPCWSTR lpLibFileName);

根据上一篇文章中针对注入头文件lyshark.h的封装,本章将继续使用这个头文件中的函数,首先我们实现这样一个功能,将一段准备好的UCHAR字符串动态的写出到应用层进程内存,并以宽字节模式写出在对端内存中,这段代码可以写为如下样子;

// 署名权// right to sign one"s name on a piece of work// PowerBy: LyShark// Email: me@lyshark.com#include "lyshark.h"// 驱动卸载例程VOID UnDriver(PDRIVER_OBJECT driver){DbgPrint("Uninstall Driver \n");}// 驱动入口地址NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){DbgPrint("Hello LyShark \n");DWORD process_id = 7112;DWORD create_size = 1024;DWORD64 ref_address = 0;// 分配内存堆 《内核远程堆分配与销毁》 核心代码NTSTATUS Status = AllocMemory(process_id, create_size, &ref_address);DbgPrint("对端进程: %d \n", process_id);DbgPrint("分配长度: %d \n", create_size);DbgPrint("[*] 分配内核堆基址: %p \n", ref_address);UCHAR DllPath[256] = "C:\\hook.dll";UCHAR Item[256] = { 0 };// 将字节转为双字for (int x = 0, y = 0; x < strlen(DllPath) * 2; x += 2, y++){Item[x] = DllPath[y];}// 写出内存 《内核MDL读写进程内存》 核心代码ReadMemoryStruct ptr;ptr.pid = process_id;ptr.address = ref_address;ptr.size = strlen(DllPath) * 2;// 需要写入的数据ptr.data = ExAllocatePool(PagedPool, ptr.size);// 循环设置for (int i = 0; i < ptr.size; i++){ptr.data[i] = Item[i];}// 写内存MDLWriteMemory(&ptr);Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;}

运行如上方所示的代码,将会在目标进程7112中开辟一段内存空间,并写出C:\hook.dll字符串,运行效果图如下所示;

此处你可以通过x64dbg附加到应用层进程内,并观察内存0000000002200000会看到如下字符串已被写出,双字类型则是每一个字符空一格,效果图如下所示;

继续实现所需要的子功能,实现动态获取Kernel32.dll模块里面LiadLibraryW这个导出函数的内存地址,这段代码相信你可以很容易的写出来,根据上节课的知识点我们可以二次封装一个GetProcessAddress来实现对特定模块基址的获取功能,如下是完整代码案例;

// 署名权// right to sign one"s name on a piece of work// PowerBy: LyShark// Email: me@lyshark.com#include "lyshark.h"// 实现取模块基址PVOID GetProcessAddress(HANDLE ProcessID, PWCHAR DllName, PCCHAR FunctionName){PEPROCESS EProcess = NULL;NTSTATUS Status = STATUS_SUCCESS;KAPC_STATE ApcState;PVOID RefAddress = 0;// 根据PID得到进程EProcess结构Status = PsLookupProcessByProcessId(ProcessID, &EProcess);if (Status != STATUS_SUCCESS){return Status;}// 判断目标进程是32位还是64位BOOLEAN IsWow64 = (PsGetProcessWow64Process(EProcess) != NULL) ? TRUE : FALSE;// 验证地址是否可读if (!MmIsAddressValid(EProcess)){return NULL;}// 将当前线程连接到目标进程的地址空间(附加进程)KeStackAttachProcess((PRKPROCESS)EProcess, &ApcState);__try{UNICODE_STRING DllUnicodeString = { 0 };PVOID BaseAddress = NULL;// 得到进程内模块基地址RtlInitUnicodeString(&DllUnicodeString, DllName);BaseAddress = GetUserModuleAddress(EProcess, &DllUnicodeString, IsWow64);if (!BaseAddress){return NULL;}DbgPrint("[*] 模块基址: %p \n", BaseAddress);// 得到该函数地址RefAddress = GetModuleExportAddress(BaseAddress, FunctionName, EProcess);DbgPrint("[*] 函数地址: %p \n", RefAddress);}__except (EXCEPTION_EXECUTE_HANDLER){return NULL;}// 取消附加KeUnstackDetachProcess(&ApcState);return RefAddress;}VOID Unload(PDRIVER_OBJECT pDriverObj){DbgPrint("[-] 驱动卸载 \n");}NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegPath){DbgPrint("Hello LyShark.com \n");// 取模块基址PVOID pLoadLibraryW = GetProcessAddress(5200, L"kernel32.dll", "LoadLibraryW");DbgPrint("[*] 所在内存地址 = %p \n", pLoadLibraryW);DriverObject->DriverUnload = Unload;return STATUS_SUCCESS;}

编译并运行如上驱动代码,将自动获取PID=5200进程中Kernel32.dll模块内的LoadLibraryW的内存地址,输出效果图如下所示;

实现注入的最后一步就是调用自定义函数MyCreateRemoteThread该函数实现原理是调用RtlCreateUserThread开线程执行,这段代码的最终实现如下所示;

// 署名权// right to sign one"s name on a piece of work// PowerBy: LyShark// Email: me@lyshark.com#include "lyshark.h"// 定义函数指针typedef PVOID(NTAPI* PfnRtlCreateUserThread)(IN HANDLE ProcessHandle,IN PSECURITY_DESCRIPTOR SecurityDescriptor,IN BOOLEAN CreateSuspended,IN ULONG StackZeroBits,IN OUT size_t StackReserved,IN OUT size_t StackCommit,IN PVOID StartAddress,IN PVOID StartParameter,OUT PHANDLE ThreadHandle,OUT PCLIENT_ID ClientID);// 实现取模块基址PVOID GetProcessAddress(HANDLE ProcessID, PWCHAR DllName, PCCHAR FunctionName){PEPROCESS EProcess = NULL;NTSTATUS Status = STATUS_SUCCESS;KAPC_STATE ApcState;PVOID RefAddress = 0;// 根据PID得到进程EProcess结构Status = PsLookupProcessByProcessId(ProcessID, &EProcess);if (Status != STATUS_SUCCESS){return Status;}// 判断目标进程是32位还是64位BOOLEAN IsWow64 = (PsGetProcessWow64Process(EProcess) != NULL) ? TRUE : FALSE;// 验证地址是否可读if (!MmIsAddressValid(EProcess)){return NULL;}// 将当前线程连接到目标进程的地址空间(附加进程)KeStackAttachProcess((PRKPROCESS)EProcess, &ApcState);__try{UNICODE_STRING DllUnicodeString = { 0 };PVOID BaseAddress = NULL;// 得到进程内模块基地址RtlInitUnicodeString(&DllUnicodeString, DllName);BaseAddress = GetUserModuleAddress(EProcess, &DllUnicodeString, IsWow64);if (!BaseAddress){return NULL;}DbgPrint("[*] 模块基址: %p \n", BaseAddress);// 得到该函数地址RefAddress = GetModuleExportAddress(BaseAddress, FunctionName, EProcess);DbgPrint("[*] 函数地址: %p \n", RefAddress);}__except (EXCEPTION_EXECUTE_HANDLER){return NULL;}// 取消附加KeUnstackDetachProcess(&ApcState);return RefAddress;}// 远程线程注入函数BOOLEAN MyCreateRemoteThread(ULONG pid, PVOID pRing3Address, PVOID PParam){NTSTATUS status = STATUS_UNSUCCESSFUL;PEPROCESS pEProcess = NULL;KAPC_STATE ApcState = { 0 };PfnRtlCreateUserThread RtlCreateUserThread = NULL;HANDLE hThread = 0;__try{// 获取RtlCreateUserThread函数的内存地址UNICODE_STRING ustrRtlCreateUserThread;RtlInitUnicodeString(&ustrRtlCreateUserThread, L"RtlCreateUserThread");RtlCreateUserThread = (PfnRtlCreateUserThread)MmGetSystemRoutineAddress(&ustrRtlCreateUserThread);if (RtlCreateUserThread == NULL){return FALSE;}// 根据进程PID获取进程EProcess结构status = PsLookupProcessByProcessId((HANDLE)pid, &pEProcess);if (!NT_SUCCESS(status)){return FALSE;}// 附加到目标进程内KeStackAttachProcess(pEProcess, &ApcState);// 验证进程是否可读写if (!MmIsAddressValid(pRing3Address)){return FALSE;}// 启动注入线程status = RtlCreateUserThread(ZwCurrentProcess(),NULL,FALSE,0,0,0,pRing3Address,PParam,&hThread,NULL);if (!NT_SUCCESS(status)){return FALSE;}return TRUE;}__finally{// 释放对象if (pEProcess != NULL){ObDereferenceObject(pEProcess);pEProcess = NULL;}// 取消附加进程KeUnstackDetachProcess(&ApcState);}return FALSE;}VOID Unload(PDRIVER_OBJECT pDriverObj){DbgPrint("[-] 驱动卸载 \n");}NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegPath){DbgPrint("Hello LyShark.com \n");ULONG process_id = 5200;DWORD create_size = 1024;DWORD64 ref_address = 0;// -------------------------------------------------------// 取模块基址// -------------------------------------------------------PVOID pLoadLibraryW = GetProcessAddress(process_id, L"kernel32.dll", "LoadLibraryW");DbgPrint("[*] 所在内存地址 = %p \n", pLoadLibraryW);// -------------------------------------------------------// 应用层开堆// -------------------------------------------------------NTSTATUS Status = AllocMemory(process_id, create_size, &ref_address);DbgPrint("对端进程: %d \n", process_id);DbgPrint("分配长度: %d \n", create_size);DbgPrint("分配的内核堆基址: %p \n", ref_address);// 设置注入路径,转换为多字节UCHAR DllPath[256] = "C:\\lyshark_hook.dll";UCHAR Item[256] = { 0 };for (int x = 0, y = 0; x < strlen(DllPath) * 2; x += 2, y++){Item[x] = DllPath[y];}// -------------------------------------------------------// 写出数据到内存// -------------------------------------------------------ReadMemoryStruct ptr;ptr.pid = process_id;ptr.address = ref_address;ptr.size = strlen(DllPath) * 2;// 需要写入的数据ptr.data = ExAllocatePool(PagedPool, ptr.size);// 循环设置for (int i = 0; i < ptr.size; i++){ptr.data[i] = Item[i];}// 写内存MDLWriteMemory(&ptr);// -------------------------------------------------------// 执行开线程函数// -------------------------------------------------------// 执行线程注入// 参数1:PID// 参数2:LoadLibraryW内存地址// 参数3:当前DLL路径BOOLEAN flag = MyCreateRemoteThread(process_id, pLoadLibraryW, ref_address);if (flag == TRUE){DbgPrint("[*] 已完成进程 %d 注入文件 %s \n", process_id, DllPath);}DriverObject->DriverUnload = Unload;return STATUS_SUCCESS;}

编译这段驱动程序,并将其放入虚拟机中,在C盘下面放置好一个名为lyshark_hook.dll文件,运行驱动程序将自动插入DLL到Win32Project进程内,输出效果图如下所示;

回到应用层进程,则可看到如下图所示的注入成功提示信息;

关键词:

资讯
业界
企业
骑闻
产品
我国高技术制造业保持较快增长   服务业生产下滑
5月16日,国家统计局新闻发言人、国民经济综合统计司司长付凌晖在国新办4月份国民经济运行情况新闻发布会上表示:总体来看,4月份疫情对经
2022-05-22
唐山曹妃甸推动京津冀协同发展 产业协同转移全面提速
春暖渤海湾,书写新画卷。位于唐山曹妃甸的金隅天坛(唐山)木业科技有限公司的生产车间内一片繁忙景象——铺装、压机、翻板等工作正紧张有序
2022-03-19
石家庄海关共签发RCEP原产地证书864份 货值3.9亿元
自今年1月1日RCEP(《区域全面经济伙伴关系协定》)正式实施以来,截至3月14日,石家庄海关共签发RCEP原产地证书864份,货值3 9亿元。据介绍
2022-03-19
蚌埠海关累计签发RCEP原产地证书35份 涉及金额2583.09万元
在蚌埠海关报关大厅原产地证办理窗口,海关关员仔细核对着递交过来的材料。十分钟后,一份RCEP原产地证书打印盖章后交到了企业业务员手中。
2022-03-19
昆明西山区:“双招双引”推动人才链和产业链融合发展
为激励党员干部在营商环境建设中担当作为,昆明市西山区深入实施人才强区战略和人才领跑工程,建立健全招商引资和招才引资并轨新模式,以产
2022-03-19
绥化望奎以工业化思维为引领 推动肉类加工制造产业腾飞
望奎县以工业化思维为引领,推动全县以生猪为主的肉类加工制造产业一年全面开局、三年基本成势、五年产业腾飞,聚焦五化做强做优肉类加工制
2022-03-19
  中新网海口1月23日电(符宇群)海南省第六届人民代表大会第五次会议23日在海口举行第二次全体会议。海南省人民检察院检察长张毅在作报告
2022-01-24
  中新网太原1月23日电 (高雨晴 冉涌 张鹏宇)记者23日从国网山西省电力公司获悉,该公司冬奥保电应急发电队伍已到达河北张家口赛区,
2022-01-24
  中新网西宁1月23日电 (记者 李江宁)据青海省地震局23日消息,中国地震台网正式测定,北京时间2022年1月23日10时21分,在青海海西州德
2022-01-24
  中新网贵阳1月23日电 (周燕玲)对外开放,是内陆开放型经济试验区贵州正在召开的两会热点词汇,如何拓展海内外“朋友圈”助力贵州经济
2022-01-24
温馨生活好young 厦门推广文旅产品火爆全网
  中新网厦门1月23日电 (记者 杨伏山)“冬日暖阳厦门好young”福建省内宣传推广线下活动22日精彩收官。主办方称,本次活动火爆全网及福
2022-01-24
宁夏非遗传承人:刻刀里的守正创新更有“年味”
  (新春见闻)宁夏非遗传承人:刻刀里的守正创新更有“年味”  中新网银川1月23日电 题:宁夏非遗传承人:刻刀里的守正创新更有“年味
2022-01-24
沧州:8个重大科技专项项目确定 引领经济社会高质量发展
为充分发挥科技在经济社会高质量发展中的引领和支撑作用,沧州市确定8个项目为2021年全市重大科技专项项目。这8个重大科技专项项目分别为:
2022-03-19
  中新网海口1月23日电(王子谦 符宇群)海南省高级人民法院院长陈凤超23日说,2021年海南法院为自贸港建设提供坚强司法保障,全年有效管
2022-01-24
  新华社武汉1月23日电(记者王贤)随着春节假期临近,从广州、深圳等地返回湖北的旅客较多。为此,23日,武汉站、汉口站、襄阳东站、十堰
2022-01-24
  1月22日0—24时,广东省新增本土确诊病例3例和本土无症状感染者1例,均为珠海报告。23日,珠海市疫情防控新闻发布会上,珠海市政府副秘
2022-01-24
青海海西州德令哈市发生3.7级地震
  据中国地震台网正式测定,1月23日11时58分在青海海西州德令哈市发生3 7级地震,震源深度9千米,震中位于北纬38 40度,东经97 35度。
2022-01-24
  北京2022年冬奥会和冬残奥会颁奖花束已于近期完成交付。与传统的鲜切花不同,这些花束全部采用上海市非物质文化遗产“海派绒线编结技艺
2022-01-24
  中新网宿迁1月23日电 (刘林 张华东)核酸检测是当下及时发现潜在感染者、阻断疫情传播的有效方法。23日,记者从宿迁市宿豫区警方获悉
2022-01-24
  记者从天津市人社局获悉,从明天(24日)起,天津2022年度第一期积分落户申报工作正式开始,这是新修订的《天津市居住证管理办法》《天津
2022-01-24
  中新社北京1月23日电 (记者 刘亮)记者23日从中国海关总署获悉,2021年,中国海关组织开展“国门绿盾”专项行动,在寄递、旅客携带物
2022-01-24
  记者从天津市疫情防控指挥部获悉,天津疫情第341—360例阳性感染者基本信息公布。  目前,这20例阳性感染者已转运至市定点医院做进一
2022-01-24
“最美基层民警”武文斌:案子破了最管用
  中新网吕梁1月23日电 题:“最美基层民警”武文斌:案子破了最管用  作者 高瑞峰  同事称他为“拼命三郎”。从警14年,武文斌破
2022-01-24
  据“西安发布”消息,截至2022年1月23日,雁塔区长延堡街道近14天内无新增本地病例和聚集性疫情。根据国务院联防联控机制关于分区分级
2022-01-24
  中新网西宁1月23日电 (记者 孙睿)据青海省地震台网测定,2022年1月23日10点21分(北京时间)在青海省海西州德令哈市(北纬38 44度,东经
2022-01-24
江西南昌:市民赏年画迎新年 书法家挥毫送春联
  (新春见闻)江西南昌:市民赏年画迎新年 书法家挥毫送春联  1月23日,“赏年画过大年”新年画作品联展江西南昌站活动在江西省文化馆
2022-01-24
  中新网成都1月23日电 (祝欢)成都市第十七届人民代表大会第六次会议23日在成都举行,成都市中级人民法院院长郭彦与成都市人民检察院检
2022-01-24
列车临时停车3分钟救旅客
  (新春见闻)列车临时停车3分钟救旅客  中新网广州1月23日电 (郭军 黄伟伟)“车长,车长,4号车厢有位旅客腹涨难忍,身体不舒服”…
2022-01-24
女子背负命案潜逃24年 因涉疫人员核查落网
  中新网湖州1月23日电(施紫楠 徐盛煜 赵学良)1998年7月,犯罪嫌疑人杜某因家庭琐事,用菜刀将自己的弟媳砍伤致死。案发后,她从老家河
2022-01-24
广东“00后”雄狮少年锤炼功夫迎新春
  (新春见闻)广东“00后”雄狮少年锤炼功夫迎新春  中新社广州1月23日电 题:广东“00后”雄狮少年锤炼功夫迎新春  作者 孙秋霞 
2022-01-24
03-19 2022岳阳国际旅游节开幕 特色农产品展销等系列活动目不暇接
2022岳阳国际旅游节开幕 特色农产品展销等系列活动目不暇接
今天,天下洞庭岳阳市君山区第九届良心堡油菜花节暨2022岳阳国际旅游节开幕,菊红、粉红、水红、桃红、紫色、白色等七色组成的4万亩花海在 [详细]
03-19 2022年郴州计划重点推进文旅项目101个 总投资354亿元
2022年郴州计划重点推进文旅项目101个 总投资354亿元
3月16日,我市举行全市文旅项目和城市大提质大融城项目集中开工仪式,市委书记吴巨培宣布项目开工。郴州嘉合欢乐世界、仙福路工地清风徐来 [详细]
03-19 宿州泗县深入推进文旅融合发展 擦亮城市品牌
宿州泗县深入推进文旅融合发展 擦亮城市品牌
近年来,泗县以争创安徽省文化旅游名县为目标,深入推进文旅融合发展,努力擦亮水韵泗州 运河名城城市品牌,全县文化旅游业实现高质量发展 [详细]
03-19 淡季不忘引流 京郊民宿市场有望迎来回暖
淡季不忘引流 京郊民宿市场有望迎来回暖
旅游淡季中的京郊民宿有望成为市场中最先复苏的板块。3月17日,北京商报记者调查发现,虽然正值旅游淡季,且受疫情变化的影响,不过各家民 [详细]
01-24 西安浐灞回应“社区领导怒怼咨询群众”:涉事社区主任已停职
西安浐灞回应“社区领导怒怼咨询群众”:涉事社区主任已停职
西安浐灞回应“一社区领导在市民咨询离市政策时发生争执”事件 涉事社区主任已停职  西部网讯(记者 刘望)日前,网络上流传一条视频 [详细]
01-24 陕西:截至23日12时 西安56.5万大中专学生已离校返家
陕西:截至23日12时 西安56.5万大中专学生已离校返家
1月23日,陕西省举行第45场疫情防控工作发布会,发布会上陕西省教育厅相关负责人通报,陕西全省疫情有效控制后,大中专学校能不能放假 [详细]
01-24 河北魏县发布北京一阳性人员在魏县的主要轨迹
河北魏县发布北京一阳性人员在魏县的主要轨迹
魏县疾病预防控制中心关于紧急寻找丰台区新冠肺炎阳性检测者同时间同空间人员的公告  2022年01月22日,接到邯郸市疾控中心转北京市疾 [详细]