Archivo para la Tutoriales & Manuales (ASM) categoría

Importar funciones de Windows en Fasm “manualmente”

Publicado en Tutoriales & Manuales (ASM) con etiquetas el Mayo 3, 2009 por ni0ssw

Hola,
todos seguramente para llamar a una API (como puede ser MessageBox() ) utilizan
Código:

invoke MessageBox,0,”hola”,”hola”,0

y listo, pero hay otra forma mas compleja y que sirve “en casos de emergencia” que esta buena conocer, aparte de que se entiende un poco mejor la forma de trabajar windows con sus .exe
y si ya se piensan que voy a salir con “LoadLibrary” y “GetProcAddress” lamento decirles que no xD es mas complejo que eso.

lo que yo hize y averigue es para el FASM, pero debe de ser muuy parecido para otros compiladores

lo que vamos a hacer es crear una nueva seccion dentro del ejecutable donde vamos a poner determinada informacion para que cuando ejecutamos el .exe el windows automaticamente carge las DLLs y las direcciones de memoria de las funciones..

este es un ejemplo, creo que bastante claro, crea una ventanita con MessageBox() y llama a ExitProcess()
lo importante de todo esta al final, donde empieza la seccion .idata

;——————————————————————;

format PE gui

entry main

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section ‘.text’ code readable executable

main:
;aca empiezan los argumentos de MessageBox
;(se empieza por el ultimo argumento)
push 0 ;MB_OK
push hi ;texto
push hi ;texto
push 0 ;HWND_DESKTOP
call [MessageBox]
;fijense que uso [nombre], no como el invoke que no utiliza []

push eax ;salimos con lo que retorno MessageBox
call [ExitProcess]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section ‘.data’ data readable writeable

hi db ‘hola mundo!’,0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;aca viene lo interesante!
section ‘.idata’ import data readable writeable

dd 0,0,0, rva kernel_name, rva kernel_table
dd 0,0,0, rva user_name, rva user_table
;dd 0,0,0, rva dll_name, rva dll_table
;etc.
dd 0,0,0,0,0

;aca es donde se va a cargar
;la direccion de memoria de la funcion
kernel_table:
ExitProcess dd rva _ExitProcess
;LoadLibrary dd rva _LoadLibrary
;etc.
dd 0 ;para terminar la tabla

kernel_name db ‘kernel32.dll’,0

;aca le indicamos el nombre
;de las funciones que aparecen en la tabla
_ExitProcess dw 0
db ‘ExitProcess’,0
;_LoadLibrary dw 0
;db ‘LoadLibraryA’,0

;lo mismo pero para user32
user_table:
MessageBox dd rva _MessageBox
dd 0

user_name db ‘user32.dll’,0

_MessageBox dw 0
db ‘MessageBoxA’,0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;——————————————————————;

fijense que lo que hacemos es crear manualmente la seccion de importacion, estamos indicandole byte por byte que es lo que tiene que escribir en esa seccion, por lo que se puede hacer con cualquier compilador (con sus respectivas nomenclaturas obiamente)

section ‘.idata’ import data readable writeable
esas son las características de la sección
dentro de esa seccion primero colocamos el nombre de la DLL (la direccion donde esta el nombre) y donde esta la tabla, fijense que uso “rva”, eso indica que en vez de colocar la direccion en memoria, coloque la direccion dentro del archivo.

creo que la estructura de la seccion es facil de entender con ese ejemplo, puse entre comentarios como agregar mas funciones o mas dlls.

no es muy practico si podemos hacerlo de la forma facil, pero creo que es interesante (por lo menos para mi lo fue), se tiene mas control sobre el archivo y se aprende mas sobre el formato PE de los .exe

salu2!

x86 calling conventions (castellano)

Publicado en Tutoriales & Manuales, Tutoriales & Manuales (ASM) el Septiembre 3, 2008 por ni0ssw

Hola, aca voy a explicar las “calling conventions”, toda la informacion la voy a sacar de:
http://en.wikipedia.org/wiki/X86_calling_conventions
(esta en inglés)


-He notado que algunas especificaciones estan.. incompletas, quisa le falta decir como retorna o si se ponen de derecha a izqueirda o de izquierda a derecha los argumentos, yo solo saque la informacion de la pagina citada arriba de todo

