fs寄存器 资料

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的返回值。

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

 

 

 

 

 

你可能感兴趣的:(文件系统)