Hola.. bueno les cuento.. estoy tratando de entender el lenguaje ASM, con ayuda de un amigo y leyendo un poco he conseguido crear un programa que muestra un msgbox al inicio, se crea una ventana y al clickarla sale otro msgbox.. necesito un poco de ayuda para poder hacer un boton que haga alguna acción (por ejemplo ejecutar CMD) o algo así.
Buehh este es el code..
hInstance equ 0x00400000
format PE GUI 4.0 at hInstance as 'exe'
entry codee
include 'WIN32A.INC'
section '.bss' readable writeable
msg MSG
bools db ? ; [1]Exit
section '.text' code readable executable
codee:
push MB_ICONEXCLAMATION
push _msgb0
push _msgb1
push 0
call [MessageBox]
push _classname
push 0
push 0
call [CreateMutex]
call [GetLastError]
TEST EAX,EAX
jnz .end
push BLACK_BRUSH
call [GetStockObject]
mov [wc.hbrBackground],EAX
push IDC_ARROW
push 0
call [LoadCursor]
mov [wc.hCursor],EAX
push IDI_APPLICATION
push 0
call [LoadIcon]
mov [wc.hIcon],EAX
push wc
call [RegisterClass]
push 0
push [wc.hInstance]
push 0
push 0
push 300
push 500
push CW_USEDEFAULT
push CW_USEDEFAULT
push WS_VISIBLE+WS_CAPTION+WS_SYSMENU+WS_MAXIMIZEBOX
push _title
push _classname
push 0
call [CreateWindowEx]
jmp .jump0
.jump:
push msg
call [TranslateMessage]
push msg
call [DispatchMessage]
test [bools],1
jnz .end
.jump0:
push 0
push 0
push 0
push msg
call [GetMessage]
cmp EAX,1
je .jump
.end:
ret
WindowProc:
mov EAX,DWORD PTR SS: ESP+8
cmp EAX,WM_LBUTTONDOWN
je .lbdwn
cmp EAX,WM_DESTROY
je .wm_destroy
jmp [DefWindowProc]
.lbdwn:
push 0
push _titlebox
push _msgboxcnt
push 0
call [MessageBox]
retn 16
.wm_destroy:
or [bools],1
retn 16
section '.data' writable readable
_msgb0 TCHAR 'ALERT',0
_msgb1 TCHAR 'Test program, use under your own risk',0
_text1 TCHAR 'Testing this program fucking',0
_msgboxcnt TCHAR 'Do not click my program fucking',0
_titlebox TCHAR 'WARNING',0
_title TCHAR 'Program fucking',0
_classname TCHAR 'MyFuckingProgram'
wc WNDCLASS 0,WindowProc,0,0,hInstance,0,0,0,0,_classname
data import
U_KERNEL32 equ 1
U_NTDLL equ 0
U_USER32 equ 1
U_GDI32 equ 1
U_DWM equ 0
U_SHELL32 equ 0
U_ADVAPI32 equ 0
U_WS2_32 equ 0
U_COMCTL32 equ 0
U_MSIMG32 equ 0
U_MSVCRT equ 0
U_OLE32 equ 1
include 'LIBS.INC'
end data
Si me pudieran explicar o darme algun texto donde se explique el funcionamiento de la pila les agradeceria tambien..
EAX_
Edito:
Se me olvidaba.. para programar uso FASM y me ayudo con OllyDbg para tratar de entender bien..
Para empezar a probar cambia el codigo de la etiqueta lbdwn, para ejecutar un programa la forma mas simple es usar WinExec (http://msdn.microsoft.com/en-us/library/ms687393(VS.85).aspx) (despues ya podras usar CreateProcess o ShellExecute).
Despues cuando ya sepas ejecutar algo tendras que crear una ventana hija de la primera para el control del tipo boton (nombre de clase BUTTON) y manejando el mensaje WM_COMMAND podras ver el ID del boton. Lee al respecto en la MSDN: http://msdn.microsoft.com/en-us/library/bb775943(VS.85).aspx
Tal vez esto te sirva para la pila:
http://insecure.org/stf/smashstack.html
Leer todo esto no viene mal tampoco:
http://foro.elhacker.net/asm/entry_point-t256455.0.html
Gracias por responder, cuando tenga tiempo voy a leer lo que me mandaste y ahora voy a tratar de agregar esa funcion que me dijiste para ver si sale algo..
EAX_
EI: juntando mensajes.
Ufff.. despues de varios intentos y acordandome de algunas cosas que me decia un amigo que me ayuda con esto.. pude abrir CMD.. ahora, no sé si sobra algo o si está mal porque todavia no entiendo bien a la pila.. creo que puse algo de más..
WindowProc:
mov EAX,DWORD PTR SS: ESP+8
cmp EAX,WM_LBUTTONDOWN
je .lbdwn
cmp EAX,WM_DESTROY
je .wm_destroy
jmp [DefWindowProc]
.lbdwn:
push SW_SHOWNORMAL
push _cmd
call [WinExec]
retn 16 ; Al quitarlo se cierra el programa y se abre cmd
.wm_destroy:
or [bools],1
retn 16
section '.data' writable readable
_cmd TCHAR 'C:\Windows\system32\cmd.exe',0
Ese retn 16 todavia no lo entiendo bien.. si pudieras explicarme que hace te lo agradeceria.. creo que tiene que ver algo con los push, pero no recuerdo bien..
EAX_
PD: Perdón por el multipost..
http://pdos.csail.mit.edu/6.828/2009/readings/i386/RET.htm
Retorna al llamador y saca los parametros de la pila (que para esta funcion son 4 DWORDS, 16 bytes).
PD. ¿De donde sale libs.inc? Cada dia odioa mas FASM y sus includes ...
Libs.inc es esto:
library kernel32,'KERNEL32.DLL',U_KERNEL32,\
ntdll,'NTDLL.DLL',U_NTDLL,\
user32,'USER32.DLL',U_USER32,\
gdi32,'GDI32.DLL',U_GDI32,\
dwm,'DWMAPI.DLL',U_DWM,\
shell32,'SHELL32.DLL',U_SHELL32,\
advapi32,'ADVAPI32.DLL',U_ADVAPI32,\
ws2_32,'WS2_32.DLL',U_WS2_32,\
comctl32,'COMCTL32.DLL',U_COMCTL32,\
msvcrt,'MSVCRT.DLL',U_MSVCRT,\
msimg32,'MSIMG32.DLL',U_MSIMG32,\
ole32,'OLE32.DLL',U_OLE32,\
oleaut32,'OLEAUT32.DLL',U_OLE32
include 'API/KERNEL32.INC'
include 'API/NTDLL.INC'
include 'API/USER32.INC'
include 'API/GDI32.INC'
include 'API/DWM.INC'
include 'API/SHELL32.INC'
include 'API/ADVAPI32.INC'
include 'API/WS2_32.INC'
include 'API/COMCTL32.INC'
include 'API/MSIMG32.INC'
include 'API/MSVCRT.INC'
include 'API/OLE32.INC'
Ya voy entendiendo un poco sobre el ret.. tambien pude usar la funcion WinExec con algunas propiedades y eso.. ahora voy a ver como me va con ShellExecute porque no tube suerte con CreateProcess..
EAX_
Edito
Bueno, con ShellExecute me fue bien.. ahora, queria hacer una pregunta. Cómo podría yo obtener la letra de la unidad donde esta instalado windows? Me refiero a %HomeDrive% o %SystemRoot%.
EAX_
Podes usar GetWindowsDirectory o GetSystemDirectory; siempre consulta la MSDN (http://msdn.microsoft.com), esta la referencia donde explica que representa cada parametro y muchas veces incluye ejemplos.
estuve buscando sobre GetWindowDirectory, leí en msdn pero no se me ocurre como poder usar lo que GetWindowDirectory devuelve.. o aunque sea imprimirlo en la ventana que tengo..
Cómo puedo hacer eso?
hInstance equ 0x00400000
format PE GUI 4.0 at hInstance as 'exe'
entry codee
include 'WIN32A.INC'
section '.bss' readable writeable
msg MSG
bools db ? ; [1]Exit
section '.text' code readable executable
codee:
push _classname
push 0
push 0
call [CreateMutex]
call [GetLastError]
TEST EAX,EAX
jnz .end
push DKGRAY_BRUSH
call [GetStockObject]
mov [wc.hbrBackground],EAX
push IDC_ARROW
push 0
call [LoadCursor]
mov [wc.hCursor],EAX
push IDI_APPLICATION
push 0
call [LoadIcon]
mov [wc.hIcon],EAX
push wc
call [RegisterClass]
push 0
push [wc.hInstance]
push 0
push 0
push 300
push 500
push CW_USEDEFAULT
push CW_USEDEFAULT
push WS_VISIBLE+WS_CAPTION+WS_SYSMENU+WS_MAXIMIZEBOX
push _title
push _classname
push 0
call [CreateWindowEx]
jmp .jump0
.jump:
push msg
call [TranslateMessage]
push msg
call [DispatchMessage]
test [bools],1
jnz .end
.jump0:
push 0
push 0
push 0
push msg
call [GetMessage]
cmp EAX,1
je .jump
.end:
ret
WindowProc:
mov EAX,DWORD PTR SS: ESP+8
cmp EAX,WM_LBUTTONDOWN
je .lbdwn
cmp EAX,WM_DESTROY
je .wm_destroy
jmp [DefWindowProc]
.lbdwn:
push 0
push _c
push _cmdp
push _cmd
push _open
push 0
call [ShellExecute]
retn 16
.wm_destroy:
or [bools],1
retn 16
section '.data' writable readable
_open TCHAR 'open',0
_c TCHAR 'C:\',0
_cmd TCHAR 'cmd',0
_cmdp TCHAR '/c msg * asd',0
_msgb0 TCHAR 'ALERT',0
_text1 TCHAR 'Testing this program fucking',0
_msgboxcnt TCHAR 'Do not click my program fucking',0
_title TCHAR 'Program fucking',0
_classname TCHAR 'MyFuckingProgram'
wc WNDCLASS 0,WindowProc,0,0,hInstance,0,0,0,0,_classname
data import
U_KERNEL32 equ 1
U_NTDLL equ 0
U_USER32 equ 1
U_GDI32 equ 1
U_DWM equ 0
U_SHELL32 equ 1
U_ADVAPI32 equ 0
U_WS2_32 equ 0
U_COMCTL32 equ 0
U_MSIMG32 equ 0
U_MSVCRT equ 0
U_OLE32 equ 1
include 'LIBS.INC'
end data
EAX_
.data
buff db 512 dup(0)
.code
main:
push 512
push offset buff
call GetSystemDirectoryA
Gracias por contestar, traté poniendo eso y me da error con "offset".. el error es: undefined symbol 'offset'.
Faltará algún include?
EAX_
No, es MASM ... saca offset y listo.
Sisi, recien lo saque y con un msgbox confirme que funcionó, iba a responder pero ganaste.. gracias..
EAX_
Citar%HomeDrive% o %SystemRoot%.
Puedes tambien obtener las variables de entorno con GetEnvironmentVariable
include "win32ax.inc"
.code
start:
invoke GetEnvironmentVariable,"HomeDrive",Buffer,MAX_PATH
invoke MessageBox,0,Buffer,0,0
invoke ExitProcess,0
.data
Buffer db MAX_PATH dup (0)
.end start
Uff, despues de unos intentos me sirvio lo que me pasaste, gracias.. pero no logré usar invoke asi que lo hice asi:
.codee:
push MAX_PATH
push buff2
push _home
call [GetEnvironmentVariable]
.data
buff2 db MAX_PATH dup (0)
end data
Gracias..
Edito
Me quede sin memoria (out of memory) y le di más con FASM, ahora nose porque pero me cierra el programa y sale la ventanita de enviar informe de errores
Que tengo mal?
hInstance equ 0x00400000
format PE GUI 4.0 at hInstance as 'exe'
entry codee
include 'WIN32A.INC'
section '.bss' readable writeable
msg MSG
bools db ? ; [1]Exit
section '.text' code readable executable
codee:
push _classname
push 0
push 0
call [CreateMutex]
call [GetLastError]
TEST EAX,EAX
jnz .fiiin
push MAX_PATH
push buff2
push _home
call [GetEnvironmentVariable]
push DKGRAY_BRUSH
call [GetStockObject]
mov [wc.hbrBackground],EAX
push IDC_ARROW
push 0
call [LoadCursor]
mov [wc.hCursor],EAX
push IDI_APPLICATION
push 0
call [LoadIcon]
mov [wc.hIcon],EAX
push wc
call [RegisterClass]
push 0
push [wc.hInstance]
push 0
push 0
push 300
push 500
push CW_USEDEFAULT
push CW_USEDEFAULT
push WS_VISIBLE+WS_CAPTION+WS_SYSMENU+WS_MAXIMIZEBOX+WS_THICKFRAME
push _title
push _classname
push 0
call [CreateWindowEx]
jmp .jump0
.jump:
push msg
call [TranslateMessage]
push msg
call [DispatchMessage]
test [bools],1
jnz .fiiin
.jump0:
push 0
push 0
push 0
push msg
call [GetMessage]
cmp EAX,1
je .jump
.fiiin:
ret
WindowProc:
mov EAX,DWORD PTR SS: ESP+8
cmp EAX,WM_LBUTTONDOWN
je .lbdwn
cmp EAX,WM_DESTROY
je .wm_destroy
jmp [DefWindowProc]
.lbdwn:
push SW_SHOWNORMAL
push 0
push _c
push _cmdp
push _cmd
push _open
push 0
call [ShellExecute]
retn 16
.wm_destroy:
or [bools],1
retn 16
section '.data' writable readable
buff2 db MAX_PATH dup(0)
_home TCHAR 'HomeDrive'
_open TCHAR 'open',0
_c TCHAR 'C:\',0
_cmd TCHAR 'cmd',0
_cmdp TCHAR '/c msg * asd',0
_title TCHAR 'Program fucking',0
_classname TCHAR 'MyFuckingProgram'
wc WNDCLASS 0,WindowProc,0,0,hInstance,0,0,0,0,_classname
data import
U_KERNEL32 equ 1
U_NTDLL equ 0
U_USER32 equ 1
U_GDI32 equ 1
U_DWM equ 0
U_SHELL32 equ 1
U_ADVAPI32 equ 0
U_WS2_32 equ 0
U_COMCTL32 equ 0
U_MSIMG32 equ 0
U_MSVCRT equ 0
U_OLE32 equ 1
include 'LIBS.INC'
end data
EAX_
Le metes un parametro de mas al ShellExecute :P
Lo adapte un poquito a mi gusto pero esta funcional toma
hInstance equ 0x00400000
format PE GUI 4.0 at hInstance as 'exe'
include 'WIN32AX.INC'
section '.bss' readable writeable
msg MSG
bools db ? ; [1]Exit
section '.text' code readable executable
codee:
push _classname
push 0
push 0
call [CreateMutex]
call [GetLastError]
TEST EAX,EAX
jnz .fiiin
push MAX_PATH
push buff2
push _home
call [GetEnvironmentVariable]
push DKGRAY_BRUSH
call [GetStockObject]
mov [wc.hbrBackground],EAX
push IDC_ARROW
push 0
call [LoadCursor]
mov [wc.hCursor],EAX
push IDI_APPLICATION
push 0
call [LoadIcon]
mov [wc.hIcon],EAX
push wc
call [RegisterClass]
push 0
push [wc.hInstance]
push 0
push 0
push 300
push 500
push CW_USEDEFAULT
push CW_USEDEFAULT
push WS_VISIBLE+WS_CAPTION+WS_SYSMENU+WS_MAXIMIZEBOX+WS_THICKFRAME
push _title
push _classname
push 0
call [CreateWindowEx]
jmp .jump0
.jump:
push msg
call [TranslateMessage]
push msg
call [DispatchMessage]
test [bools],1
jnz .fiiin
.jump0:
push 0
push 0
push 0
push msg
call [GetMessage]
cmp EAX,1
je .jump
.fiiin:
ret
WindowProc:
mov EAX,DWORD[ESP+8]
;pop edx
cmp EAX,WM_LBUTTONDOWN
je .lbdwn
cmp EAX,WM_DESTROY
je .wm_destroy
jmp [DefWindowProc]
.lbdwn:
invoke ShellExecute,0,_open,_cmd,_cmdp,_c, SW_SHOWNORMAL
ret
.wm_destroy:
invoke ExitProcess,0
section '.data' writable readable
buff2 db MAX_PATH dup(0)
_home TCHAR 'HomeDrive'
_open TCHAR 'open',0
_c TCHAR 'C:\',0
_cmd TCHAR 'cmd',0
_cmdp TCHAR '/c msg * asd',0
_title TCHAR 'Program fucking',0
_classname TCHAR 'MyFuckingProgram'
wc WNDCLASS 0,WindowProc,0,0,hInstance,0,0,0,0,_classname
.end codee