首页
社区
课程
招聘
[求助]关于fs寄存器的问题
发表于: 2009-4-14 13:08 16789

[求助]关于fs寄存器的问题

2009-4-14 13:08
16789

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,为什么


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (14)
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
刘明帮你顶下啦~~~我也希望能看到答案的哈
2009-4-14 13:22
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
3
对于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的返回值。

以上内容在调试或者说软件加密与解密过程中是基本的常识。
2009-4-14 14:06
0
雪    币: 152
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
[QUOTE=轩辕小聪;606574]对于Ring3的应用程序,fs:[0]的地址指向的是TEB结构,这个结构的开头是一个NT_TIB结构,NT_TIB结构的0x18偏移处是一个Self指针,指向这个结构自身,也就是指向TEB结构的开头。
TEB结构的0x30偏移是一个指向PEB的指针。PEB又是一个结构,这个结构的0x2偏移处是一个...[/QUOTE]
好像LZ问的是FS段初始化的问题
2009-4-14 14:18
0
雪    币: 270
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
问题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:11
0
雪    币: 270
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
问题2具体内容可以看老罗的Windows环境下32位汇编语言,第一章里有介绍
2009-4-14 15:12
0
雪    币: 137
活跃值: (430)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
貌似是GetLastError()代码
2009-4-14 15:25
0
雪    币: 229
活跃值: (503)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
8
谢谢,楼上各位。。。
有些懂了
2009-4-14 16:32
0
雪    币: 224
活跃值: (147)
能力值: ( LV9,RANK:970 )
在线值:
发帖
回帖
粉丝
9
typedef struct _PEB
{
   UCHAR InheritedAddressSpace;                     // 00h
   UCHAR ReadImageFileExecOptions;                  // 01h
   UCHAR BeingDebugged;                             // 02h
   UCHAR Spare;                                     // 03h
...................
2009-4-14 17:08
0
雪    币: 204
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
说说问题二吧,这里我用实例证明一下。

我这里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
2009-4-14 17:11
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
11
学习3456
2009-4-14 17:30
0
雪    币: 229
活跃值: (503)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
12
请问有哪些资料详细介绍这方面的知识。。。
麻烦介绍下,谢了。。
老兄度过有相关资料的话。可不可以发我邮箱里
4378wslm@163.com
2009-4-14 18:05
0
雪    币: 204
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
名叫《Intel@64 and IA-32 Architectures Software Developer Manual》的pdf文档,自己google吧。顺便八卦一下,内事不决问百度,外事不决问谷歌
2009-4-14 18:14
0
雪    币: 270
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
高手和菜鸟的区别不仅是知识上的差别,更重要的是高手懂得解决问题方法。
2009-4-14 22:55
0
雪    币: 270
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
很详细,学习了
2009-4-14 22:55
0
游客
登录 | 注册 方可回帖
返回
//