这两天稍微学习了一下寄存器相关知识,很多人说为什么进程、线程一些重要信息可以通过FS寄存器简单的取到?
kd> u PsLookupProcessByProcessId
nt!PsLookupProcessByProcessId:
805ca38a 8bff mov edi,edi
805ca38c 55 push ebp
805ca38d 8bec mov ebp,esp
805ca38f 53 push ebx
805ca390 56 push esi
805ca391 64a124010000 mov eax,dword ptr fs:[00000124h]
805ca397 ff7508 push dword ptr [ebp+8]
805ca39a 8bf0 mov esi,eax
kd> u PsGetCurrentProcess
nt!IoGetCurrentProcess:
804ef608 64a124010000 mov eax,dword ptr fs:[00000124h]
804ef60e 8b4044 mov eax,dword ptr [eax+44h]
804ef611 c3 ret
804ef612 cc int 3
804ef613 cc int 3
804ef614 cc int 3
804ef615 cc int 3
804ef616 cc int 3
kd> u PsGetCurrentThread
nt!PsGetCurrentThread:
8052890c 64a124010000 mov eax,dword ptr fs:[00000124h]
80528912 c3 ret
80528913 cc int 3
80528914 cc int 3
80528915 cc int 3
80528916 cc int 3
80528917 cc int 3
nt!PsGetCurrentThreadStackBase:
80528918 64a124010000 mov eax,dword ptr fs:[00000124h]
可以看到 都有个 fs:[00000124h],我们先 r 一下看看fs的值:
kd> r
eax=00000001 ebx=ffdff980 ecx=8054bd4c edx=000002f8 esi=00000000 edi=1d399334
eip=80528bdc esp=8054abd0 ebp=8054abe0 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000202
nt!RtlpBreakWithStatusInstruction:
80528bdc cc int 3
可见在内核态中 fs=0x30,我们.formats 0x40看一下:
kd> .formats 0x30
Evaluate expression:
Hex: 00000030
Decimal: 48
Octal: 00000000060
Binary: 00000000 00000000 00000000 00110000
Chars: ...0
Time: Thu Jan 01 08:00:48 1970
Float: low 6.72623e-044 high 0
Double: 2.37152e-322
然后查一下intel手册,对比一下:
可以看到: RPL:0 TI:0 INDEX:6
也就是序号为6,如下:
kd> r gdtr
gdtr=8003f000
取全局描述符gdtr = 8003f000,
kd> dq 8003f000
8003f000 00000000`00000000 00cf9b00`0000ffff
8003f010 00cf9300`0000ffff 00cffb00`0000ffff
8003f020 00cff300`0000ffff 80008b04`200020ab
8003f030 ffc093df`f0000001 0040f300`00000fff
8003f040 0000f200`0400ffff 00000000`00000000
8003f050 80008954`af000068 80008954`af680068
8003f060 00009302`2f40ffff 0000920b`80003fff
8003f070 ff0092ff`700003ff 80009a40`0000ffff
选取第六个:ffc093df`f0000001,分别.formats一下
kd> .formats ffc093df
Evaluate expression:
Hex: ffc093df
Decimal: -4156449
Octal: 37760111737
Binary: 11111111 11000000 10010011 11011111
Chars: ....
Time: ***** Invalid
Float: low -1.#QNAN high -1.#QNAN
Double: -1.#QNAN
kd> .formats f0000001
Evaluate expression:
Hex: f0000001
Decimal: -268435455
Octal: 36000000001
Binary: 11110000 00000000 00000000 00000001
Chars: ....
Time: ***** Invalid
Float: low -1.58456e+029 high -1.#QNAN
Double: -1.#QNAN
接下来继续查看intel手册:
根据手册将:
Binary: 11111111 11000000 10010011 11011111
Binary: 11110000 00000000 00000000 00000001
拼接 起来:
Base Address:11111111 11011111 11110000 00000000
转化为16进制:FFDFF000
看到这里是不是特别熟悉了!没错就是KPCR结构,接下来就应该明白为什么可以通过FS寄存器简单取到进程、线程的信息了吧!
以上是单核win xp 系统的分析。xp的FFDFF000地址是固定不变的。