-Cuando aveces digo que en C se puede indicar de que forma compilar la funcion, quisa no sea igual para todos los compiladores, hasta es probable que en algunos compiladores se pueda incluir otras calling conventions.


que son las calling conventions?
resulta que hace tiempo, con las maquinas de Unix, todo funcionaba como reloj, las funciones se llebaba bien entre ellas, pero parecio IBM, con sus pcs con procesador intel, sistema operativo de microsoft y hardware IBM, entonces tubieron que hacer una serie de reglas para que las funciones funcionen bien. estas reglas son las calling conventions.

que dicen estas reglas?
definen como se pasan los argumentos y como debe retornar un valor la función, por ejemplo, los argumentos se pueden pasar a los registros o a la pila, empezando por la derecha o por la izquierda.

sirve para cualquier lenguaje?
si, aunque en pocos lenguajes se puede especificar que reglas seguir, o bien, crear tus propias reglas (con asm, aunque tambien podes seguir las calling conventios ya establecidas obiamente)
creo que es importante para asm, pero no es de importancia cuando no podes especificar nada, pero saber que hace el compilador con tus funciones no esta de mas Lengua


Las calling conventions se dividen en 2 grandes grupos
“caller clean-up”
“callee clean-up”

Caller clean-up:
Aca el que llame a la funcion se encarga de limpiar la pila (ya veremos que es eso), facilidad para las funciones con indefinida cantidad de argumentos, como lo es printf en C.

tenemos 3 “reglas”:
cdecl
syscall
optlink

cdecl:
la cdecl calling convention es la mas usada por compiladores de C
los argumentos (parametros) de la funcion son pasados por la pila, empezando de la derecha y terminando con el argumento de la izqueirda.
la funcion retorna el valor en el registro EAX, exepto para valores reales que se ponen en ST0.
los registros EAX, ECX y EDX quedan libres para la funcion (osea, los podes modificar tranquilamente)

en C para especificar que la funcion utilize este metodo debemos poner _cdecl antes del nombre de la funcion:

Código
int _cdecl funcion(int, int, int);

un ejemplo:

Código
int function_name(int, int, int);
int a, b, c, x;
...
x = function_name(a, b, c);

al compilarse queda:

Código
push c
push b
push a
call function_name
add esp, 12 ;Limpia la pila
mov x, eax

el que llamo a la funcion debe limpiar la pila despues de la llamada, esto se hace regresando la pila a donde estaba, como tenemos 3 variables de 4 bytes, el valor de esp va a disminuir 12 bytes (los 3 push), asique para que vuelva a donde estaba hay que sumarle 12 a esp Lengua
en caso de que el valor a retornar sea de 64 bits entonces retoran en EAX:EDX (32bits mas significativos en EAX y los menos significativos en EDX)

en Linux los puntos flotantes de 32 bits o los de 64 bits son pasados asi:

Código
sub esp,8;    hace espacio en la pila 
fld [ebp+x]; carga el flotante de 64bits
fstp [esp]; pone el flotante de 64bits en la pila
call func;
add esp,8;

syscall:
Este es parecido a cdecl en que los argumentos se pasan de derecha a izqueirda.
EAX, EDX  y ECX no se conservan. (creo que quiere decir que no los podemos modificar)
El tamaño de la lista de parametros se pasa a AL

Syscall es el metodo estandar para OS/2 32bits

optlink:
Los argumentos son puestos de derecha a izquierda. Los tres primeros (de la izquierda) se pasan por EAX, EDX y ECX, y hasta 4 variables flotantes se pasan de ST(0) a ST(3) aunque se reserva espacio en la pila para ellos.
en este caso EBP, EBX, ESI, y EDI son conservadas
se retorna por EAX o ST(0)

optlink se usa por los compiladores IBM VisualAge.

Callee clean-up:
cuando la funcion llamada limpia la pila, el compilador tiene que saber cuantos bytes debe “limpiar” en el tiempo de ejecucion, por eso este metodo no es compatible con funciones con la cantidad de  argumentos variables (como printf).
este metodo es un poco mas eficiente.
la instruccion ret del x86 permite un un parametro de un byte que especifica el numero de posiciones de la pila a limpar antes de retornar.

Código
ret 12

tenemos las sigientes:
pascal
register
stdcall
fastcall
Microsoft fastcall
Borland fastcall
Watcom register based calling convention
TopSpeed / Clarion / JPI
safecall

