奥黛莉脱壳亚麻籽作用中的汇编指令sysenter是什么作用

HOOK技术主要分为两大类,一是内核层HOOK,一是用户层HOOK!_ce大神吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:19,568贴子:
HOOK技术主要分为两大类,一是内核层HOOK,一是用户层HOOK!收藏
HOOK技术主要分为两大类,一是内核层HOOK,一是用户层HOOK.
用户层HOOK也就是在ring3环境下hook kenerl32.dll、User3.dll、Gui32.dll、Advapi.dll等导出的函数。而内核层HOOK就是HOOK只有ring0级别环境下才能操作写入改变的内核对象,例如SSDT系统服务描述符表等。综合而言,主要有以下9种HOOK技术。(1)消息钩子消息钩子是最常见的钩子之一,例如常见的键盘鼠标钩子,很多木马就是通过消息钩子获取密码的。消息钩子是由Win32子系统提供,用户通过它注册全局钩子。当系统获取某些事件,比如用户按键,键盘driver将扫描码等传入win32k的KeyEvent处理函数,处理函数判断有无相应hook,有则通过回调函数处理。此时,系统取得Hook对象信息,若目标进程没有装载对应的Dll,则装载之。(2)IAT HOOKIAT HOOK[4]是最常见和普遍的HOOK之一。IAT表示导入地址表(Import Address Table),导入函数就是被程序调用但其执行代码又不在程序中的函数,当PE 文件被装入内存的时候,Windows 装载器才将DLL 装入,并将调用导入函数的指令和函数实际所处的地址联系起来(动态连接),这种操作就需要导入表完成。其中导入地址表就指示函数实际地址。程序每个调用的 API 函数地址都保存在 IAT 表中,而每个调用 API 函数的 CALL 指令所使用的地址都是相应函数登记在 IAT 表的地址。IATHOOK原理是在将 IAT 表中的地址换成用户自己的 函数地址,这样每个 API 调用都是先调用用户自己的 函数。在这个函数中我们可以完成函数名称的记录、参数的记录、调用原来的过程,并在返回时记录结果。(3)EAT HOOKEAT HOOK的原理是根据替换 PE 格式导出表中的相应函数来实现的。EAT表示导出地址表(Export Address Table),EAT存在于PE文件中的edata节,保存了可执行文件(如DLL 文件)的导出的可供其他模块来调用的函数和公共变量,包括函数名称和地址等。通过替换Windows 系统某些重要DLL中的输出函数地址,即可实现目标函数的挂接。EAT记录DLL中可供其他程序使用的函数,可执行文件装载时会使用相应DLL的EAT表来初始化IAT表。EAT HOOK原理是通过替换EAT表中的函数地址,使依赖于本DLL的程序得到一个假的地址。(4)SSDT HOOKSSDT是最常见的内核层 HOOK。SSDT的全称是系统服务描述符表(System Services Descriptor Table)。SSDT是关联ring3的Win32 API和ring0的内核API的重要数据结构,它存储着Windows把需要调用的所有内核API地址。SSDT HOOK原理是将内核层 API地址修改为指向其位于Ring0层的驱动入口,这样每次系统执行到这个函数时,都会通过SSDT表将原始调用引向修改后的模块中。(5)IDT HOOKIDT HOOK是Win2000操作系统上常用的一种HOOK。IDT是中断描述表,可以替换其中的中断处理程序。这种方法对于跟踪、分析系统调用来说用的比较多。IDT HOOK的原理是通过替换 IDT表中的 INT 2E 中断,使之指向新的中断服务处理例程来实现的。它首先保存出特定的中断向量中断服务程序(ISR), 然后直接修改该中断向量的ISR为自定义的函数,每当这个中断向量对应的中断产生时,就会调用自定义的函数。由于我们自定义的函数里面执行完我们的功能后再跳转到原ISR处执行。(6)SYSENTRY HOOKSYSENTRY是Windows XP之后的操作系统进入ring0的函数。Win2000中通过 int2e系统调用机制,涉及到的Interrupt/Exception Handler的调用都是通过 call/trap/task这一类的gate来实现的,这种方式会进行栈切换,并且系统栈的地址等信息由TSS提供,可能会引起多次内存访问 (来获取这些切换信息),系统开销较大。SYSENTER通过汇编指令实现快速系统调用机制。SYSENTER HOOK的原理是首先Ntdll 加载相应的请求服务号到EAX 寄存器中,同时EDX 寄存器存贮当前的栈指针ESP,然后Ntdll发出SYSENTER 指令,该指令转移控制权到寄存器IA32_SYSENTER_EIP 存贮的地址中[21],通过修改这个地址,可实现相应的挂接。(7)Inline HOOKinline hook是直接在以前的函数体内修改指令,用一个跳转或者其他指令来实现挂钩的目的。
而普通的hook只是修改函数的调用地址,而不是在原来的函数体里面做修改。Inline hook原理是解析函数开头的几条指令,把他们Copy到数组保存起来,然后用一个调用我们的函数的几条指令来替换,如果要执行原函数,则在我们函数处理完毕,再执行我们保存起来的开头几条指令,然后调回我们取指令之后的地址执行。它需要在程序中嵌入汇编代码(Inline Assembly)以操作堆栈和执行内核API对应的部分汇编指令。(7)OBJECT HOOKOBJECT HOOK是相对于IAT HOOK之类的 API HOOK而言,API HOOK是挂钩应用层函数,而OBJECT HOOK是挂钩内核层函数。其原理与API HOOK类似。(9)IRP HOOKIRP是 I/O request packets,在Windows中几乎所有的I/O都是通过包(packet)驱动的,每个单独的I/O由一个工作命令描述,此命令将会告诉驱动程序需要一些什么操作,并通过I/O子系统跟踪处理过程。这些工作命令就表现为一个个被称为IRP的数据结构。IRP HOOK原理是拦截管理器发向文件或网络系统等驱动程序的IRP。一般通过创建一个上层过滤器设备对象并将之加入系统设备所在的设备堆栈中。也有部分IRP HOOK通过拦截传递IRP请求包的函数IofCallDriver或MajorFunction函数表来实现的。
苏宁易购大神,正品行货+百城半日达,全国联保,服务一站式,全场为你而省!苏宁易购大神,支持货到付款,让您省钱省心!
虽然我看不懂,不过看起来好厉害的样子!楼下队形跟上!
虽然我看不懂,不过看起来好厉害的样子!楼下队形跟上!
虽然我看不懂,不过看起来好厉害的样子!楼下队形跟上!
说了一大堆,我没怎么听懂
不懂这样的十五字够了没
~~~~~~~~~~~~~~~~~~~~~~
虽然我看不懂,不过看起来好厉害的样子!楼下队形跟上!
火钳刘明 不懂这样的十五字够了没 ~~~~~~~~~~~~~~~~~~~~~~
虽然我看不懂,不过看起来好厉害的样子!楼下队形跟上!
「京东」大神全程低价不等待!秒杀天天有,&机&惠难得!上京东买大神,「认真购物,买点好的」
请问ce怎么用啊?为什么我一上游戏就封号啦
我来破坏队形。
看不懂 可是有经验啊
太深奥了 ,,,做伸手党吧
伸手党万岁
请问ce怎么用啊?为什么我一上游戏就封号啦[不高兴]
虽然我看不懂,不过看起来好厉害的样子!楼下队形跟上!
虽然我看不懂,不过看起来好厉害的样子!楼下队形跟上!
勉强能看懂点,
虽然我看不懂,不过看起来好厉害的样子!楼下队形跟上!
        ————
