FS寄存器

来源:互联网 发布:对接软件的php会员源码 编辑:程序博客网 时间:2024/05/16 15:40

FS寄存器指向当前活动线程的TEB结构(线程结构)

偏移  说明

000  指向SEH链指针

004  线程堆栈顶部

008  线程堆栈底部

00C  SubSystemTib

010  FiberData

014  ArbitraryUserPointer

018  FS段寄存器在内存中的镜像地址

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基址

 

实例分析:如何用FS寄存器查找KERNEL32.DLL

 

在shellcode中用它来找KERNEL32.DLL基地址是常见的算法了,经典的三种算法都用到了FS寄存器!她们是:

 

1.       通过PEB(FS:[30])获取KERNEL32.DLL基地址

 

2.       通过TEB(FS:[18])获取KERNEL32.DLL基地址

 

3.       通过SEH(FS:[00])获取KERNEL32.DLL基地址

 

命题一:通过PEB(FS:[30])获取KERNEL32.DLL基地址

 

算法描述:

 

mov eax,fs:[30h]     ;得到PEB结构地址

 

mov eax,[eax + 0ch]  ;得到PEB_LDR_DATA结构地址

 

mov esi,[eax + 1ch]  

 

lodsd  ; 得到KERNEL32.DLL所在LDR_MODULE结构的

 

; InInitializationOrderModuleList地址

 

mov edx,[eax + 8h]   ;得到BaseAddress,既Kernel32.dll基址

 

 

 

证明:

 

1.       随便open一个exe,内存中的KERNEL32.DLL基地址是不变的;

 

2.       获取PEB基地址,

 

0:000> dd fs:30 L1

 

003b:00000030  7ffd6000

 

看到了,7ffd6000

 

3.       获取PEB_LDR_DATA结构地址7ffd6000+0c

 

peb的结构定义:

 

ntdll!_PEB

 

   +0x000 InheritedAddressSpace : UChar

 

   +0x001 ReadImageFileExecOptions : UChar

 

   +0x002 BeingDebugged    : UChar

 

   +0x003 SpareBool        : UChar

 

   +0x004 Mutant           : Ptr32 Void

 

   +0x008 ImageBaseAddress : Ptr32 Void

 

   +0x00c Ldr              : Ptr32 _PEB_LDR_DATA

 

   +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS

 

   +0x014 SubSystemData    : Ptr32 Void

 

   +0x018 ProcessHeap      : Ptr32 Void

 

   +0x01c FastPebLock      : Ptr32 _RTL_CRITICAL_SECTION

 

......

 

0:000>  dd 7ffd6000+0c L1

 

7ffd600c  00181ea0

 

PEB_LDR_DATA-> 00181ea0

 

4.       获取InInitializationOrderModuleList的地址

 

说一下这个PEB_LDR_DATA,她是ntdll.dll中的undocumented的一个结构,PEB_LDR_DATA的结构定义:

 

0:000> dt _PEB_LDR_DATA

 

   +0x000 Length           : Uint4B

 

   +0x004 Initialized      : UChar

 

   +0x008 SsHandle         : Ptr32 Void

 

   +0x00c InLoadOrderModuleList : _LIST_ENTRY

 

   +0x014 InMemoryOrderModuleList : _LIST_ENTRY

 

   +0x01c InInitializationOrderModuleList : _LIST_ENTRY

 

   +0x024 EntryInProgress  : Ptr32 Void

 

0:000> dd 00181ea0+1c L1

 

00181ebc  00181f58

 

InInitializationOrderModuleList->00181f58

 

5.       获取kernel32的基地址

 

0:000> dd 00181f58+8 L1

 

00181f60  7c920000

 

7c920000就是了?

 

check一下:

 

0:000> dd kernel32 L1

 

7c800000  00905a4d

 

啊!竟然不是啊,7c920000是ntdll.dll的,哈哈。

 

不过,算法命题仍然是正确的。因为在shellcode中模块列表的第一个就是kernel32了,当然可以通过镜像名称来check的,不过shellcode的空间不允许的,这就是shellcode的艺术了。我用来测试的exe恰好先加载了ntdll.dll。

 

 

 

命题二:通过TEB(FS:[18])获取KERNEL32.DLL基地址

 

算法描述:

 

本地线程的栈里偏移18H的指针指向kernel32.dll内部,而fs :[ 0x18 ] 指向当前线程而且往里四个字节指向线程栈,结合栈顶指针进行对齐遍历,找到PE文件头(DLL的文件格式)的“MZ”MSDOS标志,就拿到了kernel32.dll基址。

 

xor esi , esi

 

mov esi , fs :[ esi + 0x18 ] // TEB

 

mov eax , [ esi + 4 ] // 这个是需要的栈顶

 

mov eax , [ eax - 0x1c ] // 指向Kernel32.dll内部

 

find_kernel32_base :

 

dec eax // 开始地毯式搜索Kernel32空间

 

xor ax , ax

 

cmp word ptr [ eax ], 0x5a4d // "MZ"

 

jne find_kernel32_base // 循 环遍 历 ,找到 则 返回 eax

 

 

 

