2010-10-12 165 views
6

__RTC_CheckEsp是一个调用,用于验证esp,堆栈,寄存器的正确性。它被调用以确保esp的值在函数调用中保存。__RTC_CheckEsp如何实现?

任何人都知道它是如何实现的?

回答

1

如果你在任何ASM好,也许这会有所帮助:

JNE(不相等则跳转) - 跳转,如果零标志为NZ(NotZero)

_RTC_CheckEsp: 
004C8690 jne   esperror (4C8693h) 
004C8692 ret    
esperror: 
004C8693 push  ebp 
004C8694 mov   ebp,esp 
004C8696 sub   esp,0 
004C8699 push  eax 
004C869A push  edx 
004C869B push  ebx 
004C869C push  esi 
004C869D push  edi 
004C869E mov   eax,dword ptr [ebp+4] 
004C86A1 push  0  
004C86A3 push  eax 
004C86A4 call  _RTC_Failure (4550F8h) 
004C86A9 add   esp,8 
004C86AC pop   edi 
004C86AD pop   esi 
004C86AE pop   ebx 
004C86AF pop   edx 
004C86B0 pop   eax 
004C86B1 mov   esp,ebp 
004C86B3 pop   ebp 
004C86B4 ret    
004C86B5 int   3  
004C86B6 int   3  
004C86B7 int   3  
004C86B8 int   3  
004C86B9 int   3  
004C86BA int   3  
004C86BB int   3  
004C86BC int   3  
004C86BD int   3  
004C86BE int   3  
004C86BF int   3 
+0

为什么这么多'int 3',是不是一个足够? – ollydbg 2010-10-12 13:14:08

+2

“int 3”是一个字节,它是断点中断。因此,该字节值传统上用作函数之间的填充。 (当然是x86)。请注意,它无法访问,实际上零就足够了。 – MSalters 2010-10-12 13:19:42

+3

他们的理由是,如果在int 3s中发生无效跳转,那么代码将立即中断,您可以轻松看到发生了无效跳转。 – Goz 2010-10-13 07:40:49

5

那么一点点汇编程序的检查将其发送出去

0044EE35 mov   esi,esp 
0044EE37 push  3039h 
0044EE3C mov   ecx,dword ptr [ebp-18h] 
0044EE3F add   ecx,70h 
0044EE42 mov   eax,dword ptr [ebp-18h] 
0044EE45 mov   edx,dword ptr [eax+70h] 
0044EE48 mov   eax,dword ptr [edx+0Ch] 
0044EE4B call  eax 
0044EE4D cmp   esi,esp 
0044EE4F call  @ILT+6745(__RTC_CheckEsp) (42BA5Eh) 

有两条注意事项。首先在0x44ee35注释它将esp的当前值存储到esi。

然后,函数调用完成后,它执行esp和esi之间的cmp。他们现在应该都是一样的。如果他们不是,那么有人要么两次解开堆叠,要么没有解开它。

的_RTC_CheckEsp功能如下:

_RTC_CheckEsp: 
00475A60 jne   esperror (475A63h) 
00475A62 ret    
esperror: 
00475A63 push  ebp 
00475A64 mov   ebp,esp 
00475A66 sub   esp,0 
00475A69 push  eax 
00475A6A push  edx 
00475A6B push  ebx 
00475A6C push  esi 
00475A6D push  edi 
00475A6E mov   eax,dword ptr [ebp+4] 
00475A71 push  0  
00475A73 push  eax 
00475A74 call  _RTC_Failure (42C34Bh) 
00475A79 add   esp,8 
00475A7C pop   edi 
00475A7D pop   esi 
00475A7E pop   ebx 
00475A7F pop   edx 
00475A80 pop   eax 
00475A81 mov   esp,ebp 
00475A83 pop   ebp 
00475A84 ret    

正如你可以看到它检查的第一件事是较早比较的结果是否是“不等于”即ESI = ESP!如果是这种情况,那么它跳转到失败代码。如果它们相同,那么函数只是返回。

+0

不错,我忘记了调用代码... – 2010-10-12 12:56:27