pascal
los parametros son pasados de izquierda a derecha (al contrario de cdecl)
retorna como cdecl

este metodo fue usado comunmente en 16 bit APIs OS/2 1.x , Microsoft Windows 3.x, y Borland Delphi version 1.x.

register
asi se lo llamaba a Borland fastcall.

stdcall
se pasan los argumentos de dercha a izqueirda
EAX, ECX y EDX son destinados para la funcion
y se retorna en EAX
este metodo es el estandar para WIN32
en C para indicar que use este metodo usamos

Código
_stdcall
Código
char _stdcall mifunc(int x);

fastcall
esta convencion no se estandarizó (creo que se escribe asi xD) por lo que cada compilador lo interpreta a su manera:
Microsoft fastcall
Microsoft o GCC __fastcall pasa los primeros 2 argumentos (de izquierda a derecha) en ECX y en EDX, el resto se ponen en la pila de DERECHA a izquierda.
Borland fastcall
Pasa de izquierda a derecha los argumentos en EAX, EDX y ECX, el resto por la pila (tambien de izquierda a derecha)
es el metodo estandard de Borland Delphi.
Watcom register based calling convention
Watcom no soporta la palabra clave __fastcall, exepto que se le haga un alias a NULL
el “registrer calling convention” se selecciona por la linea de comandos
los argumentos se pasan de izquierda a derecha por eax, edx, ebx, ecx. Si algun argumento no puede ser pasado por el registro, ese y todos los siguientes se pasan por la pila, los argumentos de la pila se pasan de DERECHA a izquierda
Watcom C/C++  admite “#pragma aux” que te permite definir tu propio metodo (no se como xD da un enlaze a http://www.openwatcom.org/index.php/Calling_Conventions#Specifying_Calling_Conventions_the_Watcom_Way pero eso no entraria en este post)
TopSpeed / Clarion / JPI
Los primeros 4 son pasados por eax, ebx, ecx y edx, para los puntos flotantes usamos st0, st1, st2, st3, st4, st5 y st6. parametros de estructuras son siempre pasados por la pila y cuando se acaban los registros usamos la pila
enteros se retornan por EAX
punteros por EDX
puntos flotantes por st0

safecall
En borland delphi este metodo se usa para chequekar errores, los errores se reportan cuando se retorna, y delphi automaticamente chekea ese valor devuelto y si es necesario manda algun mensaje de error.

safecall es igual a stdcall exepto que los errores son pasados por EAX (en vez de fs:[0]) mientras que el valor devuelto se pasa por la pila como si fuese un ultimo parametro out.
esta convencion va a perecer como cualquier otra convencion, aunque los errores son pasados por EAX, estos son automaticamente convertidos a la exprecion adecuada por el que llama a la funcion safecall.
estas 2 declaraciones son iguales:

Código
function function_name(a: DWORD): DWORD; safecall;
Código
function function_name(a: DWORD; out Result: DWORD): HResult; stdcall;


thiscall

esta tiene 2 verciones, caller-clean up y callee-clean up, depende del compilador
para el GCC, thiscall es igual que cdecl, la diferencia es que agrega “this pointer”, que se pone ultimo en la pila, como si fuese el primer parametro de la funcion

para microsoft visual C++ “this pointer” es pasado por ECX y la funcion llamada es la que limpia la pila, exepto para las funciones con numeros variados de parametros que es la funcion que llama la que limpia.

thiscall puede ser esplicitamente especificado en Microsoft Visual C++ 2005 y mayores. para cualquier otro compilador thiscall no es una palabra reservada
(no se que es a lo que se refiere con “this pointer”

Citar
The difference is the addition of the this pointer, which is pushed onto the stack last, as if it were the first parameter in the function prototype.

)

Intel ABI
esta convencion muchos compiladores y lenguajes usan, segun Intel ABI, EAX, EDX y ECX son de uso libre para la funcion, asique no tienen que ser preservadas.

