rootkit hook之[三] inline hook

简单linux 下 x64任意地址的inlinehook 相对主流工具frida,更加快速的inlinehook,代码简单,可以针对性进行修改 阅读详情
 作 者: combojiang
时 间: 2008-01-30,17:27
链 接: http://bbs.pediy.com/showthread.php?t=59127

最近为了写好rootkit inline hook篇,特意A了著名的流氓软件(cdnprot.sys),这个文件很庞大,有152k之多, 花费了我好几个晚上的时间,让我少看好多集的电视剧《闯关东》,在这个软件里面用了很多好的技术,不管怎么说,技术本身是无辜的,由于我们今天谈论的主题是Inline hook,因此今天只是带领大家看看他是怎样使用inline hook这项技术的。今天是一年一度的小年,发表此篇,作为对大家的小年献礼吧,顺祝大家小年好。

关于什么是inline hook.,这些基本概念,我们就不在这里说了,大家可以google下。
对于ring3下的inline hook使用起来非常的方便,也非常简单。但是到了ring0,inline hook就麻烦些,搞不好就出现了bsod.    ,我们今天讲的是内核中的inline hook。这个技术,在这个流氓软件中应用的比较稳定。我们就来看看它是怎么用的。

先谈谈思路:

1.  Hook之前的准备工作之一。
在这个软件中,总共hook了15个native api 函数。他们分别是:
ZwOpenKey , ZwClose, ZwQueryValueKey, ZwDeleteKey, ZwSetValueKey, ZwCreateKey,
ZwDeleteValueKey. ZwEnumerateValueKey,ZwRestoreKey, ZwReplaceKey, ZwTerminateProcess, ZwSetSecurityObject, ZwCreateThread, ZwTerminateThread, ZwQuerySystemInformation.

这15个函数中,包括2个未公开的函数,ZwCreateThread, ZwTerminateThread,这两个函数,需要我们从ntdll.dll的导出表中找到。另外,所有的native api函数的最终实现都是在ntoskrnl模块中,所以,我们使用ZwQuerySystemInformation的0B号功能,找出ntoskrnl模块的内存加载区间,然后逐个判断ssdt表中这些要hook的函数地址,是否在这个区间内。确保我们是第一个吃螃蟹的人。呵呵。

2.  Hook之前准备工作之二:
1)一个全局函数表 ,保存这15个要hook的函数的原始地址。
这个表起始地址位于:.data:00036860 ,终止于:data:0003689C 共60字节
2)一个hook 的函数地址表,分别对应于要hook的15个函数的跳转。
这个表起始地址位于:.data:00034E98
.data:00034E98 off_34E98        dd offset sub_1EEA8    
.data:00034E9C                 dd offset sub_1EE82
.data:00034EA0                 dd offset sub_1EF82
.data:00034EA4                 dd offset sub_1EF4A
.data:00034EA8                 dd offset sub_1EF6D
.data:00034EAC                 dd offset sub_1EEC1
.data:00034EB0                 dd offset sub_1EED2
.data:00034EB4                 dd offset sub_1EEF5
.data:00034EB8                 dd offset sub_1EF31
.data:00034EBC                 dd offset sub_1EF18
.data:00034EC0                 dd offset sub_1EF93
.data:00034EC4                 dd offset sub_1EFA8
.data:00034EC8                 dd offset sub_1EFBD
.data:00034ECC                 dd offset sub_1EFE6
.data:00034ED0                 dd offset sub_1EFFF

这15个函数,都是在cdnprot.sys中实现的。

3)一个用于保存函数开头字节的二维数组数据区,数组形式是 array[15][30];
  15个函数,每个函数有30个字节可用。 这30个字节中,首先保存原hook函数开头字节,然后写入0xe9 ,再写入数组当前位置跟原hook函数地址偏移我们已复制出的字节码后的位置之间的相对偏移值。(具体我们要保存原hook函数开头多少字节,代码中有一个算法。)
  这个数组的作用是,当我们hook了函数后,执行完我们的hook函数之后,然后,需要恢复执行原api函数,由于原api函数开头5字节已经被改写,由于函数原开头字节已经保存到相应的数组里,因此这里的作法是,执行这个数组中的机器码,数组机器码执行到最后,会跳转到原hook函数某个偏移位置,继续执行。

