Subclasificando una ventana FASM

Iniciado por linkgl, Diciembre 24, 2012, 08:08:49 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Diciembre 24, 2012, 08:08:49 PM Ultima modificación: Mayo 01, 2014, 08:50:11 AM por Expermicid
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

Código: asm
;******
; 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