Microsoft x64 calling convention
esta convencion, como bien deben de suponer, es para arquitecturas de 64 bits, y utiliza las ventajas de los 64 bits utilizando RCX, RDX, R8 y R9 para enteros y punteros
XMM0, XMM1, XMM2, XMM3 para flotantes, el resto se pone en la pila y se retorna por RAX.
cuando compilamos en 64bits utilizando las herramientas de microsoft, hay una sola convencion (esta xD) asique stdcall cdecl ,fastcall etc son todas una y la misma
es de la responsabilidad del que llama a la funcion reservar 32bytes (sin importar el numero de parametros) en la pila antes de llamar a la funcion, este espacio es para RCX, RDX, R8 y R8

AMD64 ABI convention
este sistema es usado en linux (obiamente 64 bits xD) y otros sistemas operativos menos los de microsoft
RDI, RSI, RDX, RCX, R8 y R9 son usados para enteros y punteros
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 y XMM7 para flotantes
los demas son por la pila y se retorna en RAX.

Standard exit and entry sequences for C code
asi es como EMPIEZA la funcion

Código
_function:
    push ebp       ;guarda el ebp viejo
    mov ebp, esp   ;ahora la base de la pila es el puntero a la pila
                   ;arriba de todo esta el viejo ebp y seguida por la posicion de retorno
    sub esp, x     ;x es el tamaño de todas las variables "automatic" ("automatic" es algo de C, por defecto todas son automatic)

lo unico que explico es que sub esp, x es hacer espacio, donde dentro van a estar las variables locales automaticas.
este comportamiento hace posible hacer funciones recursivas

y asi es como TERMINA

Código
mov esp, ebp   ;reset the stack to "clean" away the local variables
pop ebp        ;restore the original base pointer
ret            ;return from the function

creo que esta claro, un ejemplo de este code en C:

Código
int _cdecl MyFunction(int i){
    int k;
    return i + k;
}

produce

Código
;entry sequence
push ebp
mov ebp, esp
sub esp, 4     ;create function stack frame

;function code
mov eax, [ebp + 8]
               ;move parameter i to accumulator
add eax, [ebp - 4]
               ;add k to i
               ;result is returned in eax

;exit sequence
mov esp, ebp
pop ebp
ret

aunque esto algunos compiladores lo optimizan cuando no necesitan hacer espacio en la pila y esas cosas.


si.. es un poco largo y pesado, no creo que se lo lean todo xD quisa tienen duda y consultan aca Lengua

salu2! y espero que les haya gustado!

Preguntas Frecuentes de ASM

Publicado en Tutoriales & Manuales (ASM) el Julio 12, 2008 por lShadowl

FAQ acerka del ASM by Shadow

P:¿Que es “ASM”?
R: Es la abreviatura de lenguaje “assembler” o “ensamblador” en español.

P:¿Que es entonces el lenguaje “ensamblador”?
R: “Vistos a muy bajo nivel, los microprocesadores procesan exclusivamente señales electrónicas binarias. Dar una instrucción a un microprocesador supone en realidad enviar series de unos y ceros espaciadas en el tiempo de una forma determinada.
Esta secuencia de señales se denomina código máquina. El código representa normalmente datos y números e instrucciones para manipularlos.
Un modo más fácil de comprender el código máquina es dando a cada instrucción un mnemónico, como por ejemplo CMP, ADD o JMP.
Esta abstracción da como resultado el ensamblador, un lenguaje de muy bajo nivel que es específico de cada microprocesador.”

P:¿Que puedo programar en este lenguaje?
R:Simple, todo lo que puedes ver digitalizado por un monitor.

P:¿Que necesito para aprender a programar en ASM?
R:Descartando lo obvio, un cerebro con IQ de mas 81, ser incha del RMFC y ganas de aprender

P:¿Tiene que ver ASM que esos 0s y 1s de la ciencia ficcion de los “juackers”?
R: Dejame explicarlo asi:
En la pregunta #2 vimos que “los microprocesadores procesan exclusivamente señales electrónicas binarias”. Veamos la instruccion “10010000″:
Binario (lo que procesa el micro): 10010000
Hexadecimal (representacion de la instruccion en otro sistema de numeracion): 90
Mnemonico (representacion o “comando” de ensamblador): NOP
Uso: No hace nada, es una instruccion nula.

P:¿Como puedo practicar o hacer programas en ASM?
R:Puedes bajar un compilador. Entre los mas comunes estan: TASM (Turbo Asemmbler de Borland), MASM (Macro Assembler de Microsoft) y el RadASM.

