asm en delphi

Upload: testdumps12

Post on 20-Jul-2015

557 views

Category:

Documents


6 download

TRANSCRIPT

BASM. Ensamblador con Delphi ( Borland ASM )

Lisa&&Alquimista( Introduccin copiada de un articulo de Nestor Freire )La necesidad de cualquier lenguaje de alto nivel, como lo es Delphi, de conseguir rutinas a bajo nivel, es muy importante. Lamentablemente no es suficiente el API. Pues no, no es suficiente el API y me estoy refiriendo a Windows. Hay actuaciones concretas que no son controladas como nosotros quisiramos, y Delphi, deja en manos de las API una cantidad ingente de trabajo, y hacer esto con la interface de un S.O. con numerosas lagunas. Pero hay que ser educado, y antes que ninguna otra cosa dar las gracias nuestro buen amigo, Francisco Charte, cuyo libro publicado hace muy poco, y de ttulo Ensamblador, es una muestra de lo que cualquier programador deberamos conocer y un acto de valenta por su parte, habida cuenta de que la inmensa mayora preferimos que nos lo den todo hecho y no complicarnos. Pero no vamos a escribir un artculo sobre ensamblador, sino el tratamiento de ste con Delphi.

Ensamblador s o no?A la vez, y lamentablemente, la utilizacin de Ensamblador (o Assembler, para quien est ms acostumbrado a esa terminologa) es un tema vedado. Desconozco lo que puede pensar el lector, y hago constar lo que pienso yo, y es que nos alejan cada vez ms de aquello que est cercano a la mquina y por lo tanto susceptible de entradas no deseadas. Ocurre con este lenguaje, el ms bajo que existe y por lo tanto el ms poderoso, segn se enfoque, y lo vemos en temas diarios como puedan ser los punteros disfrazados en Delphi. Los fabricantes me recuerdan a la letra de un cantoautor espaol, J.M. Serrat: nio, eso no se hace, eso no se dice, eso no se toca. Delphi, al menos hasta la versin 6, ha incluido un ensamblador que se le conoce por BASM (Borland ASseMbler), pero segn vamos avanzando en la versin del Sistema, menos posibilidades tenemos de utilizacin. Teixeira y Pacheco incorporan en su libro sobre Delphi 5, indicaciones con referencia al uso de BASM como: No optimice sus programas con cdigo ensamblador. El cdigo ensamblador optimizado manualmente puede ejecutarse ms rpidamente que el cdigo Object Pascal, pero pagando el precio de la legibilidad y la mantenibilidad del mismo. Igualmente indican Comente siempre su cdigo ensamblador detalladamente [. .] La falta de comentarios puede ser que sea difcil de entender. Pienso que como programadores debemos de comentar todo el cdigo, con independencia del lenguaje. Ensamblador no tiene por qu ser un caso especial. Hasta aqu el articulo ahora explicaremos un poco como utilizar ASM en Delphi, que es lo que realmente importa ,pues para eso escribimos este ensayo. Bueno lo primero de todo vamos a ver el deburgger que incorpora Delphi, para dichos casos, que como veremos es muy parecido a Olly, as pues, no hay ningn problema para manejarlo.

Debugger de DelphiPara nosotros esta parte ser muy fcil pues estamos acostumbrados a Olly y son parecidos.Con dicha Herramienta podemos ver el Deburgger de Delphi y lo que es nuestro programa segn lo estamos generando. Tan slo hay que activar un punto de ruptura y pasar a ejecucin. Cuando se detenga se selecciona View Debug Window CPU y nos encontraremos con algo del tipo que aparece en la Figura 1. Figura 1.

Donde el cuadro superior izquierdo muestra en negrita el cdigo fuente y a continuacin las instrucciones en ensamblador que se corresponden con dicho cdigo. Por supuesto, y casi siempre, el cdigo en Delphi tiene muchas menos lneas que su traduccin a ensamblador. ( se parece a Olly as pues no problema ).

Cdigo ASM generado por BASM ( El cdigo original tambin esta en ASM)

