[Script]Generic OEP Finder por UND3R

Iniciado por .:UND3R:., 5 Septiembre 2011, 10:29 AM

0 Miembros y 1 Visitante están viendo este tema.

.:UND3R:.

Este es mi primer script, está orientado en la búsqueda del OEP de manera genérica, una serie de métodos que están basados en el tutorial de introducción de ricardo narvaja, el objetivo de este script es poder optimizar la búsqueda de script, evitando realizar comandos repetitivos que ralentizan y demoran el trabajo de obtener un OEP,  los métodos de este script son los siguientes:

-PUSHAD-POPAD
una vez realizado este método, podemos buscar los siguientes Opcodes:
push ebp,push 0
-EXCEPCIONES
Este método consiste en colocar un BPM después de pasar por la última excepción
nos da la posibilidad de que si no sabemos cual es, el script en el registro (log)nos mostrará
una vez que estemos en la última excepción, nos da la posibilidad de dirigirnos en el retorno de la excepción para luego poder combinarlo con el método de bpmx(opcional)
-BPMX(Memory Breakpoint on execution)
este nos pedirá como requerimiento tener nuestro ollydbg parcheado (parcheado 4),nos preguntará en cual sección deseamos colocar el memory breakpoint on execution
-API COMÚN POR PACKER
Coloca un BP GetProcAddress la última vez que es llamada desde el packer, si no sabemos nos da la posibilidad de logear las veces que son llamadas
(el address a colocar no necesariamente debe ser el último, si no el último que es llamado desde la sección del packer)
-API COMÚN POR PROGRAMA
Este nos da la posibilidad de poder colocar un bp en 2 apis muy usadas al inicio de los programas:
GetModuleHandleA,GetVersion una vez que se detiene el programa se debe buscar el retorno y subir unas cuantas lineas

Script:
/*
    -=================================================================-
                           .:[CracksLatinoS]:.                       
        Script realizado por :UND3R                                       
        Script para : Generic OEP finder                                               
        Configuracion: Plugins Break on Execution o OllyDbg parcheado (cuando sea requerido por el script)                     
        Fecha : 05/09/2011                                           
                                                                     
                    -=[ Comentario del Script ]=-                   
     Agradecimientos:Apuromafo,Karmany,MCKSys Argentina,Tinkipinki                                                               
     por brindarme siempre ayuda cuando la necesito                                                               
     y a todos los de CracksLatinoS                                                               
    -=================================================================-
*/
START:
ASK "Métodos:Pushad-Popad(1),Excepciones(2),BPMX(3),API packer(4),API programa(5),Salir(x)"
cmp 1,$RESULT   //compara el resultado de ask con 1
je PUSHADPOPAD  //si el resultado es 1 se dirijirá al label PUSHADPOPAD
CMP 2,$RESULT   //compara el resultado de ask con 2
JE EXCEPCIONES  //si el resultado es 2 se dirijirá al label EXCEPCIONES
CMP 3,$RESULT   //compara el resultado de ask con 3
JE METODOBPMR   //si el resultado es 3 se dirije al label METODOBPMR
CMP 4,$RESULT
JE MUY_USADA_PACKER
CMP 5,$RESULT
JE MUY_USADA_PROGRAMA
CMP "x",$RESULT //compara el resultado de ask con x
JE SALIRDELSCRIPT //si el resultado es x terminará el script
CMP 0,$RESULT
JE SALIRDELSCRIPT