P:¿Como se ve un programa en ASM para compilar?
R:Mirandolo (XD).
En 16 bits:
.MODEL SMALL ; Determinamos el modelo de memoria
.STACK ; Definimos el área de pila
.DATA
MENS DB "HOLA MUNDO!.$" ; Especificamos la cadena de texto a mostrar
.CODE ; Inicio del código
INI: ; Etiqueta de inicio
MOV AX, @DATA ; Permite tener acceso a los datos
MOV DS,AX ; a través de el registro DS
MOV DX,OFFSET MENS ; Prepara para desplegar el mensaje
MOV AH,9 ; Llama al servicio 9
INT 21H ; de la int 21h para desplegar el texto
MOV AH,4CH ; Llama al servicio 4Ch
INT 21H ; de la int 21h para terminar
END INI ; Cierra la etiqueta de inicio

En 32 bits (para MASM):
.486
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
print MACRO arg1:REQ,varname:VARARG
invoke StdOut,reparg(arg1)
IFNB
invoke StdOut,chr$(varname)
ENDIF
ENDM
.data
v0 dd 0
v1 dd 1
v2 dd 2
v3 dd 3
v4 dd 4
v5 dd 5
v6 dd 6
ary dd v0,v1,v2,v3,v4
dd v5,v6
.code
start:
call main
exit
main proc
LOCAL cnt :D WORD
push esi
push edi
mov cnt, 6
mov esi, ary
lp:
mov edi, [esi+2]
print str$(esi)
print chr$(" = Direccion en memoria",13,10)
print str$(edi)
print chr$(" = contenido",13,10,13,10)
add esi, 4
sub cnt, 1
jnz lp
pop edi
pop esi
ret
main endp
end start

P:¿Porque la diferencia?
R:Un micro (microprocesador) de 16 bits soporta eso mismo, 16 bits de informacion por cada operacion que realize; uno de 32 soporta, 32 bits.

P:¿Que otras diferencias hay entre estos 2?
R: Programar para 32 bits nos permite usar o “llamar” APIs de librerias externas como “kernel32.dll”, no permite manejar la interrupciones como lo hace un programa para 16 bits; para 32 bits, los registros (“variables”; espacios de memoria reservados para guardar informacion especifica en el procesador) al aumentar su tamaño, cambian de sintaxis (PE.: de “ax” a “eax”) aunque tambien se pueden seguir usando los registros de 16 bits; entre otras diferencias.

P:En la pregunta #5 mencionaste otros representaciones de los mnemonicos (binario y hexadecimal). ¿Tengo que saber estas conversiones o conocer estos sistemas de numeracion?.
R:Tecnicamente, no. Pero, en la practica si (por lo menos tienes que saber convertir hexadecimal a decimal)

P:¿Que ventajas tiene la programacion en ASM?
R:La principal ventaja es que permite crear programas muy rápidos y livianos (Un programa hecho en C++ que imprima la cadena “Hola Mundo!.” pesa unos 15.663 bytes, cuando uno hecho en ASM, que realize lo mismo y compilado con TASM, pesa 541 bytes, asiq estariamos hablando de
unas 29 veces mas pequeño).

P:¿Y desventajas?
R:A menudo es dificil de aprender.

P:¿Porque?
R:Los programadores de lenguajes de alto nivel no estan acostumbrados a la abstraccion, a la “limitacion” de funciones del ASM y a trabajar hablando direcctamente con el procesador, esto quiere decir que si la persona que intenta aprender ASM, no conoce el funcionamiento de un ordenador a nivel de memoria, procesador y hardware en general, le sera mucho mas dificil que al que ya conoce esto mas a fondo.

P:¿Esto quiere decir que tengo que tener algun tipo de conocimientos sobre este tema (funcionamiento del ordenador)?
R:Si.

P:¿De que me sirve saber ASM en nuestros dias? Por algo se inventaron los lenguajes de alto nivel.
R:Como dije, la principal ventaja es que permite crear programas muy rápidos y livianos. Otro de los usos del ASM en nuestro dias es la llamada “Ingenieria Inversa” o “Cracking”.

