fs寄存器

利用FS寄存器获取KERNEL32.DLL基址算法的证明FS寄存器指向当前活动线程的TEB结构(线程结构)偏移  说明000  指向SEH链指针004  线程堆栈顶部008  线程堆栈底部00C  SubSystemTib010  FiberData014  ArbitraryUserPointer018  FS段寄存器在内存中的镜像地址020  进程PID024  线程ID02C  指向线程局部存储指针030  PEB结构地址(进程结构)034  上个错误号 在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 L1003b:00000030  7ffd6000看到了,7ffd60003.       获取PEB_LDR_DATA结构地址7ffd6000+0cpeb的结构定义: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 L17ffd600c  00181ea0PEB_LDR_DATA-> 00181ea0 4.       获取InInitializationOrderModuleList的地址说一下这个PEB_LDR_DATA,她是ntdll.dll中的u ndocumented的一个结构,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 Void0:000> dd 00181ea0+1c L100181ebc  00181f58InInitializationOrderModuleList->00181f585.       获取kernel32的基地址0:000> dd 00181f58+8 L100181f60  7c9200007c920000就是了?check一下:0:000> dd kernel32 L17c800000  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 , esimov esi , fs :[ esi + 0x18 ] // TEBmov eax , [ esi + 4 ] // 这个是需要的栈顶mov eax , [ eax - 0x1c ] // 指向Kernel32.dll内部find_kernel32_base :dec eax // 开始地毯式搜索Kernel32空间xor ax , axcmp word ptr [ eax ], 0x5a4d // "MZ"jne find_kernel32_base // 循 环遍 历 ,找到 则 返回 eax 证明:1.       找到TEB,这个好办:0:000>  dd fs:18 L1003b:00000018  7ffdd000TEB->7ffdd0002.       找到栈顶指针:0:000> dd 7ffdd000+4 L17ffdd004  000700003.       进入Kernel32空间:0:000> dd 00070000-1c L10006ffe4  7c839aa8 4.       Kernel32空间的大搜索:0:000> db 7c839aa7 L47c839aa7  30 55 8b ec                                      0U........一直搞下去0:000> db 7c800000 L47c800000  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 , ecxmov esi , fs :[ ecx ]find_seh :mov eax ,[ esi ] mov esi , eaxcmp [ eax ], ecxjns find_seh // 0xffffffffmov eax , [ eax + 0x04 ] // handlerfind_kernel32_base :dec eaxxor ax , axcmp word ptr [ eax ], 0x5a4djne find_kernel32_base 证明:1.    &n bsp;  找到当前SEH: 0:000> dd fs:0 L1003b:00000000  0006fedc2.       找到最外层SEH:round 1:0:000> dd 0006fedc L10006fedc  0006ffb0 ; esi0:000> dd 0006ffb0 L10006ffb0  0006ffe0 ; [eax]round 2:0:000> dd 0006ffb0 L10006ffb0  0006ffe0 ; esi0:000> dd 0006ffe0 L10006ffe0  ffffffff ; [eax]不错,第二趟就找到了!此时,eax=0006ffe03.       找到MZ:0:000> dd 0006ffe0+4 L10006ffe4  7c839aa8 0:000> db 7c839aa7 L47c839aa7  30 55 8b ec                                      0U........又是一直搞下去0:000> db 7c800000 L47c 800000  4d 5a 90 00                                      MZ.. 找到! 知其然,更要知其所以然!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值