PUSHADPOPAD:
VAR AUX2 //declara una variable
VAR AUX //declara una variable
VAR KIUSER //declara una variable
VAR ZWCONT //declara una variable
VAR entrypoint //declara una variable
GPA "KiUserExceptionDispatcher", "ntdll.dll" //devuelve el address de una api
MOV KIUSER, $RESULT //mueve el resultado de la operacion anterior a KIUSER
BP KIUSER //coloca un bp en la address que apunta KIUSER
GPA "ZwContinue", "ntdll.dll" //devuelve el address de una api
MOV ZWCONT, $RESULT // mueve el resultado de la operación anterior a ZWCONT
BP ZWCONT //coloca un bp en la address que apunta ZWCONT
MOV entrypoint,[eip],1 //mueve el primer byte de eip a la variable entrypoint
CMP entrypoint,60 //compara entrypoint con 60 (equivale a un pushad)
JE PASO1 //si el primer opcode es pushad salta
TICND "byte [eip]==60" //tracea hasta encontrar un pushad
PASO1:
STI //Step into (F7), para ejecutar el pushad
MOV AUX,esp //mueve el valor de esp dentro de la variable AUX
INICIO:
BPHWS AUX, "r" //coloca un hadware breakpoint on access en AUX
TRABAJO:
EOB COMPROBAR // si ocurre una excepción o un bp se dirije a COMPROBAR
RUN //se ejecuta ollydbg (f9)
COMPROBAR:
CMP eip,KIUSER //compara eip con KIUSER
JE QUITAR   //si estamos en KiUserExceptionDispatcher irá a quitar BPHWS
CMP eip,ZWCONT //compara eip con ZWCONT
JE RESTAURAR  //si estamos en ZwContinue irá a restaurar
CMP eip,AUX2  //compara eip con el retorno de una excepción
JE RESTAURAR2 //si estamos en el retorno irá a restaurar2
JMP SALIR     //terminado todo se dirige a salir
QUITAR:
BPHWC         //quita el BPHWS
JMP TRABAJO  //salta a trabajo
RESTAURAR:
MOV AUX2,[ESP+4]  //introduce el valor de CONTEXT a AUX2
ADD AUX2,0b8 //le suma 0b8 para saber a que lugar retomará una vez pasada la excepción
BP AUX2      //sabiendo el retorno coloca un BP en ella     
JMP TRABAJO  //salta a trabajo
RESTAURAR2:
BC AUX2     //elimina el BP del retorno de la excepción
JMP INICIO   //salta a INICIO para volver a colocar el BPHWS
SALIR:
BPHWC //limpia todos los BPHWS
BC    //limpia todos los bp
MSGYN "Aproximación terminada,desea buscar OPcodes?"
CMP 1,$RESULT //compara resultado con 1(YES)
JZ BUSCAR_PUSH_EBP //si la comparación anterior se cumple salta al laber BUSCAR_PUSH_EBP
JMP START  //retorna al menú principal

EXCEPCIONES:
VAR BORRARZWCONTINUE //declara una variable
VAR ZWCONTINUAR //declara una variable
VAR COMPRO_MSG              //declara una variable
VAR EXCEPCION_ENCONTRADA         //declara una variable
VAR ZXCVAR     //declara una variable
VAR ZWCONTIN    //declara una variable
VAR ESP14       //declara una variable
VAR EXCEP       //declara una variable
VAR KIUSEREXCEP  //declara una variable
GPA "KiUserExceptionDispatcher", "ntdll.dll" //devuelve el address de una api
MOV KIUSEREXCEP,$RESULT   //mueve el address de la api a la variable KIUSEREXCEP
ASK "Introduzca la última excepción, si no sabe cual es introduzca 0"
MOV EXCEP,$RESULT
CMP 0,EXCEP   //compara con 0
JZ BUSCADOREX  //si es 0 irá a BUSCADOREX

BUSCADORCOND1:
BP KIUSEREXCEP  //coloca un bp en la variable KIUSEREXCEP
BUSCADORCOND2:
EOB BUSCADORCOND3  //si existe una excepción o bp se dirige a BUSCADORCOND3
RUN                //F9
BUSCADORCOND3:
MOV ESP14,[esp+14]  //Mueve el valor de [esp+14] en ESP14
CMP ESP14,EXCEP     //Compara si el valor es el mismo que la excepción introducida en el ask
JE ZXC              //si se cumple se dirijirá al label ZXC
JMP BUSCADORCOND2

BUSCADOREX:
MSG " El programa se ejecutará,una vez ejecutado se debe reiniciar (Control+F2)"
MSGYN "Las excepciones serán registradas en el log de OllyDBG,desea que estas también aparescan como MSG?"
MOV COMPRO_MSG,$RESULT
BP KIUSEREXCEP //Coloca un BreakPoint KIUSEREXCEP
BUSCADOREX2:
EOB BUSCADOREX3 //Si existe una excepción o un Breakpoint va a BUSCADOREX3
RUN
BUSCADOREX3:
MOV EXCEPCION_ENCONTRADA,[esp+14]
cmp COMPRO_MSG,0
JE BUSCADOREX4
EVAL "La última excepción por el momento es en la dirección:{EXCEPCION_ENCONTRADA}"
MSG $RESULT
BUSCADOREX4:
LOG EXCEPCION_ENCONTRADA
JMP BUSCADOREX2