P:¿”Ingenieria Inversa”?
R:”Arte del destripado”; rama de “hacking” o “censurado informatica” que se encarga de romper cualquier tipo de seguridad que posea un programa comercial usando metodos de desensamblado y reconstruccion, comprometiendo asi cualquier tipo de cifrado o proteccion anti-”crackeo”, tambien llamado por los coders: “debug”, para poder disfrutar del limite de sus funciones o simplemente para modificar a gusto su funcionamiento.

P:¿Ahora, que hago?
R:Busca un tuto basico o de introduccion que sientas que entiendas sobre este lenguaje y empieza a leer y si tienes alguna duda, ES FATAL que te quedes con ella, PREGUNTA, PREGUNTA, PREGUNTA, APRENDE, APRENDE, APRENDE, esa es la ley… Luego transmite lo que sabes!

P. Quiero aprender asm, pero soy usuario de linux ¿hay diferencias en cuanto a sintaxis de las operaciones con DOS/Windows?
R. Si la hay, linux utiliza mayormente sintaxis AT&T, aunque tambien puedes programar con la sintaxis de intel en linux, dependiendo de que compilador uses.

con NASM en linux:
global _start

section .data
hola db "Hola , mundo!", 11
length equ $-hola

section .text

_start:
mov eax, 4 ; escribe en el archivo
mov ebx, 1 ; manejador de STDOUT
mov ecx, hola ; el mensaje
mov edx, length ; tamanio del mensaje
int 80h ; ejecuta la llamada al sistema

xor ebx, ebx ; envia 0 como codigo de salida
mov eax, 1 ; termina proceso
int 80h ; ejecuta la llamada al sistema
–> [p3ll3]

y con la sintaxis de AT&T:

.data
msg: .string "Hola mundo!\n"
len = . - msg
.text
.globl _ini
_ini:
movl $4, %eax
movl $1, %ebx
movl $msg, %ecx
movl $len, %edx
int $0x80

movl $1, %eax
xor %ebx, %ebx
int $0x80

Saludos!

Espero que les sirva de algo en su introduccion en este mundo!…

Saludos!

Estructura de un PE

Publicado en Tutoriales & Manuales (ASM) el Julio 12, 2008 por lShadowl

Estructura de un PE (Portable Executable):
-Cabecera ‘MZ’: 3ch apuntando a la cabecera ‘PE’.

-Cabecera ‘PE’: Contiene info acerca del fichero.
Algunas direcciones interesantes (respecto a PE):
00h ~ Cabecera (dword)
04h ~ tipo de maquina de destino (word)
06h ~ numero de secciones (word)
14h ~ tamaño de la cabecera opcional (word)
16h ~ características del fichero (word)
18h ~ comienza la cabecera opcional (si hay, claro xD)

-Cabecera opcional: Contiene más info acerca del fichero.
Algunas direcciones interesantes (respecto a PE):
01Ch ~ tamaño del code (dword)
028h ~ entrypoint (dword)
034h ~ dirección predeterminada donde se mapeara en fichero (dword)
03Ch ~ alineamiento del fichero respecto al disco (dword)

-Tabla de secciones: Contiene info sobre su respectiva sección, habrá tantas como secciones tiene el fichero. Para llegar a la tabla hay que hacer coger PE header+tamaño de PE header+tamaño de Optional header.
Algunas direcciones interesantes:
00h ~ nombre de la sección (8 bytes)
08h ~ virtual size (dword)
0ch ~ virtual address (dword)
14h ~ size of raw data (dword)
024h ~ flags (lectura, escritura, ejecución) (dword)

-Secciones: Son exactamente eso, secciones en las cuales el código es divido. Algunas de estas son: .text; .idata; .bss; .data; .reloc. Es importante destacar que podemos añadir secciones al fichero y que normalmente los compresores y crypters cambian, fusionan, o modifican estos nombre, así que podremos deducir que el nombre de la sección en si no es esencial en el funcionamiento del fichero.

Saludos!

Usando los servicios 9h y 10h de la int 21h

Publicado en Tutoriales & Manuales (ASM) el Julio 12, 2008 por lShadowl

El programa pide que escribas algo y esa cadena la voltea . . . osea q si escribes “hola”, el programa imprime “aloh”

