Hola,
todos seguramente para llamar a una API (como puede ser MessageBox() ) utilizan
Código:
invoke MessageBox,0,"hola","hola",0
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!