3.  Inline hook
1)  IoAllocateMdl ,分配一个mdl,将要hook的函数映射进去。
2)  MmProbeAndLockPages,锁定页面
3)  去掉写保护
4)  保存函数开头机器码到对应的二维数组区,改写开头5个字节,让他跳转到起始地址位于.data:00034E98的跳转表中的对应跳转函数。
5)  恢复写保护
6)  MmUnlockPages
7)  IoFreeMdl


4.  Inline hook后的恢复工作
正如2步骤3)中描述的那样。

代码太多,不在这里贴出了。
Inline hook对应的函数是sub_1F30D,这个函数很庞大。嵌套了n多层。我把逆向的源文件和.idb文件附上。有兴致的可以使用ida5.2看看。

附上一个例子吧:
这个例子是hook了KiInsertQueueApc,由于KiInsertQueueApc没有导出,需要在KeInsertQueueApc中找出来。
#include <ntddk.h> 
#include <ntifs.h>
ULONG g_KiInsertQueueApc;
char g_oricode[8];
ULONG g_uCr0;
char *non_paged_memory;

void WPOFF()
{
   
    ULONG uAttr;
   
    _asm
    {
        push eax;
        mov eax, cr0;
        mov uAttr, eax;
        and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
        mov cr0, eax;
        pop eax;
        cli
    };
   
    g_uCr0 = uAttr; //保存原有的 CRO 屬性
   
}

VOID WPON()
{
   
    _asm
    {
        sti
        push eax;
        mov eax, g_uCr0; //恢復原有 CR0 屬性
        mov cr0, eax;
        pop eax;
    };
   
}

__declspec(naked) my_function_detour_KiInsertQueueApc()
{
  __asm
  {    
    mov edi,edi
    push ebp
    mov  ebp, esp
    push ecx
    mov eax,ecx
    _emit 0xEA
    _emit 0xAA
    _emit 0xAA
    _emit 0xAA
    _emit 0xAA
    _emit 0x08
    _emit 0x00
  }
}

ULONG GetFunctionAddr( IN PCWSTR FunctionName)
{
    UNICODE_STRING UniCodeFunctionName;
    RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
    return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );   

}

//根据特征值,从KeInsertQueueApc搜索中搜索KiInsertQueueApc
ULONG FindKiInsertQueueApcAddress()
{
  char * Addr_KeInsertQueueApc = 0;
  int i = 0;
  char Findcode[] = { 0xE8, 0xcc, 0x29, 0x00, 0x00 };
  ULONG Addr_KiInsertQueueApc = 0;
    Addr_KeInsertQueueApc = (char *) GetFunctionAddr(L"KeInsertQueueApc");
  for(i = 0; i < 100; i ++)
  {
        if( Addr_KeInsertQueueApc[i] == Findcode[0] &&
      Addr_KeInsertQueueApc[i + 1] == Findcode[1] &&
      Addr_KeInsertQueueApc[i + 2] == Findcode[2] &&
      Addr_KeInsertQueueApc[i + 3] == Findcode[3] &&
      Addr_KeInsertQueueApc[i + 4] == Findcode[4] 
      )
    {
      Addr_KiInsertQueueApc = (ULONG)&Addr_KeInsertQueueApc[i] + 0x29cc + 5;
      break;
    }
  }
  return Addr_KiInsertQueueApc;
}

VOID DetourFunctionKiInsertQueueApc()
{

  char *actual_function = (char *)g_KiInsertQueueApc;
  unsigned long detour_address;
  unsigned long reentry_address;
  KIRQL oldIrql;
  int i = 0;

  char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90 };

  reentry_address = ((unsigned long)g_KiInsertQueueApc) + 8; 

  non_paged_memory = ExAllocatePool(NonPagedPool, 256);
  
  for(i=0;i<256;i++)
  {
    ((unsigned char *)non_paged_memory)[i] = ((unsigned char *)my_function_detour_KiInsertQueueApc)[i];
  }

  detour_address = (unsigned long)non_paged_memory;
  
  *( (unsigned long *)(&newcode[1]) ) = detour_address;

  for(i=0;i<200;i++)
  {
    if( (0xAA == ((unsigned char *)non_paged_memory)[i]) &&
      (0xAA == ((unsigned char *)non_paged_memory)[i+1]) &&
      (0xAA == ((unsigned char *)non_paged_memory)[i+2]) &&
      (0xAA == ((unsigned char *)non_paged_memory)[i+3]))
    {
      *( (unsigned long *)(&non_paged_memory[i]) ) = reentry_address;
      break;
    }
  }


    oldIrql = KeRaiseIrqlToDpcLevel();
  for(i=0;i < 8;i++)
  {
    g_oricode[i] = actual_function[i];
    actual_function[i] = newcode[i];
  }
    KeLowerIrql(oldIrql);
}

