Test Foro de elhacker.net SMF 2.1

Programación => Ingeniería Inversa => Mensaje iniciado por: Mad Antrax en 27 Febrero 2013, 12:03 PM

Título: Como comprobar si mi código asm ha cambiado?
Publicado por: Mad Antrax en 27 Febrero 2013, 12:03 PM
Hola, vengo con una pregunta un tanto rara.

Me gustaría saber, si existe alguna forma para comprobar X offsets de un ejecutable.

Es decir, un programa que se auto-desensamble y compruebe si parte de su código ha sido modificado o no (una simple comprobación CRC de un array de bytes o comprobar byte por byte, por ejemplo)

Supongamos que conozco exactamente el offset de mi ejecutable que contiene un salto condicional crítico. Dicho offset debería tener un JE, ejemplo:

013B1CE5  74 0C         JE SHORT Bioshock.013B1CF3

Que API's debería utilizar para leer el offset 013B1CE5 y comprobar si tiene el byte 74 o 75?

Digamos que la comprobación no la quiero hacer en el propio ejecutable, si no cuando está ejecutándose (en memoria).

Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: Karcrack en 27 Febrero 2013, 13:31 PM
Lo mejor sería hacer la suma de comprobación del bloque de memoria crítica. Bastaría con leer la memoria del proceso a proteger con ReadProcessMemory() y tras realizar el checksum comparar.
En caso de que hubiese discrepancia y pretendieses reparar la zona de memoria lo adecuado sería suspender el hilo de ejecución con SuspendThread() y después de WriteProcessMemory() resumirlo con ResumeThread().

En caso de que sólo quieras proteger la memoria del proceso durante la ejecución puedes meter un breakpoint de escritura en ese zona de memoria.
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: Mad Antrax en 27 Febrero 2013, 14:34 PM
Cita de: Karcrack en 27 Febrero 2013, 13:31 PM
Lo mejor sería hacer la suma de comprobación del bloque de memoria crítica. Bastaría con leer la memoria del proceso a proteger con ReadProcessMemory() y tras realizar el checksum comparar.
En caso de que hubiese discrepancia y pretendieses reparar la zona de memoria lo adecuado sería suspender el hilo de ejecución con SuspendThread() y después de WriteProcessMemory() resumirlo con ResumeThread().

En caso de que sólo quieras proteger la memoria del proceso durante la ejecución puedes meter un breakpoint de escritura en ese zona de memoria.

Gracias por contestar, vamos por partes:

No necesito reparar la zona de memoria modificada, así que el suspendthread y writeprocessmemory no lo necesitaría. Solo quiero leer un bloque de offsets y comprobar, si no coinciden finalizar la ejecución del programa y listo.

Ahora mismo estoy fuera, en un par de horas estaré en mi casa. Compilo un ejemplo de código y te digo los offsets que quiero comprobar, a ver si me puedes dar un ejemplo hecho (en VB6), te parece?

Por mi parte, ayer estuve haciendo pruebas con ReadProcessMemory, pero no logré objeter los bytes que correspondian al offset, supongo que lo hice mal a la hora de pasar los parámetros a la API, por eso necesito tu ayuda a modo de ejemplo :D

Te envio MP cuando lo tenga
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: Mad Antrax en 27 Febrero 2013, 17:16 PM
Vale, ya estoy aqui, te dejo un ejemplo muy sencillo para que pueda aprender.

Tras analizar el código en OllyDbg, el offset que quiero proteger es el siguiente:

00401C7E     74 44         JE SHORT ejemplo.00401CC4

Teniendo en cuenta que la Base es 00401000 o a veces es 00403000 puedo deducir que el offset es: BASE+1C7E ¿lo digo bien?

Bueno, pues lo que quiero es un simple timer que compruebe el valor del offset BASE+1C7E y verifique si ha cambiado. Suena sencillo, pero me estoy dando hostias contra un muro que no veo, no se hacerlo xD.

Luego, para rizar el rizo, como comprobar un grupo de offsets, por ejemplo:

00401C21   7D 12                          JGE SHORT ejemplo.00401C35
00401C23   68 A0000000                    PUSH 0A0
00401C28   68 101A4000                    PUSH ejemplo.00401A10
00401C2D   57                             PUSH EDI
00401C2E   50                             PUSH EAX
00401C2F   FF15 14104000                  CALL DWORD PTR DS