ZXC:
EVAL "El programa se ha detenido en la excepción: {EXCEP}"
MSG $RESULT
MSGYN "Desea continuar en el retorno de la excepción?"
CMP 1,$RESULT
JE RETORNOEXCEP
BPHWC
BC
JMP START
RETORNOEXCEP:
BC
GPA "ZwContinue", "ntdll.dll"
BP $RESULT
MOV BORRARZWCONTINUE,$RESULT
RETORNOEXCEP2:
EOB RETORNOEXCEP3
RUN
RETORNOEXCEP3:
CMP eip,$RESULT
JZ RETORNOEXCEP4
CMP eip,[ZWCONTINUAR]
JZ RETORNOEXCEP5
JMP RETORNOEXCEP2
RETORNOEXCEP4:
MOV ZWCONTINUAR,[esp+4]
LOG ZWCONTINUAR
ADD ZWCONTINUAR,0b8
BP [ZWCONTINUAR]
JMP RETORNOEXCEP2
RETORNOEXCEP5:
BC BORRARZWCONTINUE
EVAL "Retorno de la excepción EIP:({eip})"
MSG $RESULT
JMP START

METODOBPMR:
MSG "Este método consiste en colocar un MemoryBreakPoint on EXECUTION,Se requiere el plugins Break On Execution o un OllyDbg parcheado para continuar"