En la imagen superior podemos ver que si el cdigo escrito en Delphi esta en ASM el cdigo generado es igual al cdigo escrito( no hace falta traducirlo). Vemos tambin que en negrilla esta la instruccin en Delphi, que se esta ejecutando, ( podemos verlo tambin seleccionando ver cdigo (Crtl+V) ,veremos su comentario si lo hemos puesto) debajo de la instruccin en Delphi esta la instruccin que ejecutara el compilador en ASM con su direccin de memoria. ( podramos trazar el programa desde Olly en dicha direccin y solo veramos las instrucciones que no estn en negrilla). Por ejemplo si el cdigo esta en Delphi como se muestra abajo Var i :Integer; begin for i := 1 to 100 do begin // Poner los 100 numeros en un ListBox ListBox1.Items.Add (IntToStr(i)); end; end; Cdigo ASM generado por BASM ( El cdigo original esta en Delphi)

Vemos las instrucciones en Delphi en negrilla y el cdigo ASM generado por el compilador, como vemos aqu son diferentes ya que el compilador tiene que traducir las instrucciones de Delphi a ASM.

El cuadro inferior izquierdo es un mapa de memoria, al cual podemos visualizar la direccin deseada. (Pero hay que acordarse de que las direcciones por defecto son en Decimal, as pues hay que poner el smbolo del dlar para que sean Hexa $00401000). Desde el tambin podemos buscar Bit o cadenas ASCII.

Tambin podemos ver los registros que por supuesto podemos modificar a voluntad.

Tambin tenemos los Flag los cuales como no podemos modificar, para por ejemplo forzar un salto.

En las imgenes superiores en la primera (la de los Flag) se ve que hemos cambiado

el Flag ZF ( Esta en rojo), y en la segunda la flecha izquierda indica la instruccin actual, y la derecha ( como hemos cambiado el Flag), El salto se va ha ejecutar y ser hacia abajo. Si este no se ejecutara la flecha derecha no estara. Y por ltimo, el inferior derecho nos muestra el contenido de la pila del programa: direccin de memoria, valor que contiene y representacin ASCII. Como curiosidad, se vern ordenados en orden decreciente, debido a la propiedad LIFO de la pila. Podemos ver todas las variables de nuestro programa que queramos, de donde venimos o los hilos en proceso, para ello solo hace falta activar View Debug Window y la opcin deseada. Por cierto, que podemos utilizar el sistema Delphi de las teclas F7 y F8, y sera lo deseable para ir lnea a lnea y estudiar los resultados. Bueno esto es lo bsico sobre el debugger que Delphi trae incorporado, como comentamos anteriormente es parecido a Olly as pues ningn problema con , seguro que trasteando un poco con l se sacan ms funciones que las comentadas aqu, pero el cometido de este ensayo es aprender a programar ASM dentro del entorno de Delphi no Analizar exhaustivamente el debugger que trae incorporado.

Programacin en ASM en DelphiBueno despus de todo este rollo ahora viene la parte interesante de la historia Cmo programo yo en ASM el Delphi? Como conexiono Delphi y ASM ? Bueno esperemos que despus de leer esto dichos puntos queden ms claros. Cmo programo yo en ASM el Delphi? Lo mejor ser primero, decirle a Delphi que cuando escribamos en ASM nos pinte las instrucciones de otro color as nos aclararemos un poco ms, para conseguirlo Tools->Editor Option->pestaa color.

Y elegimos los colores que queramos para ASM. En este ensayo el color ser Azul todo lo que este en Azul ser ASM.

Bueno pues sigamos Pues lo nico que tenemos que hacer es meter las intrusiones ASM entre las intrusiones ASM y END. Un ejemplo: . . . asm // aqu empieza XOR EAX,EAX // XOR EBX,EBX // XOR ECX,ECX // XOR EDX,EDX // End; // Fin de ASM . Se ve claramente que el cdigo anterior es ASM Es muy recomendable utilizar sangra de texto ( para su mejor visualizacin) y poner el comentario en el END de final de asm ( no solo en este sino en todos los END ) pues sino tendremos en montn de end y no sabremos donde. Los bucles como ya sabemos en ASM hay que hacer uso de los diferentes saltos.JMP JA (JNBE) JAE (JNBE) JB (JNAE) JBE (JNA) JE (JZ) JNE (JNZ) JG (JNLE) JGE (JNL) JL (JNGE) JLE (JNG) JC JNC JNO JNP (JPO) JNS JO JP (JPE) JS

el asm Limpiamos Limpiamos Limpiamos Limpiamos

todos todos todos todos

los los los los

registros registros registros registros