Puedes ayudarme? Te dejo el link del ejecutable de prueba:

http://www.mediafire.com/?jle3dupeb7sbmmw
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: Karcrack en 27 Febrero 2013, 17:58 PM
Código (vb) [Seleccionar]
Option Explicit

'KERNEL32
Private Declare Function OpenProcess Lib "KERNEL32" (ByVal dwDA As Long, ByVal bIH As Integer, ByVal dwPID As Long) As Long
Private Declare Sub CloseHandle Lib "KERNEL32" (ByVal hObject As Long)
Private Declare Function ReadProcessMemory Lib "KERNEL32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
'NTDLL
Private Declare Function NtQueryInformationProcess Lib "NTDLL" (ByVal ProcessHandle As Long, ByVal InformationClass As Long, ByRef ProcessInformation As Any, ByVal ProcessInformationLength As Long, ByRef ReturnLength As Any) As Long
   
Private Const PROCESS_VM_READ           As Long = &H10
Private Const PROCESS_QUERY_INFORMATION As Long = &H400

Private Const ProcessBasicInformation = 0

Private Type PROCESS_BASIC_INFORMATION
   ExitStatus                      As Long
   PebBaseAddress                  As Long
   AffinityMask                    As Long
   BasePriority                    As Long
   UniqueProcessId                 As Long
   InheritedFromUniqueProcessId    As Long
End Type

Private Const MY_REL_POS    As Long = &H1C7E
Private Const MY_SIZE       As Long = &HF

Sub Main()
   Dim lPID    As Long
   Dim hProc   As Long
   Dim bvBuf() As Byte
   
   Do
       lPID = Val(InputBox("PID a proteger?"))
   Loop Until lPID > 0
   
   hProc = OpenProcess(PROCESS_QUERY_INFORMATION + PROCESS_VM_READ, False, lPID)
   
   If hProc Then
       ReDim bvBuf(0 To MY_SIZE)
       If ReadProcessMemory(hProc, GetBaseAddr(hProc) + MY_REL_POS, bvBuf(0), MY_SIZE, ByVal 0&) Then
           Debug.Print Hex$(bvBuf(0))
       End If
       Call CloseHandle(hProc)
   End If
End Sub

Private Function GetBaseAddr(ByVal hProc As Long) As Long
   Dim PBI     As PROCESS_BASIC_INFORMATION
   
   Call NtQueryInformationProcess(hProc, ProcessBasicInformation, PBI, Len(PBI), Len(PBI))
   If PBI.PebBaseAddress Then
       Call ReadProcessMemory(hProc, PBI.PebBaseAddress + 8, GetBaseAddr, 4, ByVal 0)
   End If
End Function


La obtención del BaseAddr del proceso no funcionará si el proceso es de 64bits.
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: Mad Antrax en 27 Febrero 2013, 18:33 PM
Muchisimas gracias, voy a probarlo ahora mismo, tengo que hacer pruebas con el código que me ofreces, pero pinta perfecto :P

Gracias de nuevo
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: MCKSys Argentina en 27 Febrero 2013, 19:07 PM
Si no entendí mal, el EXE se comprobaría a si mismo, por lo que ReadProcessMemory no seria necesario.

Bastaria con un "GetMem" de la direccion en concreto y listo...

O bien, entendí mal...  :P
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: Mad Antrax en 27 Febrero 2013, 19:18 PM
Cita de: MCKSys Argentina en 27 Febrero 2013, 19:07 PM
Si no entendí mal, el EXE se comprobaría a si mismo, por lo que ReadProcessMemory no seria necesario.

Bastaria con un "GetMem" de la direccion en concreto y listo...

O bien, entendí mal...  :P