VAR CONTADORBPM2 //establece una variable
VAR CONTADORBPM //establece una variable
VAR MODULOPESIGNA3 //establece una variable
VAR VIRTUAL_ADDRESS //establece una variable
VAR SIZE_OF_SECCION //establece una variable
VAR NAME_OF_SECCION //establece una variable
VAR MODULOPESIGNA2 //establece una variable
VAR MODULOPESIGNA  //establece una variable
VAR MEMORYBREAKPOINT //establece una variable
VAR MEMORYBREAKPOINT2 //establece una variable
VAR MEMORYBREAKPOINT3 //establece una variable
VAR NSECCIONES    //establece una variable
VAR PESIGNA      //establece una variable
VAR MODULO       //establece una variable
VAR MODULO2       //establece una variable
VAR MODULOP      //establece una variable
///////////////////////////////////////
GMI eip,MODULEBASE //obtiene el MODULEBASE
MOV MODULO,$RESULT  //el resultado de la operación anterior se guarda en la var MODULO
MOV MODULOP,MODULO  //mueve lo que está en MODULO a MODULOP
MOV MODULO2,MODULO
ADD MODULOP,3c       //a MODULOP se le suma 3c
MOV PESIGNA,[MODULOP]  //lo que está dentro de MODULEBASE+3C se guarda en PESIGNA
ADD MODULO,PESIGNA //suma MODULO con PESIGNA
MOV MODULOPESIGNA,MODULO //suma MODULOPESIGNA con MODULO
ADD MODULO,6 //MODULO se le suma 6 para saber el número de secciones
MOV NSECCIONES,[MODULO],1 //mueve un byte de lo que está dentro de [MODULO] a NSECCIONES
ADD MODULOPESIGNA,F8      //suma F8 a MODULOPESIGNA,para dirigirse al primer nombre de las secciones
MOV MODULOPESIGNA3,MODULOPESIGNA
LOG "*|--Informacion de secciones--|:" //logea lo que está en comillas
EVAL "Total de secciones:{NSECCIONES}"
LOG $RESULT
NMOFSEC:
MOV MODULOPESIGNA2,MODULOPESIGNA //mueve lo que está en MODULOPESIGNA a MODULOPESIGNA2
MOV SIZE_OF_SECCION,MODULOPESIGNA
ADD SIZE_OF_SECCION,8
MOV VIRTUAL_ADDRESS,SIZE_OF_SECCION
ADD VIRTUAL_ADDRESS,4
MOV NAME_OF_SECCION,[MODULOPESIGNA2]
BUF NAME_OF_SECCION //Convierte una String o dword a buffer
STR NAME_OF_SECCION //Convierte un buffer a STRING
LOG NAME_OF_SECCION //logea NOMBRE_DE_SECCION       
LOG [VIRTUAL_ADDRESS]
LOG [SIZE_OF_SECCION]
LOG "______________________________"
ADD MODULOPESIGNA,28 //suma 28 a MODULOPESIGNA
CMP [MODULOPESIGNA],0 //compara lo que está dentro de [MODULOPESIGNA] con 0
JZ MENSAJEDESEC //si es 0 es por que ya no hay más secciones
JMP NMOFSEC     //si hay más secciones salta a NMOFSEC
MENSAJEDESEC:
EVAL  "Numero de secciones encontradas:({NSECCIONES})más información ir al log"
MSG $RESULT
PREGNUMSEC:
ASK "Introduzca el nº de sección en donde desea colocar un memory breakpoint ej:1,2,3"
MOV MEMORYBREAKPOINT,$RESULT  //mueve el resultada a una variable
MOV CONTADORBPM,MEMORYBREAKPOINT //mueve una variable a otra
CMP MEMORYBREAKPOINT,NSECCIONES  //compara el nº de la sección con el introducido
JA  ERRORSEC //si es mayor se dirijirá a errorsec
CMP MEMORYBREAKPOINT,0 //compara nº introducido con 0
JZ ERRORSEC //si es 0 este irá a errorsec
CMP MEMORYBREAKPOINT,1  //compara con 1
JE MEMORYBREAK //si se comple se dirije a MEMORYBREAKPOINT
DEC CONTADORBPM  //toma el resultado del ASK anterior y lo disminuye en 1
MOV CONTADORBPM2,0 //CONTADORBPM2 toma el valor de 0
CONTADORBPMA:
//la finalidad de este loop está hecho para que modulopesigna se encuentre en el nombre de la sección elejida
CMP CONTADORBPM,CONTADORBPM2 //compara 0 con la sección elegida-1 ej:sec 3 cmp 0,2
JZ MEMORYBREAK //si se cumple se dirige a MEMORYBREAK
ADD MODULOPESIGNA3,28 //si no se dirije a la segunda sección sumándole 28
INC CONTADORBPM2     //incrementa el contador en 1
JMP CONTADORBPMA     //salta nuevamente a CONTADORBPMA
MEMORYBREAK:
ADD MODULOPESIGNA3,8 //estando en la sección elejida se le suma 8 para obtenr el size
MOV MEMORYBREAKPOINT2,[MODULOPESIGNA3] //guarda el (size) en MEMORYBREAKPOINT2
ADD MODULOPESIGNA3,4  //Le suma 4 para obtener el virtualadress
MOV MEMORYBREAKPOINT3,[MODULOPESIGNA3] //guarda el (virtualadress) en MEMORYBREAKPOINT3
ADD MEMORYBREAKPOINT3,MODULO2  //le suma la base a virtualadress
BPRM MEMORYBREAKPOINT3, MEMORYBREAKPOINT2 //coloca un BPRM con los parámetros obtenidos anteriormente
EVAL "Se ha colocado un BPM en:({MEMORYBREAKPOINT3}),con un tamaño de:({MEMORYBREAKPOINT2})"
MSG $RESULT
MSGYN "Desea Iniciar el programa(F9)?"
CMP 1,$RESULT   //compara el resultado con yes(1)
JZ ARRANCAR    //si se cumple se dirije al label ARRANCAR
JMP START //si no se dirije al menú principal
ARRANCAR:
RUN     //arranca el programa
ERRORSEC:
MSG "El nº de sección introducida es incorrecta, intente nuevamente"
JMP PREGNUMSEC //salta a preguntar el número de secciones

