欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

ESP定律背后的原理之一:0x12FFC4,为什么是这个数

ESP定律背后的原理之一:0x12FFC4,为什么是这个数

ESP定律背后的原理之一:0x12FFC4
ESP定律:如果压缩壳执行前后的堆栈会维持平衡,在12FFC0上下读写断点,会中断在OEP的第一条指令push ebp上。那么各位有没有探究过ESP的尾数值为什么不是0xFFFC,而是0x0FFC4?这是由windows源代码的实现所确定的。
Windows创建进程的函数链为kernel32.dll!_CreateProcessInternalW -> … -> kernel32.dll!_BaseProcessStartThunk() -> kernel32.dll!_BaseProcessStart() -> EP
在进入_BaseProcessStartThunk()时,堆栈的状态确实为
+ 0012FFFC   00000000                <- ESP
---------------------------------------------------------<code>
   _BaseProcessStartThunk@8 proc near
xor     ebp, ebp
push    eax
push    0
jmp     _BaseProcessStart@4 ; BaseProcessStart(x)
_BaseProcessStartThunk@8 endp
----------------------------------------------------------</code>
在执行完_BaseProcessStartThunk时,堆栈的状态为
+ 0012FFFC   00000000                
+ 0012FFF8   EAX
+ 0012FFF4   0x00000000             <- ESP
    
---------------------------------------------------------<code>
    _BaseProcessStart proc
push    0Ch
push    offset dword_7C816FE0
call    __SEH_prolog
and     [ebp+ms_exc.disabled], 0
push    4
lea     eax, [ebp+8]
push    eax
push    9
push    0FFFFFFFEh
call    ds:__imp__NtSetInformationThread@16 ; NtSetInformationThread(x,x,x,x)
call    dword ptr [ebp+8]
push    eax             ; dwExitCode
call    _ExitThread@4
nop
nop
nop
---------------------------------------------------------</code>
在执行完BaseProcessStart()后,堆栈的状态为
+ 0012FFFC   0x00000000
+ 0012FFF8   OldEAX -2-> EntryPoint By NtSetInformationThread()
+ 0012FFF4   reserved, inited to 0x00000000
+ 0012FFF0   OldEBP(0x00000000)    <-p- NowEBP
+ 0012FFEC   TryLevel, inited to 0xFFFFFFFF
+ 0012FFE8   ScopeTable
+ 0012FFE4   __except_handler3 in kernel32.dll
+ 0012FFE0   0xFFFFFFFF            <-p- fs:00h
+ 0012FFDC   ExceptionInfo, Parameter of UnhandledExceptionFilter()
+ 0012FFD8   OldESP(0x0012FFC8)
+ 0012FFD4   ExceptionCode, Parameter of kernel32.dll!ExitProcess
+ 0012FFD0   EBX(pPEB)
+ 0012FFCC   ESI
+ 0012FFC8   EDI                   <-p- OldESP
+ 0012FFC4   retaddr in kernel32.dll!_BaseProcessStartThunk
                                               <-p- NowESP

附:
    DWORD   SizeOfStackReserve;                         // 0x48-4b
    DWORD   SizeOfStackCommit;                          // 0x4c-4f
    DWORD   SizeOfHeapReserve;                          // 0x50-53
    DWORD   SizeOfHeapCommit;                           // 0x54-57
这是IOH中的四个域。
Reserved保留的, Committed提交的是两种类型的虚拟内存。
Reserved指这段内存已有用途,不能再被分配;Committed提交的内存指的是已经与物理内存有映射的虚拟内存段(当然也可以被移到硬盘上的缓存文件pagefile.sys中)。因为Stack, Heap这两种类型的内存段都有随着程序的运行尺寸不断增大的特性,所以一开始不必占用太多宝贵的物理内存,当它们用完了,会引发内存异常,windows内存管理器就又为程序分配一部分。
SizeOfStackReserve  程序开始时保留用作堆栈空间的内存段的大小
SizeOfStackCommit   程序开始时在保留的堆栈内存段中与物理内存映射的提交的内存段的大小
SizeOfHeapReserve  程序开始时保留用作堆空间的内存段的大小
SizeOfHeapCommit   程序开始时在保留的堆内存段中与物理内存映射的提交的内存段的大小

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功