首页
论坛
专栏
课程

[调试逆向] [求助]关于fs寄存器的问题

2009-4-14 13:08 13127

[调试逆向] [求助]关于fs寄存器的问题

2009-4-14 13:08
13127
od里看了下
IsDebuggerPresent的实现代码就三条指令
mov eax,dword ptr fs:[18h]
mov eax,dword ptr [eax+30h]
movzx eax,byte ptr [eax+2h]
也就是BYTE PTR [[fs:[18h]+30h]+2h](未声明均表示DWORD类型)的值就表示是否在调试环境中
问题1:用masm实现时发现,必须先assume fs:nothing
否侧就提示非法使用寄存器,为什么?
问题2:fs在我的机子中的值是03bh,为什么
fs:[00000018]=[7FFDD018]=7FFDD000

希望有达人解答

[推荐]看雪企服平台,提供安全分析、定制项目开发、APP等级保护、渗透测试等安全服务!

上一主题 下一主题
最新回复 (14)
clayg 2009-4-14 13:22
2
0
刘明帮你顶下啦~~~我也希望能看到答案的哈
轩辕小聪 7 2009-4-14 14:06
3
0
对于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的返回值。

以上内容在调试或者说软件加密与解密过程中是基本的常识。
XSJS 2009-4-14 14:18
4
0
[QUOTE=轩辕小聪;606574]对于Ring3的应用程序,fs:[0]的地址指向的是TEB结构,这个结构的开头是一个NT_TIB结构,NT_TIB结构的0x18偏移处是一个Self指针,指向这个结构自身,也就是指向TEB结构的开头。
TEB结构的0x30偏移是一个指向PEB的指针。PEB又是一个结构,这个结构的0x2偏移处是一个...[/QUOTE]
好像LZ问的是FS段初始化的问题
烁皓 2009-4-14 15:11
5
0
问题1:MASM中默认是fs:error,也就是默认不能使用fs段寄存器,因此要在masm中使用它时必须先assume fs:nothing
问题2:大致是这样,段寄存器中的16位用来做索引信息,索引64位的段描述符。在GDT或LDT中得到段的起始地址。即你在od里看到03bh后面有一个32位7ffdf000(fff)。所以fs的基址就是7ffdf000,你可以去看看,7ffdf000处是一个指针,和你输入fs:[0]一样。
烁皓 2009-4-14 15:12
6
0
问题2具体内容可以看老罗的Windows环境下32位汇编语言,第一章里有介绍
stoy 2009-4-14 15:25
7
0
貌似是GetLastError()代码
hatling 3 2009-4-14 16:32
8
0
谢谢,楼上各位。。。
有些懂了
wynney 24 2009-4-14 17:08
9
0
typedef struct _PEB
{
   UCHAR InheritedAddressSpace;                     // 00h
   UCHAR ReadImageFileExecOptions;                  // 01h
   UCHAR BeingDebugged;                             // 02h
   UCHAR Spare;                                     // 03h
...................
wdsm 2009-4-14 17:11
10
0
说说问题二吧,这里我用实例证明一下。

我这里gdtr=8003f00003ff,某个进程空间中ring 3下的fs=0038h。

08h用二进制表示为00000000 00111000,按照intel文档的说明,最低的2位表示将要访问的段的权限级为0,第3位这里是0,表示将要访问的段的段描述符从全局描述符表(即GDT)里面取得,剩下的高13位是所为索引值用的,这里是7。每个段描述符占8个字节,8003f000处存放有一个NULL描述符。
lkd>dd 8003f000+8*7
8003f038 f0000fff 7f40f3fd 0400ffff 0000f200

每个描述符8个字节,按照intel文档的说明,8003f038处的双字的高16位是段起始地址的低16位,8003f03c处双字的高8位是段起始地址的高8位,8003f03c处双字的低8位是段起始地址的中间的8位,综合起来就是7ffdf000。

验证一下。
lkd> dd 7ffdf000+18 l1
7ffdf018  7ffdf000
foxabu 13 2009-4-14 17:30
11
0
学习3456
hatling 3 2009-4-14 18:05
12
0
请问有哪些资料详细介绍这方面的知识。。。
麻烦介绍下,谢了。。
老兄度过有相关资料的话。可不可以发我邮箱里
4378wslm@163.com
wdsm 2009-4-14 18:14
13
0
名叫《Intel@64 and IA-32 Architectures Software Developer Manual》的pdf文档,自己google吧。顺便八卦一下,内事不决问百度,外事不决问谷歌
烁皓 2009-4-14 22:55
14
0
高手和菜鸟的区别不仅是知识上的差别,更重要的是高手懂得解决问题方法。
烁皓 2009-4-14 22:55
15
0
很详细,学习了
游客
登录 | 注册 方可回帖
返回