[ASM] Subclassing, detectar movimiento de ventanas by linkgl
Publicado: 24 Dic 2011, 21:49
Que taaaaaaaaaaaal indetectables, jeje después de un ratillo sin hacer alguna herramienta publica puras bobadas para pasar el rato que hice para mi xD vengo ahora viendo esto del subclassing, que me intrigó en un post que se hizo en la sección C/C++ sabía la teoría del tema pero nunca lo había aplicado hasta hoy, pues llevo ya un rato haciendo esto tiene algo de código basura que me sirvió mientras programaba para debuggear y encontrar errores jeje no los quito porque ya me cansé llevo horas y horas en esto porque no salía... En fin, el subclassing consiste en reemplazar el procedimiento de ventana por otro (nuestro) para interceptar todos los mensajes que le sean pasados a la ventana y manipularlos o lo que se quiera hacer con ellos, en el ejemplo que hice, se inyecta en el proceso e instala mi winproc (subclasifica la ventana) y despues le manda los mensajes de nuevo a la wndproc original, lo apliqué a la calculadora intercepta el mensaje WM_WINDOWPOSCHANGED, y muestra un msgbox diciendo que se ha movido la ventana. Thanks to th3 swash aunque el problema era otro Feliz navidad
Sin más que decir...
PD: Siempre había querido poner un dibujito como el de los comentarios de hasta arriba xD
Sin más que decir...

Código: Seleccionar todo
;******
; 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
PD: Siempre había querido poner un dibujito como el de los comentarios de hasta arriba xD