NO es propsito de este ensayo explicar todos los saltos, as pues seguimos, Lo primero de todo ser saber como se ponen las etiquetas en ASM de Delphi, es muy fcil.

Lo primero ser saber como definir y utilizar una Etiqueta (Una etiqueta es una direccin de memoria con nombre). Etiqueta: @@Nombre de la etiqueta: As de fcil dos arrobas+Nombre+ dos puntos Veamos la funcin de comparar cadenas de Delphi en ASM:function CompareStr(const S1, S2: string): Integer; assembler; asm

// Comienza el ASMPUSH ESI PUSH EDI MOV ESI,EAX MOV EDI,EDX OR JE EAX,EAX @@ Etiqueta_1 EDX,EDX @@ Bucle_2 // Aqu no se ponen los dos puntos

MOV EAX,[EAX-4] @@Etiqueta_1: OR JE @@Bucle_2: // Aqu no se ponen los dos puntos

MOV EDX,[EDX-4] MOV ECX,EAX

Bueno el ejemplo anterior a quedado claro como definir y utilizar etiquetas, para conseguir hacer bucles. Con nico que hay que tener cuidado son con los dos puntos finales de la etiqueta se ponen solo en la definicin de la etiqueta, pero no son puestos en los saltos que utilizan dicha etiqueta. Definicin de la Etiqueta : Utilizacin de la Etiqueta@@Bucle_2: JE @@ Bucle_2 // Aqu no se ponen los dos puntos

La sintaxis de los dems comandos es muy clara pues es simplemente ASM.

Como Introducir valores en los registros ?Bien para no liarnos con nmeros vamos a utilizar siempre nmeros Integer, y registros extendidos ( EAX, EBX, etc, etc). Pues bien como sabemos las variables igual que las etiquetas son posiciones de memoria con un nombre, as pues utilizaremos esto para meter una variable en un registro. Para meter un nmero en el registro EAX pondremos: MOV EBX, 401000; // Mete 401000 ( 401000 (dec) en EBX) MOV EAX, $00401000; // Mete 401000 (401000 (hex) en EAX) Y para meter variables pues: Var Num_1 Num_2 Num_3 Nombre :Integer; :Integer; :Integer; :String;

Begin

Num_1:= 401000; Num_2:=$401000; Nombre:=CracksLatinos; Asm // empieza el ASM Mov Eax, Num_2; // Mov Ebx, Num_1; // Mov Num_3, Edx; // Mov Ecx,Nombre; // //Nombre End; // Fin de asm Pon Pon Pon Pon $401000 en EAX 401000 en EBX en Numero 3 el valor de EDX en Ecx la dir de memoria de

End; // fin de begin

Vemos como los Registros tienen los valores que acabamos de meter: Eax 401000 (hex) Ebx 61E68 (Hex) 401000 (dec) Ecx 0044FC0C // Direccin de la variable Nombre que contiene Cracklatinos, como podemos ver en el cuadro de memoria mostrado abajo.

Pues con esto queda aclarado como introducir datos a los registros:

Como conexiono Delphi y ASM ?En esta parte del ensayo se mostraran como pasar parmetros de ASM a Delphi y de Delphi a ASM, con eso conseguiremos, tener relacionados Ambos. Nota Aclaratoria: ( obligada la lectura para entender el manual ). Si alguien sin acabar de leer el manual empezase a escribir rutinas en ASM, con lo aprendido hasta ahora pensara que de verdad existen las Meigas (brujas) o algn otro duenende gracioso, que se ha instalado en su ordenador y esta realizando alguna que otra trastada, pues inexplicablemente unas veces funcionan las rutinas de ASM y otras no, sin que aparentemente exista ninguna explicacin lgica para ello. Si pedimos ayuda a SAN GOOGLE nos acabamos de desesperar pues en ningn sitio, obtenemos nada de ayuda, acudimos a los foros de Delphi y nada, al final creeremos en las Meigas. Pero que pasa con las rutinas ASM ? Despus de muchas pruebas si introducimos un bucle en ASM, que haga algo , como por ejemplo sumar y devuelva el resultado de la suma, luego copiamos el resultado en una variable y esa variable o la copiamos en un Edit por ejemplo, conseguimos un churro que no anda, si as como suena una rutina tan fcil como la de sumar, no conseguimos hacerla andar.

