__RTC_CheckEsp
es una llamada que verifica la exactitud del esp
, apilar, registrar. Se llama para garantizar que el valor de esp
se guardó en una llamada de función.¿Cómo se implementa __RTC_CheckEsp?
¿Alguien sabe cómo se implementa?
__RTC_CheckEsp
es una llamada que verifica la exactitud del esp
, apilar, registrar. Se llama para garantizar que el valor de esp
se guardó en una llamada de función.¿Cómo se implementa __RTC_CheckEsp?
¿Alguien sabe cómo se implementa?
Si usted es bueno en asm, tal vez esto ayuda a:
JNE (Saltar si no igual) - Salta si el flag de cero es 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
bien un poco de inspección del ensamblador lo regala
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)
Hay 2 líneas a tener en cuenta en esto. Primera nota en 0x44ee35 almacena el valor actual de esp a esi.
Luego, una vez completada la llamada a la función, realiza un cmp entre esp y esi. Ambos deberían ser lo mismo ahora. Si no lo están, alguien ha desenrollado la pila dos veces o no la ha desenrollado.
La función _RTC_CheckEsp se ve así:
_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
Como se puede ver la primera cosa que comprobar es si el resultado de la comparación anterior no eran "iguales", es decir esi = esp!. Si ese es el caso, salta al código de falla. Si SON iguales, la función simplemente regresa.
Bien, olvidé el código de llamada ... –
¿Por qué tantos 'int 3', no es suficiente? – ollydbg
'int 3' es un byte, y es la interrupción del punto de interrupción. Por lo tanto, ese valor de byte se usa tradicionalmente como relleno entre funciones. (específico de x86 por supuesto). Tenga en cuenta que es inalcanzable, cero sería suficiente, de hecho. – MSalters
La razón por la que se complementan con eso es que si se produce un salto no válido en int 3s, el código se romperá de inmediato y podrá ver fácilmente que se ha producido un salto no válido. – Goz