比爱你舒服 。
你们在看什么呢?
虽然我看不懂,不过看起来好厉害的样子!楼下队形跟上!
中文主题曲《奇迹再现》就像阳光穿过黑夜黎明悄悄划过天边谁的身影穿梭轮回间未来的路就在脚下不要悲伤不要害怕充满信心期盼着明天新的风暴已经出现怎么能够停滞不前穿越时空 竭尽全力我会来到你身边微笑面对危险梦想成真不会遥远鼓起勇气坚定向前奇迹一定会出现
虽然我看不懂,不过看起来好厉害的样子!楼下队形跟上!
有没有刷图的东西可以分享一下,这些东西没用。hoOK也要看运行账号吧?你不是超级管理员登陆,权限都没有。
额   --嘿嘿!无聊的一天又将开始,天天开心哦大家!!!小泛路过~-~
虽然我看不懂,不过看起来好厉害的样子!楼下队形跟上!
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或sysenter指令
转自:&&BBS 水木清华站
传统的几类系统调用截获技术
(一)利用sys_call_table[] 接口
sys_call_table是内核导出的符号表,定义了内核中的系统调用接口。下面的LKM例子
可以实现截获系统调用mkdir信息的功能。
extern void* sys_call_table[];
int (*orig_mkdir) (const char *path, mode_t mode) ;
int modified_mkdir (const char *path, mode_t mode)
{&&// You can do anything you
want here …
return orig_mkdir(path, mode) ;
int init_module (void) // 放置钩子
orig_mkdir = sys_call_table[SYS_mkdir] ;
sys_call_table[SYS_mkdir]=modified_
return 0 ;
void cleanup_module (void)&&//
sys_call_table[SYS_mkdir] = orig_
在Linux2.4.18内核以后,sys_call_table不能直接导出。也就是说,在2.4.18之后的内
核版本,无论是入侵检测程序或是入侵过程,上面这个代码在编译加载过程中都会报错
随后,在Phrack的一篇文章中提出了利用中断描述表和/dev/kmem结合,找到sys_call_
table的地址,继而实现对系统调用截获的方法。大致的思路如下:
每一个系统调用都是通过int 0x80中断进入核心,并在系统调用表中根据系统调用号找
到并调用相应的系统调用服务程序。idtr寄存器指向中断描述符表的起始地址,利用si
dt指令可以得到中断描述符表的起始地址,进而获得int 0x80中断服描述符所在位置,
计算出system_call的内存地址。最后,利用dev/kmem 找到真正的sys_call_table的地
址,最终实现对系统调用的劫持。这种技术可以在不导出sys_call_table的2.4系列版本
中调试通过。
(二)直接利用中断向量表截获系统调用
与上一种方法的变通形式相类似,该方法也是利用了中断向量表。但与上一种方法最大
的区别在于:我们在这里要做的事情就是修改中断向量表,把int 0x80处的中断向量用
我们构造的中断向量代替,相比方法1更通用且高效地实现系统调用的截获。
&&&&&&&&中断向量的存储格式如下:
- bits 0 to 15
:&&&&&&&&位移的低16位
- bits 16 to 31
- bits 32 to 37
- bits 37 to 39
- bits 40 to 42
类型码 011 中断门,111陷阱门,001调用门
标志位 1=32位 0=16位
- bits 45 to 46
DPL (Descriptor Privilege Level)描述项优先级别
P标志位,为1时表示在内存
- bits 48 to 63
位移的高16位
通过构造指向自定义函数的中断向量并将其写入中断向量表,一次系统调用所引发的调
用及被截获的过程如下:
0x80中断发生=&查中断向量表,得到预写入的自有函数地址=&执行该函数=&跳转到原始
0x80中断地址=&执行系统调用=&返回
预设钩子的过程:
A.&&&&&&定义自己的中断处理函数(C语言描述,例如一条打印语句即可)
B.&&&&&&定义自己的目标函数(汇编语言描述,分为4个主要部分)
保存所有寄存器数据
执行C语言描述的那部分中断处理函数
恢复所有的寄存器数据
执行真正的终端处理函数
C.&&&&&&获取目标函数内存地址,按照中断向量表的格式构造自己的中断描述符(8
D.&&&&&&利用sidt指令获取中断描述表起始地址,按顺序计算出0x80中断的中断描述符,保存
E.&&&&&&写入自己的中断描述符
解除钩子时只需要把预先保存的中断描述符写回到中断向量表中即可。
这种方式相比方式1的优点很明显。由于我们经常需要取得被监控系统的全部调用序列,
利用寻找sys_call_table的方式需要为每一个系统调用单独编写处理函数。而采用这种
方式可以利用一个函数一次截获所有的系统调用。除此以外,由于减少了寻找sys_call
_table的过程,整个截获过程的效率也得到了提高。
现在2.6内核关于系统调用实现部分的改变
在 Linux 2.4 内核中,用户态代码请求内核态代码完成某些功能是通过系统调用完成的
,而系统调用是通过中断指令(int 0x80)实现。在 x86 保护模式中,处理 INT 中断
指令时,CPU 首先从中断描述表 IDT 取出对应的门描述符,判断门描述符的种类,然后
检查门描述符的级别 DPL 和中断指令调用者的级别 CPL,当 CPL&=DPL 也就是说
调用者级别高于描述符指定级别时,才能成功调用,最后再根据描述符的内容,进行压
栈、跳转、权限级别提升。内核代码执行完毕之后,调用 IRET 指令返回,IRET 指令恢
复用户栈,并跳转回低级别的代码。
然而在实际情况中,发生系统调用时的特权检查工作是低效而没有用处的。由用户态进
入内核态的这个过程浪费了很多的CPU周期。例如,系统调用在正常情况下必然是由用户
态进入内核态(由内核直接调用 INT 指令的方式除外,这种情况没有意义),权限提升
之前和之后的级别是固定的,CPL是 3,而 INT 0x80 的 DPL 也是 3,这样 CPU 检查门
描述符的 DPL 和调用者的 CPL 就完全没必要。正是由于如此,Intel x86 CPU 从 PII
300(Family 6,Model 3,Stepping 3)之后,开始支持新的系统调用指令 sysenter
/sysexit。sysenter 指令用于由用户态直接切换到内核态并执行系统调用,SYSEXIT 指
令用于由内核态返回用户态。由于没有特权级别检查的处理,也没有压栈的操作,所以
执行速度比 INT n/IRET 快了不少。这种基于中断的系统服务调用机制,对于 Intel P
4 以上 CPU 来说存在着很大的性能隐患。根据实测结果 P3 850 在中断模式的系统调用
上,比 P4 2G 有将近一倍的性能优势,而对 Xeon 等高端 CPU 来说中断的处理性能甚
至更差。这也是为什么从 Windows XP/2003 开始,微软偷偷将 Int 0x2E 的系统调用换
成了CPU特殊的指令 sysenter (Intel) 和 syscall (AMD)。
同时,新版本的内核出于兼容性和其它的一些考虑,没有放弃int 0x80的系统调用方式
。在不支持sysenter/sysexit指令的cpu上,系统编译时通过对X86_FEATURE_SEP的判断
,还是可以利用80中断实现系统调用。除此以外,在特定的一些情况下,系统还是会利
用80中断来进行一些系统调用。我们沿用上面讲过的方法2,利用截获中断向量表的方式
,可以截获少数的几个系统调用(read、open、close、brk、mmap、munmap、sigretur
n、newuname、vfork、fstat64、set_thread_area)。这些系统调用之所以会利用80中
断完成,最大的可能就是它们都出现在系统调用的嵌套过程中。Sysenter指令相对80中
断方式的缺陷在于无法在一次系统调用中嵌套实现另一次调用。这是由sysenter的汇编
代码直接造成的(详情参见 arch/i386/kernel/entry.S
中ENTRY(sysenter_entry)部分
2.6内核上系统调用的截获
由于2.6版本内核已经采用了新的系统调用技术,上面介绍的利用中断向量表的方法已
经无法沿用。针对这些改变,可以有下面一些简单的思路:
A.&&&&&&重新编译内核,去掉对CPU
X86_FEATURE_SEP的判断,让系统继续采用80中断实现系
统调用。这样做的优劣之处都很明显,优点就是简单易行,可以继续沿用对中断向量表
的截获方式。在实际的实验中,只要系统不是P4 CPU,实际的性能差距也是不大的。缺
点则在于:第一,这种方法需要对系统内核进行重编译,实际应用中可能会比较麻烦;
第二,它彻底放弃了对sysenter/sysexit指令的支持,在特殊情况下会造成比较大的性
B.&&&&&&不加修改地使用方法一中利用dev/kmem寻找sys_call_table内存地址的方法。由于s
ysenter指令的添加只是为了躲过系统cpl与dpl的检验以及一些后续工作,真正实现系统
调用时还是通过&&call
*sys_call_table(,%eax,4) 来实现的。所以通过系统的idt还是
可以找到sys_call_table的内存地址。但这并没有解决编程时的复杂性问题和实际截获
中的效率。
在提出我们的解决办法之前,先来简单分析一下sysenter指令。
调用 sysenter/sysexit 指令地址的跳转是通过设置一组特殊寄存器(include/Msr.h)
实现的。这些寄存器包括:
SYSENTER_CS_MSR&&&&&&&&&&&&&&&&
0x174&& 指定要执行的用户空间的代码段选择符
SYSENTER_ESP_MSR&&&&&&&&&&&&&&&&0x175&&
指定要执行的内核空间的堆栈指针
SYSENTER_EIP_MSR&&&&&&&&0x176&&
指定要执行的内核空间代码的起始地址
这些寄存器可以通过 rdmsr/wrmsr 指令来读取/写入。
#define rdmsr(msr,val1,val2) \\
&&&&&&&&__asm__
__volatile__("rdmsr" \\
&&&&&&&&&&&&&&&&&&&&&&&&&&:
"=a" (val1), "=d" (val2) \\
&&&&&&&&&&&&&&&&&&&&&&&&&&:
"c" (msr))
#define wrmsr(msr,val1,val2) \\
&&&&&&&&__asm__
__volatile__("wrmsr" \\
&&&&&&&&&&&&&&&&&&&&&&&&&&:
&&&&&&&&&&&&&&&&&&&&&&&&&&:
"c" (msr), "a" (val1), "d" (val2))
执行 wrmsr 指令时,通过寄存器 edx、eax 指定设置的值,edx 指定值的高 32 位,e
ax 指定值的低 32 位。系统规定MSR寄存器的高32位长为零(也就是edx永远为0)
用户空间的代码如果想要执行一次系统调用,就需要先将系统调用的调用号写入eax,其
它参数按照该次调用的规定写入相关寄存器(或存入指向参数结构的指针)
A.&&&&&&将
SYSENTER_CS_MSR 的值读入 cs 寄存器
B.&&&&&&将
SYSENTER_EIP_MSR 的值读入eip 寄存器
C.&&&&&&将
SYSENTER_CS_MSR 的值加 8(Ring0 的堆栈段描述符)装载到 ss 寄存器。
D.&&&&&&将
SYSENTER_ESP_MSR 的值装载到 esp 寄存器
E.&&&&&&将特权级切换到
F.&&&&&&如果
EFLAGS 寄存器的 VM 标志被置位,则清除该标志
G.&&&&&&开始执行指定的
Ring0 代码(即为eip寄存器所保存的内存地址)
讨论过了sysenter指令的实现原理和一些相关的设置,我们的设计思路就已经很明显了
。作为基础的一点,由于上面已经讨论过的一个原因,并不是所有的系统调用都是通过
sysenter指令来实现,所以通过中断向量表截获系统调用的方式应该作为一个组成部分
在我们的系统中沿用。除此以外,我们通过改变SYSENTER_EIP_MSR,也就是sysenter指
令的跳转目的地址来实现我们的目的,大致步骤如下:
A.&&&&&&利用rdmsr(MSR_IA32_SYSENTER_EIP,,)
读入系统定义的sysenter指令目的地址
B.&&&&&&构造自己的系统调用处理函数(假定为:my_function),
并定义unsigned long handler_code=(unsigned
C.&&&&&&构造自己的sysenter指令处理函数
void stub_trtr(void)
&&&&&&&&".globl
my_stub&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&".align
4,0x90&&&&&&&&&&&&&&&&&&&&&&&&&&\\n"
&&&&&&&&"my_stub:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&"&&&&&&
call&&&&*%0&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&"&&&&&&
*%1&&&&&&&&&&&&&&&&&&&&
&&&&&&&&::"m"(handler_code),"m"(old_sysenter)
&&&&&&&&);
//handler_code 指向我们自己的处理函数,old_sysenter是上一步读入的目
D.&&&&&&把上面构造的sysenter指令处理函数的地址利用wrmsr写入MSR_IA32_SYSENTER_EIP
撤销截获的时候只需要把预先保存的old_sysenter写回到MSR_IA32_SYSENTER_EIP的低3
2位就可以了
另外需要说明的是,我们在自己的系统调用处理函数中可以通过读取EAX来读取具体的系
统调用号,通过读取其它寄存器来获得系统调用的相关参数,通过current_thread_inf
o来获取thread信息,继而获得当前进程的task_struct信息。
实现sysenter截获的代码如下(本例中截获代码的功能是统计被截获系统调用的调用号
和截获次数):
#include &linux/module.h&
#include &linux/kernel.h&
#include &linux/init.h&
#include &linux/sched.h&
#include &linux/thread_info.h&
#include &asm-i386/unistd.h&
#include &asm/msr.h&
#include &asm/pgtable.h&
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("trtr");
MODULE_DESCRIPTION("Sysenter Hijack module V1.0");
asmlinkage char* my_function();
unsigned long handler_code=(unsigned
unsigned long old_
extern asmlinkage void my_stub();
unsigned long handled_
unsigned long counts[300];
void stub_trtr(void)
&&&&&&&&".globl
my_stub&&&&&&&&&&&&&&&&
&&&&&&&&".align
4,0x90&&&&&&&&&&&&&&&&&&\\n"
&&&&&&&&"my_stub:&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&"&&&&&&
*%0&&&&&&&&&&&&&&&&\\n"
&&&&&&&&&&&&&&&&"&&&&&&
jmp&&*%1&&&&&&&&&&&&&&&&\\n"
&&&&&&&&::"m"(handler_code),"m"(old_sysenter)
&&&&&&&&);
asmlinkage char* my_function()
&&&&&&&&&&&&&&&&int
&&&&&&&&&&&&&&&&handled_times++;
&&&&&&&&&&&&&&&&__asm__("movl
%%eax,%0;":"=r"(my_eax));
&&&&&&&&&&&&&&&&counts[my_eax]++;
&&&&&&&&&&&&&&&&return
void my_hook()
&&&&&&&&&&&&&&&&unsigned
&&&&&&&&&&&&&&&&rdmsr(MSR_IA32_SYSENTER_EIP,old_sysenter,a);
&&&&&&&&&&&&&&&&wrmsr(MSR_IA32_SYSENTER_EIP,my_stub,0);
static int __init trtr_init(void)
&&&&&&&&&&&&&&&&int
&&&&&&&&&&&&&&&&for(i=0;i&300;i++)
counts[i]=0;
&&&&&&&&&&&&&&&&printk("Handling
on sysenter! \\n");
&&&&&&&&&&&&&&&&my_hook();
&&&&&&&&&&&&&&&&handled_times=0;
&&&&&&&&&&&&&&&&return
static void trtr_exit(void)
&&&&&&&&&&&&&&&&int
&&&&&&&&&&&&&&&&wrmsr(MSR_IA32_SYSENTER_EIP,old_sysenter,0);
&&&&&&&&&&&&&&&&for(j=0;j&300;j++)
&&&&&&&&&&&&&&&&&&&&&&&&if
(counts[j]!=0) printk("System call %d has been handled %ld
times\\n",j,
counts[j]);
&&&&&&&&&&&&&&&&printk("Total
handled %ld times!!\\n",handled_times);
&&&&&&&&&&&&&&&&printk("exited
module_init (trtr_init);
module_exit (trtr_exit);
///////////////////////////////////////////////////////////////////////////////
在 Intel 的软件开发者手册第二、三卷(Vol.2B,Vol.3)中,4.8.7 节是关于 sysenter/sysexit
指令的详细描述。手册中说明,sysenter 指令可用于特权级 3 的用户代码调用特权级 0 的系统内核代码,而 SYSEXIT
指令则用于特权级 0 的系统代码返回用户空间中。sysenter 指令可以在 3,2,1 这三个特权级别调用(Linux
中只用到了特权级 3),而 SYSEXIT 指令只能从特权级 0 调用。
执行 sysenter 指令的系统必须满足两个条件:1.目标 Ring 0 代码段必须是平坦模式(Flat Mode)的 4GB
的可读可执行的非一致代码段。2.目标 RING0 堆栈段必须是平坦模式(Flat Mode)的 4GB
的可读可写向上扩展的栈段。
在 Intel 的手册中,还提到了 sysenter/sysexit 和 int n/iret 指令的一个区别,那就是
sysenter/sysexit 指令并不成对,sysenter 指令并不会把 SYSEXIT 所需的返回地址压栈,sysexit
返回的地址并不一定是 sysenter 指令的下一个指令地址。调用 sysenter/sysexit
指令地址的跳转是通过设置一组特殊寄存器实现的。这些寄存器包括:
SYSENTER_CS_MSR - 用于指定要执行的 Ring 0 代码的代码段选择符,由它还能得出目标 Ring 0
所用堆栈段的段选择符;
SYSENTER_EIP_MSR - 用于指定要执行的 Ring 0 代码的起始地址;
SYSENTER_ESP_MSR-用于指定要执行的Ring 0代码所使用的栈指针
这些寄存器可以通过 wrmsr 指令来设置,执行 wrmsr 指令时,通过寄存器 edx、eax 指定设置的值,edx
指定值的高 32 位,eax 指定值的低 32 位,在设置上述寄存器时,edx 都是 0,通过寄存器 ecx 指定填充的 MSR
寄存器,sysenter_CS_MSR、sysenter_ESP_MSR、sysenter_EIP_MSR 寄存器分别对应
0x174、0x175、0x176,需要注意的是,wrmsr 指令只能在 Ring 0 执行。
这里还要介绍一个特性,就是 Ring0、Ring3 的代码段描述符和堆栈段描述符在全局描述符表 GDT
中是顺序排列的,这样只需知道 SYSENTER_CS_MSR 中指定的 Ring0 的代码段描述符,就可以推算出 Ring0
的堆栈段描述符以及 Ring3 的代码段描述符和堆栈段描述符。
在 Ring3 的代码调用了 sysenter 指令之后,CPU 会做出如下的操作:
1. 将 SYSENTER_CS_MSR 的值装载到 cs 寄存器
2. 将 SYSENTER_EIP_MSR 的值装载到 eip 寄存器
3. 将 SYSENTER_CS_MSR 的值加 8(Ring0 的堆栈段描述符)装载到 ss 寄存器。
4. 将 SYSENTER_ESP_MSR 的值装载到 esp 寄存器
5. 将特权级切换到 Ring0
6. 如果 EFLAGS 寄存器的 VM 标志被置位,则清除该标志
7. 开始执行指定的 Ring0 代码
在 Ring0 代码执行完毕,调用 SYSEXIT 指令退回 Ring3 时,CPU 会做出如下操作:
1. 将 SYSENTER_CS_MSR 的值加 16(Ring3 的代码段描述符)装载到 cs 寄存器
2. 将寄存器 edx 的值装载到 eip 寄存器
3. 将 SYSENTER_CS_MSR 的值加 24(Ring3 的堆栈段描述符)装载到 ss 寄存器
4. 将寄存器 ecx 的值装载到 esp 寄存器
5. 将特权级切换到 Ring3
6. 继续执行 Ring3 的代码
由此可知,在调用 SYSENTER 进入 Ring0 之前,一定需要通过 wrmsr 指令设置好 Ring0
代码的相关信息,在调用 SYSEXIT 之前,还要保证寄存器edx、ecx 的正确性。
根据 Intel 的 CPU 手册,我们可以通过 CPUID 指令来查看 CPU 是否支持 sysenter/sysexit
指令,做法是将 EAX 寄存器赋值 1,调用 CPUID 指令,寄存器 edx 中第 11 位(这一位名称为
SEP)就表示是否支持。在调用 CPUID 指令之后,还需要查看 CPU 的 Family、Model、Stepping
属性来确认,因为据称 Pentium Pro 处理器会报告 SEP 但是却不支持 sysenter/sysexit 指令。只有
Family 大于等于 6,Model 大于等于 3,Stepping 大于等于 3 的时候,才能确认 CPU 支持
sysenter/sysexit 指令。
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。【原创】另一种sysenter hook方法(绕过绝大多数的rootkit检测工具的检测) - 看雪安全论坛
『软件调试逆向』 [综合性论坛]本版讨论的主题包括:调试逆向、系统底层、商业保护、虚拟机保护、.NET平台等安全相关的话题。
该主题: "【原创】另一种sysenter hook方法(绕过绝大多数的rootkit检测工具的检测)" 因在一定的时间里没有任何回复而自动关闭。如果您还对该主题感兴趣或者想参与对此主题的讨论,请您重新发表一篇相关的新主题。
本站声明:看雪论坛文章版权属于作者,受法律保护。没有作者书面许可不得转载。若作者同意转载,必须以超链接形式标明文章原始出处和作者信息及本声明!
注册日期: Oct 2006
现金: 200 Kx
获感谢文章数:0获会员感谢数:0
【原创】另一种sysenter hook方法(绕过绝大多数的rootkit检测工具的检测)
标 题: 【原创】另一种sysenter hook方法(绕过绝大多数的rootkit检测工具的检测) 作 者: 堕落天才
时 间: ,11:09:49 链 接: /showthread.php?t=42705
*****************************************************************************
*标题:【原创】另一种sysenter&hook方法(绕过绝大多数的rootkit检测工具的检测)&&*
*作者:堕落天才&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*
*日期:号&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*
*****************************************************************************
&&&&先废话,当初是为了绕开NP对sysenter保护而想出来的,后来发现连RootkitUnhooker都绕了.
&&&&什么是sysenter&hook我也不罗唆了,一般的拦截方法就是通过rdmsr&wrmsr&两个指令把原来的sysenter地址改成自己的sysenter地址来实现的.这种方法使用方便,但检测也很容易.
&&&&这里介绍的另外一种方法不改变sysenter地址,而是通过直接在原来sysenter地址里面写跳转代码来实现的,这实际上跟一般的函数头inline&hook一样.这样rootkit检测工具就不会认为sysenter已经改变(实际上也是没变).
&&&&一般的rootkit检测工具检测函数inline&hook是通过检测长跳转指令0xE9的来判断跳转距离是不是超出函数所在的模块范围来确定的.但是实现跳转我们也可以借助寄存器或变量(用变量跳转需要涉及重定位问题,麻烦.所以一般用寄存器),这样跳转指令就不是0xE9了而是0xFF,这个绝大多数rootkit检测工具是检测不到的(包括著名的RootkitUnhooker,VICE).
&&&&由于我们已经改变了KiFastCall函数头,所以我们只能把原来的函数头代码放到另外一个地方执行(动态分配内存,当然如果不考虑兼容性硬编码也没问题),然后再跳转回来.这里使用了&三级跳&,大概是这个样子.
&&&&sysenter-&KiFastCall
&&&&&&&&&&&&&JMP&-&&MyKiFastCall(这里进行拦截或什么的)
&&&&&&&&&&&&&&&&&&&&JMP&-&&KiFastCall&head&code&(这里执行原来KiFastCall函数头代码)
&&&&&&&&&&&&&&&&&&&&&&&&&&&JMP&-&&KiFastCall&+&N(已经执行指令长度)
///////////////////////////////////////////////////////////////////////////////////////////////////&&
//堕落天才
#include&ntddk.h&
#include&&OpCodeSize.h&
ULONG&uS&&&&&&&&&&&//sysenter地址
UCHAR&uOrigSysenterHead[8];//保存原来的八个字节函数头
PUCHAR&pMovedSysenterC&//把原来的KiFastCall函数头保存在这里
ULONG&i;&&&&&&&&&&&&&&&&&&&//记录服务ID
__declspec(naked)&void&MyKiFastCallEntry(void)
&&&&&&&&&&&&pop&&edi&&&&&//因为用到了edi来跳转&这里恢复
&&&&&&&&&&&&&mov&&i,&eax&&//得到服务ID
&&__asm{&&
&&&&&&&&&&&pushad
&&&&&&&&&&&push&fs
&&&&&&&&&&&&&push&0x30
&&&&&&&&&&&&pop&fs
&&DbgPrint(&sysenter&was&hooked!&Get&service&ID:%X&,i);&//证明自己存在
&&&&&&&&&&&&&pop&fs
&&&&&&&&&&&&&popad&&&&
&&&&jmp&pMovedSysenterCode&//第二跳,跳转到原来的函数头代码&
//////////////////////////////////////////////////////
VOID&OnUnload(IN&PDRIVER_OBJECT&DriverObject)
&&&&&&&&&&&&&mov&&eax,cr0
&&&&and&&eax,not&10000h
&&&&mov&&cr0,eax
&&memcpy((PVOID)uSysenter,uOrigSysenterHead,8);//把原来函数头的八个字节恢复
&&&&mov&&eax,cr0
&&&&&&&&&&&&or&&&eax,10000h
&&&&mov&&cr0,eax
&&ExFreePool(pMovedSysenterCode);&//&释放分配的内存
&&DbgPrint(&Unload&sysenterHook&);
////////////////////////////////////////////////////////
VOID&HookSysenter()
&&UCHAR&&cHookCode[8]&=&{&0x57,&&&&&&&&&&//push&edi&&&&&&&第一跳,从KiFastCall跳到MyKiFastCallEntry.并绕过rootkit检测工具检测
&&&&&&&&&&&&&&&&&&&&&&&&&&0xBF,0,0,0,0,&&//mov&&edi,0000
&&&&&&&&&&&&&&&&&&&&&&&&&&0xFF,0xE7};&&&&//jmp&&edi
&&UCHAR&&JmpCode[]={0xE9,0,0,0,0};&&&&&&&//jmp&0000&第三跳,从KiFastCall函数头代码跳转到原来KiFastCall+N
&&int&&&&nCopyLen&=&0;
&&int&&&&nPos&=&0;
&&&&&&&&&&mov&ecx,0x176
&&&&&&&&&&&&rdmsr
&&&&mov&uSysenter,eax&&//得到KiFastCallEntry地址
&&DbgPrint(&sysenter:0x%08X&,uSysenter);
&&nPos&=&uS
&&&while(nCopyLen&8){&//我们要改写的函数头至少需要8字节&这里计算实际需要COPY的代码长度&因为我们不能把一条完整的指令打断
&&&&nCopyLen&+=&GetOpCodeSize((PVOID)nPos);&&//参考1
&&&&nPos&=&uSysenter&+&nCopyL
&&DbgPrint(&copy&code&lenght:%d&,nCopyLen);
&&pMovedSysenterCode&=&ExAllocatePool(NonPagedPool,20);
&&memcpy(uOrigSysenterHead,(PVOID)uSysenter,8);//备份原来8字节代码
&&*((ULONG*)(JmpCode+1))&=&(uSysenter&+&nCopyLen)&-&((ULONG)pMovedSysenterCode&+&nCopyLen)-&5;//计算跳转地址
&&memcpy(pMovedSysenterCode,(PVOID)uSysenter,nCopyLen);&//把原来的函数头放到新分配的内存
&&memcpy((PVOID)(pMovedSysenterCode&+&nCopyLen),JmpCode,5);&//把跳转代码COPY上去
&&*((ULONG*)(cHookCode+2))&=&(ULONG)MyKiFastCallE&//HOOK地址
&&DbgPrint(&Saved&sysenter&code:0x%08X&,pMovedSysenterCode);
&&DbgPrint(&MyKiFastCallEntry:0x%08X&,MyKiFastCallEntry);
&&&&&&&&&&&&mov&&eax,cr0
&&&&and&&eax,not&10000h
&&&&mov&&cr0,eax
&&memcpy((PVOID)uSysenter,cHookCode,8);//把改写原来函数头
&&&&mov&&eax,cr0
&&&&&&&&&&&&or&&&eax,10000h
&&&&mov&&cr0,eax
NTSTATUS&DriverEntry(IN&PDRIVER_OBJECT&DriverObject,PUNICODE_STRING&RegistryPath)
&&DbgPrint(&Welcome&to&sysenterhook.sys&);
&&DriverObject-&DriverUnload&=&OnU
&&HookSysenter();
&&return&STATUS_SUCCESS;
///////////////////////////////////////////////////////////////////////////////////////////////////&
以上代码在&XP&SP2中文&+&RootkitUnhooker下测试通过&
同理&IDT&hook也可以用这种方法实现,HOOK的实质是改变程序流程,无论在哪里改变
*************************************************************************************************
参考1,&海风月影*转载请注明来自看雪论坛@
被 堕落天才 最后编辑
注册日期: Aug 2004
现金: 55 Kx
获感谢文章数:0获会员感谢数:0
, 11:38:57
注册日期: May 2005
现金: 12 Kx
获感谢文章数:0获会员感谢数:0
, 11:43:51
注册日期: Nov 2006
现金: 200 Kx
获感谢文章数:0获会员感谢数:0
, 12:03:54
天才强,严重学习了
注册日期: Dec 2006
现金: 405 Kx
获感谢文章数:1获会员感谢数:1
, 13:06:16
注册日期: Apr 2006
现金: 200 Kx
获感谢文章数:0获会员感谢数:0
, 15:07:06
支持!!!!!!!!!!!
注册日期: Apr 2006
现金: 200 Kx
获感谢文章数:0获会员感谢数:0
, 15:23:39
支持!!!!!!!!!!!
注册日期: Jan 2005
现金: 206 Kx
获感谢文章数:0获会员感谢数:0
, 15:37:21
怎么加入opcodesize.h死活编译不过呀?
注册日期: Oct 2006
现金: 200 Kx
获感谢文章数:0获会员感谢数:0
, 15:44:56
最初由 linsion发布
怎么加入opcodesize.h死活编译不过呀?
请参考&&这篇文章
注册日期: Jan 2005
现金: 206 Kx
获感谢文章数:0获会员感谢数:0
, 16:40:48
加入了出现这么多错误!
Compiling...
sysentryHook.c
F:\Windows&Program\WINDDK\2600\inc\crt\WINBASE.H(293)&:&error&C2061:&syntax&error&:&identifier&'CRITICAL_SECTION'
F:\Windows&Program\WINDDK\2600\inc\crt\WINBASE.H(293)&:&error&C2059:&syntax&error&:&';'
F:\Windows&Program\WINDDK\2600\inc\crt\WINBASE.H(294)&:&error&C2061:&syntax&error&:&identifier&'PCRITICAL_SECTION'
F:\Windows&Program\WINDDK\2600\inc\crt\WINBASE.H(294)&:&error&C2059:&syntax&error&:&';'
注册日期: Jan 2005
现金: 206 Kx
获感谢文章数:0获会员感谢数:0
, 16:43:36
不知你加入的那个头文件是怎样的?
可不可以上传一下呢?
注册日期: Oct 2006
现金: 114 Kx
获感谢文章数:0获会员感谢数:0
, 17:21:30
强贴!学习,谢谢天才分享
注册日期: Jan 2005
现金: 206 Kx
获感谢文章数:0获会员感谢数:0
, 03:52:44
看了驱动开发网上写的那个!
#define&Naked&&&__declspec(&naked&)
ULONG&MaskTable[518]&=&
&&0xFFFFFFFF,&0xFFFFFFFF,&0xxFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xxxFFFFFFFF,&0xFFFFFFFF,
&&0xxxFFFFFFFF,&0x,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xx,
&&0xxxFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xxFFFFFFFF,&0xFFFFFFFF,&0xFFFFFFFF,
&&0xFFFFFFFF,&0xFFFFFFFF
Naked&ULONG&GetOpCodeSize_ASM_CODE(PVOID&Start,&PVOID&Tlb)
&&&&&&pushad
&&&&&&mov&&&esi,&[esp+24h]
&&&&&&mov&&&ecx,&[esp+28h]
&&&&&&xor&&&edx,&edx
&&&&&&xor&&&eax,&eax
&&&&&&and&&&dl,&0F7h
&&&&&&mov&&&al,&[ecx]
&&&&&&inc&&&ecx
&&&&&&or&&&&&edx,&[esi+eax*4h]
&&&&&&test&&&dl,&8h
&&&&&&jnz&L005
&&&&&&cmp&&&al,&0F6h
&&&&&&je&L035
&&&&&&cmp&&&al,&0F7h
&&&&&&je&L035
&&&&&&cmp&&&al,&0CDh
&&&&&&je&L040
&&&&&&cmp&&&al,&0Fh
&&&&&&je&L045
&&&&&&test&&&dh,&80h
&&&&&&jnz&L052
&&&&&&test&&&dh,&40h
&&&&&&jnz&L067
&&&&&&test&&&dl,&20h
&&&&&&jnz&L057
&&&&&&test&&&dh,&20h
&&&&&&jnz&L062
&&&&&&mov&&&eax,&ecx
&&&&&&sub&&&eax,&[esp+28h]
&&&&&&and&&&edx,&707h
&&&&&&add&&&al,&dl
&&&&&&add&&&al,&dh
&&&&&&mov&&&[esp+1Ch],&eax
&&&&&&popad
&&&&&&retn
&&&&&&or&&&&&dh,&40h
&&&&&&test&&&byte&ptr&[ecx],&38h
&&&&&&jnz&L019
&&&&&&or&&&&&dh,&80h
&&&&&&jmp&L019
&&&&&&or&&&&&dh,&1h
&&&&&&cmp&&&byte&ptr&[ecx],&20h
&&&&&&jnz&L019
&&&&&&or&&&&&dh,&4h
&&&&&&jmp&L019
&&&&&&mov&&&al,&[ecx]
&&&&&&inc&&&ecx
&&&&&&or&&&&&edx,&[esi+eax*4h+400h]
&&&&&&cmp&&&edx,&-1h
&&&&&&jnz&L019
&&&&&&mov&&&eax,&edx
&&&&&&jmp&L032
&&&&&&xor&&&dh,&20h
&&&&&&test&&&al,&1h
&&&&&&jnz&L021
&&&&&&xor&&&dh,&21h
&&&&&&jmp&L021
&&&&&&xor&&&dl,&2h
&&&&&&test&&&dl,&10h
&&&&&&jnz&L025
&&&&&&xor&&&dl,&6h
&&&&&&jmp&L025
&&&&&&xor&&&dh,&2h
&&&&&&test&&&dh,&10h
&&&&&&jnz&L027
&&&&&&xor&&&dh,&6h
&&&&&&jmp&L027
&&&&&&mov&&&al,&[ecx]
&&&&&&inc&&&ecx
&&&&&&mov&&&ah,&al
&&&&&&and&&&ax,&0C007h
&&&&&&cmp&&&ah,&0C0h
&&&&&&je&L023
&&&&&&test&&&dl,&10h
&&&&&&jnz&L090
&&&&&&cmp&&&al,&4h
&&&&&&jnz&L080
&&&&&&mov&&&al,&[ecx]
&&&&&&inc&&&ecx
&&&&&&and&&&al,&7h
&&&&&&cmp&&&ah,&40h
&&&&&&je&L088
&&&&&&cmp&&&ah,&80h
&&&&&&je&L086
&&&&&&cmp&&&ax,&5h
&&&&&&jnz&L023
&&&&&&or&&&&&dl,&4h
&&&&&&jmp&L023
&&&&&&or&&&&&dl,&1h
&&&&&&jmp&L023
&&&&&&cmp&&&ax,&6h
&&&&&&je&L096
&&&&&&cmp&&&ah,&40h
&&&&&&je&L088
&&&&&&cmp&&&ah,&80h
&&&&&&jnz&L023
&&&&&&or&&&&&dl,&2h
&&&&&&jmp&L023
&&&&&&retn
ULONG&GetOpCodeSize(PVOID&Start)
&&&&push&Start
&&&&push&offset&MaskTable
&&&&call&GetOpCodeSize_ASM_CODE
&&&&add&&&esp,&8&&&&&
注册日期: Jul 2006
现金: 1081 Kx
致谢数: 222
获感谢文章数:57获会员感谢数:216
, 08:34:02
嘿嘿,其实就是inline&hook~~晕死~
注册日期: Nov 2004
现金: 201 Kx
获感谢文章数:0获会员感谢数:0
, 13:12:43
该主题: "【原创】另一种sysenter hook方法(绕过绝大多数的rootkit检测工具的检测)" 因在一定的时间里没有任何回复而自动关闭。如果您还对该主题感兴趣或者想参与对此主题的讨论,请您重新发表一篇相关的新主题。
您不可以发表主题
您不可以回复帖子
您不可以上传附件
您不可以编辑自己的帖子
论坛论坛启用
用户控制面板
会员在线状态
CrackMe攻击篇,分析文章提交区
『看雪众测/众包』
『求助问答』
『经典问答』
『资料导航』
『软件调试逆向』
『密码学』
『编程技术』
『C32Asm』
『MDebug』
『安全工具开发』
『加壳与脱壳』
『CrackMe&ReverseMe』
『资源下载』
『Android 安全』
『Android 开发』
『iOS安全』
『WEB安全』
『漏洞分析』
『外文翻译』
『招聘专区』
『职业生涯』
『15PB培训』
『麦洛克菲培训』
『茶余饭后』
『安全资讯』
『论坛活动』
6)PEDIY Crackme竞赛2009
7)看雪十周年专版
8)腾讯公司2010软件安全竞赛
9)2011 Exploit Me竞赛
『图书项目版』
《加密与解密(第三版)》
《C++反汇编与逆向分析技术揭秘》
《Android软件安全与逆向分析》
『论坛版务』
相似的主题
『加壳与脱壳』
『加壳与脱壳』
『加壳与脱壳』
『外文翻译』
『求助问答』
所有时间均为北京时间, 现在的时间是 .
&&& 看雪学院()
| 提供带宽资源
|&微信公众帐号:

我要回帖

更多关于 汇编指令 的文章

 

随机推荐