Veamos un ejemplo de lo dicho anterirmente : var serial: Integer; Contador: Integer; begin Contador := 10; Asm // Rutina para sumar XOR EAX,EAX // Limpiamos todos los registros XOR EBX,EBX // Limpiamos todos los registros XOR EDX,EDX // Limpiamos todos los registros MOV EBX, Contador // Metemos el contador 10 vueltas @@LOOP: TEST BL,BL // Comparamos si es el final JE @@Fin // Si lo es se acabo ADD EDX,EBX // Mete la suma en EDX DEC EBX; // retrocede el contador JMP @@LOOP @@Fin: MOV Serial,EDX // Guardamos el resultado en serial end; // asm // se acabo el ASM Edit1.Text:=IntToStr(Serial); // Aqu genera el error end; El trozo de cdigo nos genera el error (imagen inferior) en la instruccin marcada en rojo, podramos repetir este ejemplo sin el bucle y todo funciona perfectamente, el bucle esta bien, entonces Que pasa ?.

Bueno el proceso fue el siguiente, Utilizamos Olly para lo que realmente fue diseado, para reparar errores y descubrimos que el error esta en la pila esta queda totalmente descuadradra cuando abandonamos el Bucle de ASM y intentamos copiar el resultado en un control de Delphi. Una vez conocido el problema la solucin es de lo ms sencilla, la primera instruccin de ASM ser siempre PUSHAD y la ltima POPAD con esto conseguimos que la pila quede en su sitio. As pues todas las rutinas de ASM escritas desde Delphi sern:

ASM PUSHAD . . . POPAD END; // Fin de asm Bueno aqu acaba la Nota aclaratoria. Una vez entendida dicha Nota, proporcionaremos una manera segura de comunicar nuestro programa Delphi con rutinas ASM.

Paso de parmetros de un programa Delphi a una rutina ASMNo pensbamos maternos en este li pero una vez dentro que ms da, cogeremos el toro por los cuernos como dira nuestro amigo ELVIS[em]. Nosotros queremos pasarle parmetros a una rutina ASM y utilizaremos esta para que nos devuelva un valor, en este estudio veremos una forma segura de pasar parmetros a una rutina ASM ,dicha rutina ser encargada de realizar una serie de operaciones y devolvernos el valor de lo que ha calculado, tambin pretendemos desde cdigo ASM ( aqu esta el li) llamar a una funcin da igual Delphi que ASM y que esta devuelva un valor. Empezaremos por la primera pues esta no tiene ningn tipo de dificultad, escribiremos una rutina en ASM que reste dos nmeros y nos devuelva el resultado, este resultado lo visualizaremos en un Edit. Seguiremos unas normas siempre al escribir rutinas en ASM para evitar cosas raras. Queremos aclarar que estas son normas que hemos aprendido con la practica para evitar los errores extraos que produca Delphi con cdigo ASM. Seguro que en muchos casos se pueden omitir, pero aconsejamos seguir las normas aqu descritas para evitar comportamientos extraos de los cdigos escritos en ASM. Las normas 4 normas sern; 1 La primera instruccin de ASM ser PUSHAD 2 La ltima instruccin de ASM ser POPAD 3 Declararemos una variable de tipo integer donde al final de la rutina de ASM copiaremos el contenido del algoritmo. 4 Fuera de la rutina de ASM, Nada ms acabar esta, copiaremos la variable que utilizamos para guardar el resultado del algoritmo en Result con Result:= variable;

Veamos esto con ejemplo muy simple una funcin para restar dos nmeros. Nota : En este ejemplo las normas no serian necesarias, pero no pasa nada si las incluimos, si los clculos son mas complejos son normas necesarias. Function resta ( A:Integer; B:Integer):Integer; Var // Declararemos siempre una variable como Integer // donde almacenar el resultado del algoritmo // En este caso resultado Resultado :integer; Begin Asm // Inicio de ASM // Pondremos siempre al principio la instruccin Pushad pushad; mov EAX,a; mov EBX,b; Sub Eax,Ebx; // Moveremos a la variable el resultado del algoritmo Mov Resultado,Eax; // Pondremos siempre al Final la instruccin Popad Popad; end; // asm; // Ya fuera de ASM asignaremos la variable que tiene el // resultado a Result ( es obligatorio) Result:=Resultado; end; // funcion Resta Esta seria la rutina en ASM y La llamada desde un procedimiento sera: procedure TForm1.Button1Click(Sender: TObject); var a :Integer; b :Integer; c :Integer; begin a:=10; b:=8; c:=Resta(a,b); Edit1.Text:=(InttoStr(c)); end;

