fs寄存器 资料

来源:互联网 发布:东方梦华录mac 编辑:程序博客网 时间:2024/05/22 10:28

FS寄存器指向当前活动线程的TEB结构(线程结构)
偏移  说明
000  指向SEH链指针
004  线程堆栈顶部
008  线程堆栈底部
00C  SubSystemTib
010  FiberData
014  ArbitraryUserPointer
018  FS段寄存器在内存中的镜像地址(TEB)
020  进程PID
024  线程ID
02C  指向线程局部存储指针
030  PEB结构地址(进程结构)
034  上个错误号


得到KERNEL32.DLL基址的方法
assume fs:nothing             ;打开FS寄存器
mov eax,fs:[30h]            ;得到PEB结构地址
mov eax,[eax + 0ch]        ;得到PEB_LDR_DATA结构地址
mov esi,[eax + 1ch]        ;InInitializationOrderModuleList
lodsd                      ;得到KERNEL32.DLL所在LDR_MODULE结构的InInitializationOrderModuleList地址
mov edx,[eax + 8h]         ;得到BaseAddress,既Kernel32.dll基址

 

S.E.H结构原理:

首先确定自己的链表知识回调函数知识已经补充.

S.E.H结构包含两个DWORD指针:SEH链表指针和异常处理函数句柄,8个字节,8个要点.

1)SEH结构体存放在系统栈;

2)线程初始化将自动向栈里安装一个SEH结构,作为默认线程异常处理.

3)如果程序源代码中使用了_try{}和_excopt{}或者宏等异常处理机制,编译器将最终通过向当前函数栈安装一个SEH来实现异常处理.

4)栈中一般会同时存在多个SEH.

5)栈中的多个SEH通过链表指针在栈内由栈顶向栈底穿成单向链表,位于链表最顶端的SEH通过TEB 0字节处的指针来标识.

6)当异常发生时,操作系统会中断程序,并首先从TEB的 0字节偏移处取得最近的SEH,使用异常处理函数句柄所指向的代码来处理异常.

7)当离异常最近的异常处理函数不能处理时,将沿顺SEH链表逐步尝试.

8)如果程序所安装的异常处理函数都不能解决,系统将采用默认的异常处理函数来处理,通常弹出错误对话框,强制关闭程序.

根据以上8个要点可以总结出以下处理顺序:

①--->首先执行线程异常处理函数及最近的SEH.

②失败后将执行链表中的下一个异常处理函数,只止于NULL而不能解决.

③执行进程异常处理SEH

④执行系统异常处理SEH.

线程异常处理:2个状态值,参数无须解释.值得一提的是unwind操作.清理现场,释放资源技巧可以借鉴.

unwind操作通过kernerl.32中的函数rtlunwind()来实现.

进程异常处理:3种状态值.进程的异常处理回调函数需要使用kernerl32.dll中的函数setunhandledexceptionfliter()函数来注册.

系统默认异常处理:终极BOSS也称UEF.如果进程异常处理函数失败或者进程异常处理函数没有注册,系统异常处理函数unhandledexptionfilter()将被调用,所有的异常都将被捕获.

首先这个函数检查注册表,HKLM/SOFTWARE/MICROSOFT/windowsnt/cv/aedebug.其中值得一提的是其中的参数.指定了程序调试器.

ring3中第一个异常处理函数为kiuserexceptiondispatcher(),其首先检查调试状态,遍历SEH表,unwind操作,

然后失败调用终极BOSS.winxp增加了VEH.其中VEH与SEH不同的一个显著特点是,其为双向链表.其处理级别要高于SEH并保存在堆内.unwind操作对起不起作用.

 

 

 

 

对于Ring3的应用程序,fs:[0]的地址指向的是TEB结构,这个结构的开头是一个NT_TIB结构,NT_TIB结构的0x18偏移处是一个Self指针,指向这个结构自身,也就是指向TEB结构的开头。
TEB结构的0x30偏移是一个指向PEB的指针。PEB又是一个结构,这个结构的0x2偏移处是一个UChar,名叫BeingDebugged,当进程被调试时,此值为1,未被调试时此值为0

因此以下代码逐行执行后的结果:
mov eax,dword ptr fs:[18h];eax=TEB的指针
mov eax,dword ptr [eax+30h];eax=PEB的指针
movzx eax,byte ptr [eax+2h];eax=PEB.BeingDebugged(byte扩展为dword)

TEB和PEB结构的详细内容可以在windbg内核调试状态下使用dt _TEB、dt _PEB命令来察看。

MASM中默认是fs:error,也就是默认不能使用fs段寄存器,因此要在masm中使用它时必须先assume fs:nothing
fs是段寄存器,即保存段选择子,对应的地址通过GDT或LDT中的相应项目来决定其范围和使用权限等。

最后回到IsDebuggerPresent,它就是通过检查PEB中的BeingDebugged字段来确定进程是否处于被调试状态的,因此修改此字段可以直接影响此API的返回值。

以上内容在调试或者说软件加密与解密过程中是基本的常识。

 

 

 

 

 

原创粉丝点击