imprimir macro val
push ax
push dx
lea dx,val
mov ah,9
int 21h
pop dx
pop ax
endm
leer macro val
push ax
push dx
lea dx,val
mov ah,10
int 21h
pop dx
pop ax
endm
data SEGMENT PARA PUBLIC
msg DB 'Escribe algo!',13,10,'$'
cad DB 30
len DB 0
cadena DB 30 DUP(0)
cad2 DB 30 DUP(0)
data ENDS
prog SEGMENT PARA PUBLIC 'code'
main PROC FAR
ASSUME CS:prog,DS:data,SS:pila,ES:data
mov ax,data
mov ds,ax
mov es,ax
inicio:
imprimir msg
leer cad
bucle:
mov al, cadena[bx]
push ax
inc bl
cmp bl, len
jne bucle
mov bx, 0
bucle2:
pop ax
mov cad2[bx], al
inc bl
cmp bl,len
jne bucle2
mov cad2[bx], '$'
imprimir cad2
mov ax,4c00h
int 21h
main ENDP
prog ENDS
pila SEGMENT PARA STACK 'stack'
DB 128 DUP(0)
pila ENDS
END main

Knowing file sizes

Publicado en Tutoriales & Manuales (ASM) el Julio 12, 2008 por lShadowl

include \masm32\include\masm32rt.inc ;mem models, libraries, includes

.data
fname DB "\masm32\include\windows.inc",0 ;target file

.code

start:

call main ; call to proc
inkey ; wait for user
exit ; end

main proc

LOCAL bytecount :D WORD ; stablish a local var

.if rv(exist,ADDR fname) != 0 ; test if file exist
mov bytecount, rv(filesize,ADDR fname) ; use the filesize proc and result is in bytecount
print "Tama?o de WINDOWS.INC = "
print str$(bytecount)," bytes",13,10 ;shows the result
.else
print "ERROR, file doesnt exist",13,10
.endif

ret ; return

main endp

end start

Detecting arguments

Publicado en Tutoriales & Manuales (ASM) el Julio 12, 2008 por lShadowl

When we code console apps we can know if the user introduced some argument by:

invoke GetCL,X,ADDR Y

where “X” will be the argument number (1,2,3,4…) and “Y” the buffer

ex:

...
ini proc
...
LOCAL p1[128]:BYTE ;p1 as local
...
invoke GetCL,1,ADDR p1 ;call the api
cmp eax,1 ;test if there is an argument or not
je noargumento
lea eax,p1 ;p1 with the argument
...

Saludos!

MCB Residence

Publicado en Tutoriales & Manuales (ASM) el Julio 12, 2008 por lShadowl

Format of MCB:

direction content type
+00h ID (Z = last, M = there are more) 1 BYTE
+01h direction to the PSP asociated segmente 1 WORD
+03h N? of paragraphs at the alocated memory zone 1 WORD
+05h Not used 11 BYTES
+10h alocated mem zone x PARRAF

so, to keep resident of program with MCB using DOS we have to:

-know if it is .com or .exe
–if .com, get the psp (if .exe we work with ds)
–* mov bx, cs |Another way to get psp and know and know if there are copies (psp to bx):
mov dx,0f904
mov ah,62
nt 21
–minus 1 to bx to find de MCB direction and move to data
–* dec bx
mov ds, bx
–on si+3 is the size of alocated mem, then, minus code size
–* sub word ptr [si+3],prg_lng
–now that we have the size of mem, we have to free it.
–* mov ax,word ptr [si+3] ;save the result on ax.
mov dx,ax ;in bx the new mem to free
push cs
pop es
mov ah,4ah ;serconnectione to free mem
int 21h
–now we have to asign the free mem to the program
–* pop bx ;get the size
dec bx ;DOS will use a DWORD
mov ah, 48h ;serconnectione to asign
int 21h
–now we can use the DOS techinique to identify his parts and it is identify his first offset with 8..
–* dec ax
mov es, ax
mov word ptr es:[1], 8
mov word ptr es:[8],’XX’
inc ax
mov es, ax
push es
rep movsb ;ready, we are residents

….directly MCB modification:

mov dx,0f904
mov ah,62 ; get psp
int 21
dec bx ; go to MCB
mov ds,bx
sub word ptr [si+3],prg_lng
sub word ptr [si+12],prg_lng ;move to DOS too
mov ds,si ;reserve 2k of mem
mov es,dx
push cs
pop ds
mov si,offset inicio
mov di,si
mov cx,(fin – inicio) / 2
rep movsw ;residents!

Saludos!

Shadow