En el Edit veramos un 2. Como no poda ser de otra forma. Bueno con esto damos pro terminado el paso de parmetros de Delphi a ASM Ahora veremos el caso opuesto es decir de ASM Delphi

Paso de parmetros de un programa ASM a DelphiEfectuar llamadas ( CALL ) en ensamblador.Segn la convencin de llamada hay que tener en cuenta los valores que puede adoptar, son esenciales para saber el orden y el funcionamiento de los parmetros. Por defecto vamos a encontrar tan slo la directiva Pascal, propia de Delphi y la Stdcall, propia de Windows. Directiva Orden de los Parmetros Tipo eliminacin Parmetros por registro? Pascal Izquierda a derecha La funcin llamada NO Stdcall Derecha a izquierda La funcin llamada NO La Directiva es el nombre que indica al compilador la forma en que ha de trabajar. Segn ella el orden de los parmetros ser el que se indica en el apartado correspondiente. Los parmetros, como aparece en la ltima columna, se pasan por la pila tipo LIFO (ltimo en entrar, primero en salir), y a su salida son eliminados por la funcin que es llamada.

Y todo este rollo que es ? Y para que sirve?.Pues es muy simple, toda funcin, (tambin los procedimientos), pueden admitir un numero de parmetros en sus llamadas, pues bien la directiva sirve para indicar el orden de dichos parmetros, si son tomados de izquierda a derecha, (directiva Pascal) o de derecha a izquierda (Directiva Stdcall). Veamos un par de ejemplos: Function LaFuncion(A, B: Integer): Integer; pascal; Siendo A = 14 y B = 5. Aqu vemos una funcin tpica de Delphi. Evidentemente no ponemos la directiva normalmente, porque es la habitual y el compilador ya se encarga de ello. No obstante tampoco pasara nada por incluirla, como vemos en el ejemplo de arriba .

function LaFuncion(A, B: Integer): Integer; stdcall; Pero si cambisemos la directiva por stdcall, como hemos hecho ejemplo de arriba, nos dara lo mismo, el compilador de Delphi es as de listo. Todo esto en Delphi, Pero si nuestra rutina fuera en ASM, habra diferencia y mucha diferencia ya que si escribimos una rutina en ASM ( Por ejemplo rutina A ) y esta tiene que llamar a otra rutina ( por ejemplo rutina B ) la rutina B tiene que incluir necesariamente la directiva. Y esto de las directivas en ASM para que sirve ? Mejor vemoslo con un ejemplo cogeremos la funcin resta anterior o escribimos otra en Delphi que es ms fcil. function Resta_Stdcall (a,b:integer):integer; Stdcall; begin Result:=a-b; end; function Resta_Pascal(a,b:Integer):integer;Pascal; begin Result:=a-b; end; Como vemos hemos escrito dos funciones Resta idnticas lo nico que hemos cambiado es la directiva, ahora realicemos una prueba, con un programa en ASM que llamara a ambas funciones y podremos ver cual es la diferencia de este lo de directivas. Crearemos un form con un Botn calcular y dos Edit el primero visualizara el resultado de la funcin Resta_StdCall y el segundo Edit visualizara el resultado de la funcin Resta_Pascal.

Aqu el cdigo del botn generar procedure TForm1.Button1Click(Sender: TObject); Var a :Integer; b :Integer; c :Integer; begin a:=9; b:=5; asm push a; // primer parmetro de la funcin Resta push b; // Segundo parmetro de la funcin Resta call Resta_StdCall; // Resta mov c,eax // Guarda el resultado en C end; // asm Edit1.Text:=IntTostr(c); // Visualiza C a:=9; b:=5; asm push a; // primer parmetro de la funcin Resta push b; // Segundo parmetro de la funcin Resta call Resta_Pascal; // Resta mov c,eax // Guarda el resultado en C end; // asm Edit2.Text:=IntTostr(c); // Visualiza C end;

La Imagen no deja lugar a dudas cuando necesitemos desde una rutina ASM llamar a otra rutina esta para que funcione igual que en Delphi necesita llevar siempre la directiva de Pascal. **** MUY IMPORTANTE ****