Sí, el propio EXE se comprueba a si mismo. No conozco la API GetMem... :(
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: Karcrack en 27 Febrero 2013, 19:26 PM
Pensé que querías proteger desde otro proceso :xD
Código (vb) [Seleccionar]
Private Declare Sub GetMem4 Lib "MSVBVM60" (ByVal Addr As Long, RetVal As Long)
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: MCKSys Argentina en 27 Febrero 2013, 19:34 PM
Bueno, estaba buscando los "hacks" de Karcrack y me doy cuenta que es él quien estaba respondiendo asi que nada que hacer por estos lados...  :silbar:

PD @||MadAntrax||: Seguro lo sabes pero te recuerdo que esa "API" lee 4 bytes (1 DWORD).

Saludos!
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: Mad Antrax en 27 Febrero 2013, 19:43 PM
Pensándolo bien, mejor haré un sub-proceso que compruebe la memoria del EXE primario, será más sencillo y la protección la podré exportar fácilmente a otros proyectos.

Usaré el código con ReadProcessMemory que ha puesto karcrack, lo he testeado con mi ejemplo y funciona de maravilla :P

Ahora toca modificarlo para que compruebe toda la memoria del EXE en un timer, y cuando cambie un byte -> mostrar una alerta. A ver si me sale :S
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: MCKSys Argentina en 27 Febrero 2013, 20:28 PM
@||MadAntrax||: Hace un tiempo hice un crackme que, entre otras cosas, tenia comprobacion del codigo de un evento.

El post es este: http://foro.elhacker.net/empty-t356892.0.html (http://foro.elhacker.net/empty-t356892.0.html)

Si lo deseas, esta noche subo el codigo fuente del crackme, pero lo recomendable aqui no es ver el source del crackme, sino el tutorial de la solucion que encontro Thunder: http://www.mediafire.com/file/spob6r4g8y92sel/Crackme4.By.MCKSysArgentina_Keygen.By.Thunder.rar (http://www.mediafire.com/file/spob6r4g8y92sel/Crackme4.By.MCKSysArgentina_Keygen.By.Thunder.rar)

Aun hoy dia me sorprende el nivel de reversing aplicado...

Saludos!
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: tincopasan en 28 Febrero 2013, 01:31 AM
MCKSys
              podrías subir el tutorial a otro server o cambiarle el nombre? esa bosta de mediafire bloquea cualquier archivo q diga crack o derivados. Gracias y perdón por joder.
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: MCKSys Argentina en 28 Febrero 2013, 04:04 AM
Está en la web de ricnar: http://ricardonarvaja.info/WEB/CURSO%20NUEVO/TEORIAS%20NUMERADAS/1401-1500/1443-Crackme4.By.MCKSysArgentina_Keygen.By.Thunder.rar (http://ricardonarvaja.info/WEB/CURSO%20NUEVO/TEORIAS%20NUMERADAS/1401-1500/1443-Crackme4.By.MCKSysArgentina_Keygen.By.Thunder.rar)

Saludos!
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: tincopasan en 28 Febrero 2013, 10:43 AM
MCKSys Gracias!
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: Mad Antrax en 28 Febrero 2013, 13:50 PM
Cita de: MCKSys Argentina en 27 Febrero 2013, 20:28 PM
@||MadAntrax||: Hace un tiempo hice un crackme que, entre otras cosas, tenia comprobacion del codigo de un evento.

El post es este: http://foro.elhacker.net/empty-t356892.0.html (http://foro.elhacker.net/empty-t356892.0.html)

Si lo deseas, esta noche subo el codigo fuente del crackme, pero lo recomendable aqui no es ver el source del crackme, sino el tutorial de la solucion que encontro Thunder: http://www.mediafire.com/file/spob6r4g8y92sel/Crackme4.By.MCKSysArgentina_Keygen.By.Thunder.rar (http://www.mediafire.com/file/spob6r4g8y92sel/Crackme4.By.MCKSysArgentina_Keygen.By.Thunder.rar)

Aun hoy dia me sorprende el nivel de reversing aplicado...

Saludos!

Esperando con ansias el source de tu ejemplo de crackme :)
Título: Re: Como comprobar si mi código asm ha cambiado?
Publicado por: MCKSys Argentina en 1 Marzo 2013, 02:29 AM
Aquí va: http://www.multiupload.nl/3O3T3UDGYT (http://www.multiupload.nl/3O3T3UDGYT)

El código que está en los recursos, lo hice en una DLL usando ASM y después es sólo cuestión de allocar memoria y saltar.

El code tiene comentarios algunos comentarios que use para guiarme al momento de desarrollarlo.

Cualquier cosa, pregunta.

Saludos!

PD: Me olvidaba! La pass del 7z es "a" (sin las comillas)