VOID UnDetourFunction()
{
    char *actual_function = (char *)g_KiInsertQueueApc;
  KIRQL oldIrql;
  int i = 0;
  
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();

  for(i=0;i < 8;i++)
  {
    actual_function[i] = g_oricode[i];
  }
    KeLowerIrql(oldIrql);
    WPON();
  ExFreePool(non_paged_memory);
}

VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
  DbgPrint("My Driver Unloaded!");
  UnDetourFunction();
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
  DbgPrint("My Driver Loaded!");
  theDriverObject->DriverUnload = OnUnload;
    
    g_KiInsertQueueApc = FindKiInsertQueueApcAddress();
  DetourFunctionKiInsertQueueApc();

  return STATUS_SUCCESS;
}

补充: 实际应用文章,可以参考sudami的 干掉KV 2008, Rising等大部分杀软
上传的附件
文件类型: rarcnnic.rar (2008-01-30 17:27, 505.8 KB, 619 次下载)
用户态rootkit之inline hook 前言Rootkit是我从大一就听说过的技术,不过那个时候几乎是0基础,也完全不懂这是个什么玩意儿,其实到现在我也不懂rootkit是如何修改内核层和隐藏自己的,不过最近在学习用户态的rootkit,倒是了解了一番,做个笔记。 用户态Rootkit的种类首先我了解的用户态的rootkit是分为两种,一种是IAT hook,还有一种就是inline hook。解释一下,rootkit不同于其他恶意代码... 阅读详情

相关推荐

Windows API Hook实战:从Inline Hook原理到C++实现与Detours应用

在Windows系统编程与软件安全领域,API拦截(Hook)是一项核心技术,它允许开发者在函数调用过程中插入自定义代码,实现对系统行为的监控与修改。其原理主要分为修改导入地址表的IAT Hook和直接覆盖函数机器码的Inline Hook两种方式。这项技术的核心价值在于为调试分析、安全监控、性能优化等场景提供了底层解决方案。通过理解内存保护、指令备份、蹦床函数等关键机制,开发者能够构建稳定的拦截系统。在实际工程中,微软Detours库封装了线程安全、指令修复等复杂细节,是生产环境的首选工具。本文以C++实

weixin_33725515的博客 362

Inline Hook IofCallDriver 截获所有IRP

<br />前段时间搞了一些Inline HOOK API的demo,例如对NtQueryDirectoryFile Inline HOOK 进行文件的隐藏,(恰好NtQueryDirectoryFile 在SSDT有导出,也可以采用改SSDT来实现HOOK.,只不过Inline HOOK 隐蔽性好点).而NtQueryDirectoryFile是调用IofCallDriver的(我猜的),那么HOOK IofCallDriver过滤掉关于MajorFunction == IRP_MJ_QUERY_INFO

Rootkit ﹏ 1063

Rootkit端口隐藏技术_rootkithook_hook_rootkit_creature2ka_隐藏驱动

ROOTKIT 利用hook技术可以隐藏指定的端口 需要以驱动加载的形式把hook加载进内核 这里利用了insdrv工具

emit指令详解

1.编译器不认识的指令,拆成机器码来写。 2.插入垃圾字节来反跟踪,又称花指令。 用emit就是在当前位置直接插入数据(实际上是指令),一般是用来直接 插入汇编里面没有的特殊指令,多数指令可以用asm内嵌汇编来做,没有 必要用emit来做,除非你不想让其它人看懂你的代码。 直接插入数据,而不是汇编的助记符 和嵌入式编程的db,dw效果相同 ...

weixin_33726943的博客 1079

