Hace mucho hice este código, experimentando y hookeando apis en ring3, lo que hace es cambiar el procedimiento de ventana por uno programado por nosotros y así poder capturar/modificar los mensajes de la ventana de un programa (acá salta un msgbox cada que cambia de posición la ventana, se captura el mensaje WM_WINDOWPOSCHANGED y salta un msgbox y luego manda el mensaje al procedimiento de ventana original para que se mueva la ventana XD) :PP me llevo varios días y nunca le seguí ni lo pulí pero va bien. :o
;******
; CODED BY LINKGL
; SUBCLASIFICANDO CALCULADORA EN FASM
; FELIZ NAVIDAD ¡! -
; --- -- -- - - / / ------ ---
; | | | || \ | || |/ / | ____| | |
; | | _ | || \ | || \ | |___ | | -
; | |_| || || \ || |\ \ | | | | |_| |
; |_______||__|| _|\___||__| \_\ |______| |_______|
;*****
format PE GUI 4.0
entry start
include 'win32ax.inc'
linkpi PROCESS_INFORMATION <>
linksi STARTUPINFO <>
temp dd ?,0
tempu dd ?,0
tam dd ?,0
handle dd ?,0
start:
;Creamos el proceso y si no existe saltamos a nohayarchivo
invoke CreateProcessA,0,"c:\windows\system32\calc.exe",0,0,0,0,0,0,linksi,linkpi
cmp eax,0
je .nohayarchivo
;Cargamos kernel32.dll
invoke LoadLibrary,"kernel32.dll"
mov [temp],eax
;Obtenemos la direccion virtual de todas estas API's
;Y las almacenamos en distintas variables
invoke GetProcAddress,[temp],"GetProcAddress"
mov [gpa],eax
invoke GetProcAddress,[temp],"LoadLibraryA"
mov [gmh],eax
invoke LoadLibrary,"user32.dll"
mov [tempu],eax
invoke GetProcAddress,[tempu],"MessageBoxA"
mov [msgbox],eax
mov [msggbox],eax
invoke GetProcAddress,[tempu],"FindWindowA"
mov [fwa],eax
invoke GetProcAddress,[tempu],"SetWindowLongA"
mov [swl],eax
invoke GetProcAddress,[tempu],"CallWindowProcA"
mov [cwp],eax
mov [dir_wproc],WndProc
;mov ruta,message
;sacamos el tamaño de las dos funciones (inyectame y el procedimiento de ventana)
;haciendo una resta de la direccion de donde comienza inyectame hasta la direccion de
;la etiqueta final
mov ebx,final
sub ebx,inyectame
mov [tam],ebx
;Reservamos ese tamaño en la memoria del proceso a inyectarnos
;Escribimos nuestras funciones
;Y creamos el hilo donde correran las funciones
invoke VirtualAllocEx,[linkpi.hProcess],0,[tam],MEM_COMMIT+MEM_RESERVE,PAGE_EXECUTE_READWRITE
mov [handle],eax
invoke WriteProcessMemory,[linkpi.hProcess],[handle],addr inyectame,[tam],0
invoke CreateRemoteThread,[linkpi.hProcess],0,0,[handle],0,0,0
; invoke Sleep,3000
; invoke MessageBox,0,'Extrayendo todo lo posible','Me he inyectado!',0
; invoke ResumeThread,[linkpi.hThread]
ret
.nohayarchivo:
invoke MessageBox,HWND_DESKTOP,'No se pudo abrir el proceso especificado','&Error',0
ret
proc inyectame
;Tecnica del offset delta
call offset
offset:
pop edx
sub edx,offset
mov edi,edx
mov esi,edx
mov esi,edx
mov edi,edx
push edx
pop edx
;un msgbox para ver si todo ha ido bien con el titulo de la ventana
add edx,ventana
push 0
push edx
push edx
push 0
call [edi+msgbox]
;restauramos el offset delta
mov edx,edi
;calculamos y cargamos en edx la direccion
;de la variable ventana
add edx,ventana
;llamamos a findwindowa
push edx
push 0
call [esi+fwa]
mov ebx,eax
;movemos el handle a ebx
mov esi,edi
mov edx,edi
;igual calculamos la direccion de la winproc
add edx,WndProc
;llamamos a setwindowlong reemplazando la winproc por la nuestra
;con esto ya la subclasificamos e instalamos nuestra wproc
push edx
push -4
push ebx
call [esi+swl]
mov [esi+prev_proc],eax
cmp eax,0
;si todo ha ido bien ya instalamos nuestra winproc
;si no saldra un msgbox
je salto
;c:\windows\system32\calc.exe
ret
salto:
; mov edx,edi
; add edi,ventana
mov edx,edi
add edx,ventana
push 0
push edx
push edx
push 0
call [edi+msgbox]
ret
;VARIABLES
;NOTA: Unas son inecesarias solo las use para debuggear errores
msgbox dd ? ;Dirección MessageBox
tit db "Inyectado",0
msg db "Ya me inyecte",0
ventana db "Calculadora",0
gpa dd ? ;Dir getprocaddress
gmh dd ? ;Dir loadlibrary/getmodulehandle en su defecto
fwa dd ? ;FindWindowA
swl dd ? ;SetWindowLongA
; cwp dd ? ;callwindowproca
dir_wproc dd ? ;v_address de la winproc
hndle dd ?
chl dd ?
endp
;procedimiento de ventana
proc WndProc, Hwnd, Umsg, wParam, lParam
;tecnica offset delta
call delta
delta:
pop edx
sub edx,delta
mov edi,edx
mov esi,edx
mov esi,edx
mov edi,edx
push edx
pop edx
mov esi,edx
mov edi,edx
;comparamos el mnsj de entrada aver si es WM_WINDOWPOSCHANGED (0X0047) VER MSDN
cmp [Umsg],0x0047
;Si es el mensaje saltamos a box
je box
mov esi,edx
;Llamamos a Callwinproc para mandar los mensajes al procedimiento original y no se cuelge el programa
push [lParam]
push [wParam]
push [Umsg]
push [Hwnd]
push [esi+prev_proc]
call [esi+cwp]
;fin
ret
box:
;llamamos al msgbox
add esi,msgg
push 0
push esi
push esi
push 0
call [edi+msggbox]
ret
cwp dd ?
msgg db "Cambio de posicion la ventana",0
msggbox dd ?
endp
;DIRECCION de la proc anterior a la que instalamos
prev_proc dd ?
final:
data import
library kernel,'KERNEL32.DLL',\
user,'USER32.DLL'
import kernel,\
GetModuleHandle,'GetModuleHandleA',\
ExitProcess,'ExitProcess',\
CreateProcessA,'CreateProcessA',\
GetProcAddress,'GetProcAddress',\
VirtualAllocEx,'VirtualAllocEx',\
WriteProcessMemory,'WriteProcessMemory',\
CreateRemoteThread,'CreateRemoteThread',\
LoadLibrary,'LoadLibraryA',\
ResumeThread,'ResumeThread',\
Sleep,'Sleep'
import user,\
DialogBoxParam,'DialogBoxParamA',\
CheckRadioButton,'CheckRadioButton',\
GetDlgItemText,'GetDlgItemTextA',\
IsDlgButtonChecked,'IsDlgButtonChecked',\
MessageBox,'MessageBoxA',\
EndDialog,'EndDialog'
end data