证明:

 

1.       找到TEB,这个好办:

 

0:000>  dd fs:18 L1

 

003b:00000018  7ffdd000

 

TEB->7ffdd000

 

2.       找到栈顶指针:

 

0:000> dd 7ffdd000+4 L1

 

7ffdd004  00070000

 

3.       进入Kernel32空间:

 

0:000> dd 00070000-1c L1

 

0006ffe4  7c839aa8

 

 

 

4.       Kernel32空间的大搜索:

 

0:000> db 7c839aa7 L4

 

7c839aa7  30 55 8b ec                                      0U..

 

......一直搞下去

 

0:000> db 7c800000 L4

 

7c800000  4d 5a 90 00                                      MZ..

 

找到了吧,哈哈。有点效率问题,shellcode有时候是要牺牲效率的,没办法,还是艺术问题。

 

 

 

命题三:通过SEH(FS:[00])获取KERNEL32.DLL基地址

 

算法描述:

 

注意:FS:[ 0 ] 指向的是SHE,它指向kernel32.dll内部链,这样就可以顺藤摸瓜了。FS:[ 0 ] 指向的是SHE的内层链,为了找到顶层异常处理,我们向外遍历找到prev成员等于 0xffffffff 的EXCEPTION_REGISTER结构,该结构的handler值就是系统 默 认的处理例程;这里有个细节,DLL的装载是64K边界对齐的,所以需要利用遍历到的指向最后的异常处理的指针进行页查找,再结合PE文件MSDOS标志部分,只要在每个 64K 边界查找 “MZ ”字符就能找到kernel32.dll基址。

 

xor ecx , ecx

 

mov esi , fs :[ ecx ]

 

find_seh :

 

mov eax ,[ esi ]

 

mov esi , eax

 

cmp [ eax ], ecx

 

jns find_seh // 0xffffffff

 

mov eax , [ eax + 0x04 ] // handler

 

find_kernel32_base :

 

dec eax

 

xor ax , ax

 

cmp word ptr [ eax ], 0x5a4d

 

jne find_kernel32_base

 

 

 

证明:

 

1.       找到当前SEH:

 

0:000> dd fs:0 L1

 

003b:00000000  0006fedc

 

2.       找到最外层SEH:

 

round 1:

 

0:000> dd 0006fedc L1

 

0006fedc  0006ffb0 ; esi

 

0:000> dd 0006ffb0 L1

 

0006ffb0  0006ffe0 ; [eax]

 

round 2:

 

0:000> dd 0006ffb0 L1

 

0006ffb0  0006ffe0 ; esi

 

0:000> dd 0006ffe0 L1

 

0006ffe0  ffffffff ; [eax]

 

不错,第二趟就找到了!此时,eax=0006ffe0

 

3.       找到MZ:

 

0:000> dd 0006ffe0+4 L1

 

0006ffe4  7c839aa8

 

 

 

0:000> db 7c839aa7 L4

 

7c839aa7  30 55 8b ec                                      0U..

 

......又是一直搞下去

 

0:000> db 7c800000 L4

 

7c800000  4d 5a 90 00                                      MZ..

 

找到!

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 交易猫买的号被找回了怎么办 uc上我的小说看不了怎么办 微信零钱忘记密码没有银行卡怎么办 九游平台冻结提不了现怎么办 计算机考试报名登录名忘记了怎么办 云顶扑克提现怎么提不出来怎么办 微信正在下载一直0kb怎么办 守望先锋运行时出现意外错误怎么办 信用卡暂停使用怎么办还能恢复吗 新刷乳胶漆墙面一碰一个坑怎么办 夏天开空调冻着了头疼打喷嚏怎么办 桑蚕丝衣服被沐浴露退了色怎么办 空间被别人知道了密码登录了怎么办 三星手机显示解析包出现问题怎么办 三星手机下载解析包出现问题怎么办 两万的流动大棚给整坏了怎么办 劲舞团抽奖领了一样的衣服怎么办 win系统ps界面字体太小怎么办 任何网页都变成监控登录界面怎么办 微信启动录音的尝试被拒绝怎么办 微信传到电脑的文件打不开怎么办 转转网账号出租时遇到防沉迷怎么办 如果买了王者号结果有防沉迷怎么办 苹果手机一直显示验证失败怎么办呢 安装包证书异常导致安装失败怎么办 qq飞车忘了几区的怎么办 5e在游戏里卡住不动怎么办 别人发的cdr文件打开太慢怎么办 qq红包充值话费未到账怎么办 qq飞车充值至尊皇冠不到账怎么办 微信支付金额超过单日限制怎么办 不小心在qq钱包中充错话费怎么办 衣服质量不好穿了几次就坏了怎么办 手机丢了找到手机店的人怎么办 在手机店买手机买贵了怎么办 王者荣耀好多没对的东西怎么办 用电脑玩游戏键盘不管用怎么办? 王者荣耀跨系统送皮肤领不到怎么办 电脑使用迅雷时提示缓存过高怎么办 扣扣安全中心动态密码忘记了怎么办 pu管两头固定了中间换截怎么办