Si una rutina tiene que ser llamada desde un cdigo ASM dicha rutina tiene que incluir siempre la directiva, pues sino aunque al compilar no nos de errores, no funciona de forma adecuada, se puede probar con el ejemplo anterior quitando la directiva a una de las funciones. Bueno pues con esto ya somos capaces de conexionar sin Meigas Delphi y ASM.

** Programacin de KeyGen en Delphi + ASM **Bueno pues despus de todo este li vamos con algo ms ameno como programar KeyGen en Delphi introduciendo funciones o trozos de cdigo ASM, (esto suena mucho mejor, que la primera parte de este ensayo verdad). La ventaja de poder introducir ASM dentro de un KeyGen es que podemos copiar con el plugin de Olly Asm2Clipboard.dll trozos de cdigo y los pegaremos en nuestro KeyGen y funcionara. As no tendremos que andar traduciendo instruccin por instruccin, y como premio aadido tendremos acceso a instrucciones tipo ROL que en Delphi no esta disponible. Si un programa o Crackme utilizase dicha instruccin u otra que en Delphi no estuviera disponible, nos tocara hacer maravillas para hacer un KeyGen y nuestros colegas que programan en ASM soltaran una carcajada al ver las cosas raras que hay que hacer para hacer un simple ROL, pues bien, ahora podremos sin ningn problema meter rutinas ASM dentro de Delphi y evitar as dichas carcajadas. Bueno en este ensayo realizaremos 2 KeyGen con cdigo Delphi + ASM. El primero de ellos llevara el cdigo ASM incorporado y el segundo sern dos funciones ASM las cuales aceptaran como parmetro el Nombre introducido en Un Edit y nos devolveran el resultado del algoritmo calculado en ellas., Usaremos Delphi para ponerlas en un Edit.