ROS2 DDS中间件(图文并茂+超详细)

DDS 的目标场景在端上,致力于使端上的应用可以更容易的进行通信,由于它的完全分布式架构,可以方便的将端上的应用拆分为多进程架构,从而提高端的容错能力。从产品定位角度来讲,它和 Chromium 中的 mojo 都是端上的通信中间件,只不过 mojo 不强调分布式,内部集成了更多的特定于端上的机制,比如句柄的传输,消息的缓存等。但由于 mojo 生于 Chromium,目前官方并没有把它独立出来,所以用起来比较不方便。而 DDS 或许可以在简单的场景下作为 mojo 的替代品。

weixin_39939185的博客 5281

详细介绍:国产操作系统银行麒麟V10的下载和安装

银河麒麟是由。银河麒麟已经发展为银河麒麟服务器操作系统、桌面操作系统、嵌入式操作系统、麒麟云、操作系统增值产品为代表的产品线。为攻克中国软件核心技术“卡脖子”的短板,银河麒麟建设自主的开源供应链,发起中国首个开源桌面操作系统根社区openKylin,银河麒麟操作系统以openKylin等自主根社区为依托,发布最新版本。

lz17267861157的博客 1万+

emit指令分析

emit指令的作用: 编译器不认识的指令,拆成机器码来写。 插入垃圾字节来反跟踪,又称花指令。 用emit就是在当前位置直接插入数据(实际上是指令),一般是用来直接插入汇编里面没有的特殊指令,多数指令可以用asm内嵌汇编来做,没有必要用emit来做,除非你不想让其它人看懂你的代码。 _emit是伪指令 一个简单的例子 int main() { __asm{ _em...

Flyour的博客 7572

Rider高效调试UE引擎:无需编译源码的符号配置指南

本文提供了一份详尽的Rider高效调试UE引擎指南,核心在于无需编译源码即可配置调试符号。通过Epic启动器下载官方PDB文件,并在Rider中正确配置外部符号服务器路径,开发者能在10分钟内实现对引擎内部代码(如AActor::Tick)的源码级断点调试、变量查看和调用堆栈分析,极大提升问题排查效率。

weixin_29011239的博客 340

linux kernel 5.0 inline hook框架

linux kernel inline hook

qq_42931917的博客 1687

DAIC-WOZ数据集文件结构详解:CLNF特征文件、音频转录与PHQ8评分全解读

本文深入解析DAIC-WOZ数据集的文件结构,重点介绍CLNF特征文件、音频转录与PHQ8评分的详细内容。通过多模态数据处理实战指南,帮助研究者高效利用这一抑郁分析领域的重要资源,掌握面部动作单元、声学特征和文本转录的科学解读与应用技巧。

weixin_29159711的博客 183

SAP FICO应付票据平台开发说明书(包括测试样例、程序代码仅作参考,不保证一定可以运行)

SAP FICO应付票据平台开发说明书(包括测试样例、程序代码仅作参考,不保证一定可以运行)

我好像病了的博客 378

Rootkit hook之[三] Inline Hook

标 题: 【原创】rootkit hook之[三] inline hook作 者: combojiang 时 间: 2008-01-30,17:27:57 链 接: http://bbs.pediy.com/showthread.php?t=59127 最近为了写好rootkit inline hook篇,特意A了著名的流氓软件(cdnprot.sys),这个文件很庞大,有152k

ccx_john的专栏 737

硬方案——几种实用的恒流源电路设计方案,敬请收藏(运放、三极管在手,让你玩出多种花样)

0 引言 我们在信号测量、供电等应用场景时常会涉及到使用恒流源,以前觉得恒流源挺神奇的,研究了下实现方案,其实也没有多么高深(这里讨论的仅限于用在信号测量中的小电流恒流源设计),这里给出几个实用的恒流源电路设计方案。 1 恒流源电路设计 (1)使用三极管搭建的恒流源 (2)使用运放搭建的恒流源 (3)使用恒流二极管搭建的恒流源 pt100恒流源测温电路图_电子技术_电工之家 ...

数字世界 万物互联 9524

【原创】rootkit hook之[三] inline hook

标 题: 【原创】rootkit hook之[三] inline hook 作 者: combojiang 时 间: 2008-01-30,17:27:57 链 接: http://bbs.pediy.com/showthread.php?t=59127 最近为了写好rootkit inline hook篇,特意A了著名的流氓软件(cdnprot.sys),这个文件很庞大,有152k之

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 878

【Claude Code的Harness Engineering实现】:06-记忆系统(Memory)

记忆系统是Claude Code实现跨会话持久化和上下文保持的核心组件。它分为短期记忆(当前会话的对话历史)和长期记忆(跨会话保留的结构化信息),通过多层级的文件系统实现灵活的记忆管理。

rengang66的博客 240

交换机四种光互联技术:OIO、OBO、NPO与CPO

在过去几十年里,数据中心交换机主要依赖电信号通过铜线进行数据传输。然而,随着数据传输速率从100Gbps向400Gbps、800Gbps甚至1.6Tbps迈进,传统电互联(Electrical Input & Output, EIO)面临三大瓶颈:信号衰减、功耗激增和空间限制。例如,高速信号在长距离铜线传输中会产生严重的信号失真,迫使设计者加入数字信号处理器(DSP)来补偿信号衰减,这进一步推高了功耗和成本。此外,传统可插拔光模块的体积较大,限制了端口密度,难以满足现代数据中心对高带宽密度的需求。

网络技术联盟站 3127

rootkit应用之[三] inline hook

标 题: rootkit应用之[三] inline hook作 者: combojiang时 间: 2008-01-30,17:27链 接: http://bbs.pediy.com/showthread.php?t=59127最近为了写好rootkitinlinehook篇,特意A了著名的流氓软件(cdnprot.sys),这个文件很庞大,有152k之多,花费了我好几个晚上的时间,让我...

weixin_30359021的博客 112

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

基于CallStack的反Rootkit HOOK检测

Anti-Rootkit目前扫描Hook的方法主要有以下几种:   1.对抗inline -hook ,IAT/EAT Hook   Anti-Rootkit使用读取磁盘上系统文件并将之进行map\重定位后,同内存中的代码进行对比的方法来检测inline hook(或EAT/IAT HOOK,后同),类似的工具例如Rootkit Unhooker, gmer, Icesword等等。

1553

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

基于CallStack的Anti-Rootkit HOOK检测思路

基于CallStack的Anti-Rootkit HOOK检测思路:MJ00112007-11-2th_decoder@126.comAnti-Rootkit目前扫描Hook的方法主要有以下几种:1.对抗inline -hook ,IAT/EAT HookAnti-Rootkit使用读取磁盘上系统文件并将之进行map/重定位后,同内存中的代码进行对比的方法来检测inline hook(或EAT/I

1730

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【解读黑客】何为Rootkit?

1、何为Rootkit?(结合AIDS加深理解) Rootkit自身也是木马后门或恶意程序的一类,只是,它很特殊,为什么呢?因为,你无法找到它。 正如自然界的规则一样,最流行的病毒,对生物的伤害却是最小的,例如一般的感冒,但是最不流行的病毒,却是最夺命的。Rootkit木马就是信息世界里的 AIDS(爱滋病),一旦感染,就难以用一般手段消灭了,因为它和自然界里的同类做的事情一样,破坏了系统...

茗染云华 荆挑赋樱 1875

高级Linux Kernel Inline Hook技术分析与实现

[目录] 1. 简述 2. 更改offset实现跳转 3. 补充 4. 如何查杀 5. 实例 一、简述 目前流行和成熟的kernel inline hook技术就是修改内核函数的opcode,通过写入jmp或 push ret等指令跳转到新的内核函数中,从而达到修改或过滤的功能。这些技术的共同点就 是都会覆盖原有的指令,这样很容易在函数中通过查找jmp,push ret等指令来...

lionzl的专栏 1040

linux 进程 inline hook,高级Linux Kernel Inline Hook技术分析与实现 -电脑资料

==Ph4nt0m Security Team==Issue 0x03, Phile #0x03 of 0x07|=---------------------------------------------------------------------------=||=--------------=[ 高级Linux Kernel Inline Hook技术分析与实现 ]=----------...

weixin_29479863的博客 237
上一篇: RootKit hook之[二] SSDT hook
下一篇: rootkit hook之[四]-- IDT Hook
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值