MUY_USADA_PACKER:
VAR ULTIMA_GETPROC //establece una variable
VAR COUNT //establece una variable
VAR RESP_GET //establece una variable
VAR ADDRESS_GET_PROC   //establece una variable
MOV COUNT,0
GPA "GetProcAddress", "kernel32.dll" //obtiene el address de GetProcAddress
MOV ADDRESS_GET_PROC,$RESULT //El Address es movida a ADDRESSGETPROC
BP ADDRESS_GET_PROC //Coloca un BP en GetProcAddress
ASK "Introduzca el address de retorno de la última call Realizada por el packer,si no sabe introduzca 0"
MOV ULTIMA_GETPROC,$RESULT
CMP 0,ULTIMA_GETPROC
JE BUSCADOR_API_PACKER
COMP_GET_PROC_ADDRES:
BP ADDRESS_GET_PROC  //coloca un bp en la variable ADDRESS_GET_PROC
COMP_GET_PRO_ADDRESS2:
EOB COMP_GET_PROC  //si existe una excepción o bp se dirige a COMP_GET_PROC
RUN                //F9
COMP_GET_PROC:
CMP [esp],ULTIMA_GETPROC     //Compara si el valor es el mismo que la excepción introducida en el ask
JE FINALIZAR_GET_PROC        //si se cumple se dirijirá al label FINALIZAR_GET_PROC
JMP COMP_GET_PRO_ADDRESS2

BUSCADOR_API_PACKER:
MSG "El programa se ejecutará,una vez ejecutado se debe reiniciar (Control+F2)"
BPL ADDRESS_GET_PROC,"[esp]"
RUN

FINALIZAR_GET_PROC:
MSG "Estado:Completado"
MSGYN "Desea colocar un MemoryBreakPoint on execution?"
CMP 1,$RESULT
JE METODOBPMR
BC
JMP START

MUY_USADA_PROGRAMA:
VAR APIUSADAPROGRAMA   //establece una variable
ASK "Opciones:GetVersion(1),GetModuleHandle(2)"
CMP 1,$RESULT
JE GETVERSION
CMP 2,$RESULT
JE GETMODULE
CMP 0,$RESULT
GETVERSION:
GPA "GetVersion","kernel32.dll"
MOV APIUSADAPROGRAMA,$RESULT
JMP MUY_USADA_PROGRAMA2
GETMODULE:
GPA "GetModuleHandleA","kernel32.dll"
MOV APIUSADAPROGRAMA,$RESULT
MUY_USADA_PROGRAMA2:
BP APIUSADAPROGRAMA  //coloca un bp en la API elegida por ASK
EOB MUY_USADA_PROGRAMA3 //si encuentra una excepción o un breakpoint se dirije al label
RUN  //inicia el programa (F9)
MUY_USADA_PROGRAMA3:
MSG "Estado:Completado"
BC   //limpia todos los bp
JMP START      //salta al menu principal

BUSCAR_PUSH_EBP:
ASK "OPcode: PUSH EBP(1),PUSH 0(2)"
CMP 2,$RESULT
JE BUSCAR_PUSH_EBP3
CMP 1,$RESULT
JE BUSCAR_PUSH_EBP2
JMP ERROR_OPCODE
BUSCAR_PUSH_EBP2:
TICND "byte [eip]==55" //tracea hasta encontrar un push ebp
JMP BUSCAR_PUSH_EBP4
BUSCAR_PUSH_EBP3:
TICND "byte [eip]==6a" //tracea hasta encontrar un push 0
BUSCAR_PUSH_EBP4:
MSGYN "OPcode encontrado,desea continuar" //muestra un mensaje al ser encontrado
CMP 1,$RESULT
JE BUSCAR_PUSH_EBP
JMP START

ERROR_OPCODE:
MSG "La opción introducida es incorrecta,por favor intente nuevamente"
JMP BUSCAR_PUSH_EBP
SALIRDELSCRIPT:
ret     //Sale del script


Espero que les sea de gran ayuda al momento de crackear,Saludos

Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)

Tinkipinki

Pedazo de script..... :P
Lo he probado y funciona correctamente.

Saludos

.:UND3R:.

Excelente, que bueno que haya servido, una duda tinkipinki, que configuraciones usaste? y con que crackme lo probaste?,creo que sirve con el reto que te envié

Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)

Tinkipinki

Efectivamente, lo he probado con dos crakme's en UPX y en los dos ha funcionado.
El reto....... haber quien lo hace con la mitad de codigo y claro esta que funcione :laugh:

Saludos

MCKSys Argentina

Cita de: Tinkipinki en  5 Septiembre 2011, 21:10 PM
Efectivamente, lo he probado con dos crakme's en UPX y en los dos ha funcionado.
El reto....... haber quien lo hace con la mitad de codigo y claro esta que funcione :laugh:

Saludos

Tinkipinki el script para UPX ocupa muy pocas lineas. Este script hace mas que desempacar UPX solamente....  :P
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


.:UND3R:.

Cita de: MCKSys Argentina en  5 Septiembre 2011, 21:23 PM
Tinkipinki el script para UPX ocupa muy pocas lineas. Este script hace mas que desempacar UPX solamente....  :P
eso es verdad de hecho para el OEP del UPX fue lo que menos me demoré, jeje

Tinkipinki:aun espero la correción del script, ya te di las pistas por privado

PUSHADPOPAD:
VAR AUX2 //declara una variable
VAR AUX //declara una variable
VAR KIUSER //declara una variable
VAR ZWCONT //declara una variable
VAR entrypoint //declara una variable
GPA "KiUserExceptionDispatcher", "ntdll.dll" //devuelve el address de una api
MOV KIUSER, $RESULT //mueve el resultado de la operacion anterior a KIUSER
BP KIUSER //coloca un bp en la address que apunta KIUSER
GPA "ZwContinue", "ntdll.dll" //devuelve el address de una api
MOV ZWCONT, $RESULT // mueve el resultado de la operación anterior a ZWCONT
BP ZWCONT //coloca un bp en la address que apunta ZWCONT
MOV entrypoint,[eip],1 //mueve el primer byte de eip a la variable entrypoint
CMP entrypoint,60 //compara entrypoint con 60 (equivale a un pushad)
JE PASO1 //si el primer opcode es pushad salta
TICND "byte [eip]==60" //tracea hasta encontrar un pushad
PASO1:
STI //Step into (F7), para ejecutar el pushad
MOV AUX,esp //mueve el valor de esp dentro de la variable AUX
INICIO:
BPHWS AUX, "r" //coloca un hadware breakpoint on access en AUX
TRABAJO:
EOB COMPROBAR // si ocurre una excepción o un bp se dirije a COMPROBAR
RUN //se ejecuta ollydbg (f9)
COMPROBAR:
CMP eip,KIUSER //compara eip con KIUSER
JE QUITAR   //si estamos en KiUserExceptionDispatcher irá a quitar BPHWS
CMP eip,ZWCONT //compara eip con ZWCONT
JE RESTAURAR  //si estamos en ZwContinue irá a restaurar
CMP eip,AUX2  //compara eip con el retorno de una excepción
JE RESTAURAR2 //si estamos en el retorno irá a restaurar2
JMP SALIR     //terminado todo se dirige a salir
QUITAR:
BPHWC         //quita el BPHWS
JMP TRABAJO  //salta a trabajo
RESTAURAR:
MOV AUX2,[ESP+4]  //introduce el valor de CONTEXT a AUX2
ADD AUX2,0b8 //le suma 0b8 para saber a que lugar retomará una vez pasada la excepción
BP AUX2      //sabiendo el retorno coloca un BP en ella     
JMP TRABAJO  //salta a trabajo
RESTAURAR2:
BC AUX2     //elimina el BP del retorno de la excepción
JMP INICIO   //salta a INICIO para volver a colocar el BPHWS
SALIR:
BPHWC //limpia todos los BPHWS
BC    //limpia todos los bp
MSGYN "Aproximación terminada,desea buscar OPcodes?"
CMP 1,$RESULT //compara resultado con 1(YES)
JZ BUSCAR_PUSH_EBP //si la comparación anterior se cumple salta al laber BUSCAR_PUSH_EBP
JMP START  //retorna al menú principal

Este es de hecho un poco más completo ya que no tan solo coloca un hadwarebreakpoint, si no que mientras se ejecuta el programa, este los quita en las excepciones,volviéndose a colocar en el retorno de ellas para así evitar de alguna u otra forma la detección del hadware breakpoint
además dándo la posibilidad que una vez ejecutado el popad,este tracea hasta encontrar uno de los op codes más usados al inicio del programa

Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)