Bueno pues empecemos con el primer Crackme para construir el KeyGen (pensamos que seria muy instructivo hacer el KeyGen, de un Crackme que el KeyGen estuviera hecho en Delphi as se podran compara ambos KeyGen. Entonces asunto resulto realizaremos el KeyGen del mismo Crame que utilizamos para el primer ensayo de KeyGen en Delphi. Que es el concurso 17 nivel 02: Dicho KeyGen fue resulto por HouDini en ASM, despus lo resolvimos en Delphi y ahora lo realizaremos en Delphi + ASM ( el cdigo se parecer mucho ms al de HouDini ). Bueno pues nos leemos los dos ensayos el de HouDini en ASM y el de Delphi ya sabemos que hace el Crackme, Utilizaremos el mismo diseo que el utilizado en Delphi solo cambiaremos el cdigo asociado al botn Generar. as pues ya solo nos queda copiar el cdigo con el Plugin.

Este ser el diseo del KeyGen:

Programando el KeyGen// Botn SalirLo primero que vamos a realizar es el evento del botn salir, para ellos pulsamos dos veces en dicho botn y nos sale la pantalla de cdigo en la cual entre : Begin y End escribiremos nuestro cdigo. begin Close; end; Como vemos solo hemos escrito Close; (Salir) ahora si compilamos el programa y le ejecutamos (F9) el programa ya sabe lo que hacer con el botn salir, si lo ejecutamos vemos que efectivamente se sale del programa.

// Botn GenerarProcedemos igual que antes pero ahora encima de begin vamos a definir las variables que vamos a utilizar, escribimos Var (variables ) y ahora las variables : Primero definiremos las de tipo numrico y las definiremos de tipo Integer (entero), estas son: LongNombre -> Una variable donde almacenar la longitud del nombre Resultado -> Donde se almacena la solucin del algoritmo. Despus definiremos las de tipo String que son: Nombre -> Donde se almacena el nombre introducido.

Este ser el cdigo para el proceso de definir las variables:Var longNombre : Integer; Resultado : Integer; Nombre : String;

Una vez echo esto vamos a proceder a su asignacin:procedure TForm1.BitBtn2Click(Sender: TObject); Var LongNombre: Integer; // declaramos las variables Resultado : Integer; Nombre : String; begin Nombre:= Edit1.Text; // Copiamos en la variable el dato introducido en Edit1 longNombre:=length (Nombre); // Calculamos su longitud if longNombre = 0 Then // Comprobamos que no sea cero begin // Si es cero Haz Edit2.Clear; // Borra el contenido de Serial Application.MessageBox('Pon Algo','Upss..!',mb_ok+Mb_IconInformation); // Si no hay nada nos muestra este mensaje Edit1.SetFocus; // Si no hay nada escrito le pasamos el foco End Else // Si no es cero sigue begin asm Pushad; // Guardamos todos los registro XOR EAX,EAX; // Limpiamos todos los registros XOR EBX,EBX; XOR ECX,ECX; XOR EDX,EDX; @@L010: MOV EAX, Nombre; //toma nuestro nombre de usuario y lo mueve a EAX //coge carcter por carcter y lo mueve a EAX MOVSX EAX,BYTE PTR DS:[EAX+ECX]; INC ECX XOR EAX,ECX ADD EBX,EAX CMP ECX, LongNombre JNZ @@L010

IMUL EAX,EAX,6 SHL EBX,7

ADD EAX,EBX MOV Resultado,EAX // Guardamos el numero en Resultado Popad // Restauramos todos los registros end; // se acabo el asm edit2.Text:= IntToHex (Resultado,0); // Pon el edit2 el contenido de solucin end; // if end; // procedure

Como vemos en la imagen hemos copiado todo con el Plugin y solo hemos adaptado el cdigo en lo siguiente. MOV EAX, Nombre; //toma nuestro nombre de usuario y lo mueve a EAX //coge caracter por carcter y lo mueve a EAX MOVSX EAX,BYTE PTR DS:[EAX+ECX]; Metemos la direccin del Nombre en un registro ( el mismo que utiliza el Crame) MOV EAX, Nombre; //toma nuestro nombre de usuario y lo mueve a EAX luego miramos cual es el registro que utiliza de contador para ir pasando letra a letra ese es ECX miramos la Instruccin /*40110C*/ MOVSX EAX,BYTE PTR SS:[EBP+ECX-B8] Vemos cual es el registro pues como nosotros la direccin del nombre la tenemos en EAX. //coge caracter por carcter y lo mueve a EAX MOVSX EAX,BYTE PTR DS:[EAX+ECX]; Despus en: /*401119*/ CMP ECX,DWORD PTR SS:[EBP-28] Compara el Contador con el final del nombre CMP ECX,LongNombre

Y por ltimo ver donde se almacena el serial y meterlo en nuestra variable /*401126*/ MOV DWORD PTR SS:[EBP-38],EAX

MOV Resultado,EAX // Guardamos el numero en Resultado Todo esto unido a las normas comentadas en este ensayo dan como resultado el KeyGen en perfecto funcionamiento. Nota : Para quien le gusten las pruebas y no se crea nada de lo que este ensayo trata, que elimine del cdigo de ASM las instrucciones Pushad y Popad, vera que el programa no funciona. Con esto esta acabado el Keygen esperemos que HouDiNi no se enfade mucho por imitarle en el KeyGen y van dos veces.

KeyGen del concurso 36 Nivel 2Bueno pues vamos a por el KeyGen del concurso 36 Nivel 2 Lo primero ser disear un Interface este quedo as: Nota: Ni que decir tiene que este KeyGen esta dedicado a Redh@aw como mostrara la pantalla de About..

Una cosa curiosa de este Crackme es que genera un serial distinto si esta siendo debuggeado que si no lo esta, de hay la casilla de verificacin que por defecto esta desactivada.

Bueno pues aprovecharemos esa circunstancia ( la que el Crackme detecta el deburgger, para realizar dos rutinas en ASM, estas sern llamadas desde Delphi y este recoger el resultado del algoritmo de las rutinas, para Mostrarlo en el Edit correspondiente. function SinDeburgger (Nombre :String ):Integer; function ConDeburgger (Nombre :String ):Integer; Como vemos las funciones se llaman: SinDeburgger la cual ser ejecutada cuando la casilla correspondiente no este marcada. ConDeburgger la cual ser ejecutada cuando la casilla correspondiente este marcada. Dichas funciones en ASM aceptaran como parmetro una String ( el Nombre cogido de un Edit), devolvern un Integer (resultado del algoritmo). Bueno pues aqu pondr las dos funciones si se comparan con el crame literalmente esta copiado con el Plugin con las mismas modificaciones que en el ejemplo anterior. As pues Y para no alargar demasiado este ensayo que ya es muy largo y dado que las modificaciones que hay que hacer en las rutina copiada con el Plugin son las mismas que en el ejemplo anterior. ( las modificaciones siempre sern muy parecidas a las realizadas anteriormente) No se explicaran exhaustivamente. Bueno empecemos con el crame Bueno primero una Imagen del Crackme donde tiene la rutina que genera si el programa esta siendo No Esta siendo deburggeado.

Como veremos solo la tenemos que copiar con el Plugin y hacer las modificaciones de siempre. function SinDeburgger (Nombre :String ):Integer; var Serial :Integer; begin asm pushad // Guardamos todos los registro XOR EAX,EAX // Limpiamos todos los registros XOR EBX,EBX // Limpiamos todos los registros XOR ECX,ECX // Limpiamos todos los registros XOR EDX,EDX // Limpiamos todos los registros @@Segir: MOV EBX, Nombre //toma nuestro nombre y lo mueve a EBX //coge el carcter y lo mueve a EBX MOVZX EBX, BYTE PTR DS:[EBX+ECX] TEST BL,BL // Comparamos si es el final JE @@Fin // Si lo es se acabo ADD EDX,EBX OR EAX,EDX INC EAX ROL EDX,CL NOT EAX INC ECX ADD EAX,EDX JMP @@Segir @@Fin: MOV Serial,EDX // Guardamos el numero en serial popad // Restauramos todos los registros end; // asm // se acabo el asm Result := Serial; end; // Funcin sin deburger

Ahora la otra rutina

Bueno primero una Imagen del Crackme donde tiene la rutina que genera si el programa esta siendo deburggeado. Como veremos solo la tenemos que copiar con el Plugin y hacer las modificaciones de siempre. function ConDeburgger (Nombre :String ):Integer; var Serial :Integer; begin asm pushad // Guardamos todos los registro XOR EAX,EAX // Limpiamos todos los registros XOR EBX,EBX // Limpiamos todos los registros XOR ECX,ECX // Limpiamos todos los registros MOV EDI,Nombre //toma nuestro nombre y lo mueve a EDI @@Segir: MOV BL,BYTE PTR DS:[ECX+EDI] // Introduce un carcter TEST BL,BL JE @@Fin ADD EAX,EBX ADD EAX,$10 INC ECX JMP @@Segir @@Fin: MOV Serial,EAX // Guardamos el numero en serial popad // Restauramos todos los registros end; // asm // se acabo el asm Result := Serial; end; // Funcin Con deburgger Una vez que tenemos las dos funciones lo dems es muy fcil ya solo es Delphi.

El cdigo del Botn Generar Es este procedure TPrincipal.BitBtn1Click(Sender: TObject); Var Result :Integer; Tamanno:Integer; Serial :String; Name :String; begin Name:= E_Nombre.text; // Copiamos en la variable el nombre introducido en edit1 Tamanno:=length(Name); // Calculamos su longitud if Tamanno = 0 then // Verifica si hemos introducido algo en el edit1 begin E_Serial.Clear; Application.MessageBox('Pon Algo','Upss..!',mb_ok+Mb_IconInformation); // Si no hay nada nos muestra este mensaje E_Nombre.SetFocus; end else // Si hay algo escrito continuamos begin if Check_debug.Checked = True then // Miramos el estado de la casilla de verificacion begin // Si esta activada Result:=ConDeburgger (Name); // Calcula el serial con debugger end else begin Result:=SinDeburgger (Name); // Calcula el serial sin debugger end; // if debug Serial :=inttoHex(Result,0); // Lo formateamos a Hexadecimal E_serial.text:= (Serial); // Muestra el Resultado final en el edit2.text end; // if end;// Procedimiento Generar Bueno pues con esto damos por terminado el ensayo de Programacin ASM en Delphi. Nota: Por supuesto, si alguien quiere las fuentes de dichos ensayos pues solo tiene que pedirlas.

*** Despedida ***Como comento Yllera en su ltimo tute hacia mucho que no sala nada de l y pensamos ni nada nuestro tampoco, as pues este ensayo en parte es gracias a l. ( Bueno Yllera ya tienes un tute ms de Delphi para tu coleccin.) Este ensayo no hubiera sido posible, sin la ayuda de todos los Crackslatinos, as pues esta totalmente dedicado a vosotros. Mencin especial a [ElVIS]em -> El maestro del Delphi. Y Como no a Nuestro entraable RED.

Solo una cosa ms mandar un montn de suerte y animo al verdadero motor de Crackslatinos al maestro RICARDO NAVAJA.