Foro de elhacker.net

Programación => Programación Visual Basic => Mensaje iniciado por: F3B14N en 29 Abril 2011, 04:33 am



Título: Obtener puntero de funcion dentro de un form o class.
Publicado por: F3B14N en 29 Abril 2011, 04:33 am
Hola, estoy tratando de obtener el puntero de una funcion que esta dentro de un form o class.
La cual no puedo mover a un modulo y usar AddressOf porque es usada por varios hilos, necesito cada funcion independiente. Pero para hacer ello tiene que estar dentro de un class o form, y no puedo obtener su puntero  :-\

Intente esto:

http://www.programmersheaven.com/mb/VBasic/237946/237949/re-hot-to-find-the-address-of-a-function/

Código
  1. Call CallWindowProc(ByVal GetDWORD(ObjPtr(Me) + ((FunctionIndex - 1) * 4) + 12), 0, 0, 0, 0)

Agradeceria de su ayuda  :P


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: F3B14N en 29 Abril 2011, 04:45 am
Aqui parece que se obtiene algo parecido: http://cobein.com/wp/?p=236#more-236

Pero no logro obtener el puntero  :-\ Gracias


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: Karcrack en 30 Abril 2011, 17:15 pm
Lo estas haciendo bien, para obtener el puntero has de leer la vTable.... Pero estas leyendo mal el puntero... el puntero a la funcion no se encuentra en el Offset 0xC, sino en el 0x1C... es decir, el puntero estaría aquí:
Código:
ObjPtr(oObjeto) + (Indice * 4) + &H1C

Creo que así podrás obtener el puntero :D


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: F3B14N en 30 Abril 2011, 17:44 pm
Lo estas haciendo bien, para obtener el puntero has de leer la vTable.... Pero estas leyendo mal el puntero... el puntero a la funcion no se encuentra en el Offset 0xC, sino en el 0x1C... es decir, el puntero estaría aquí:
Código:
ObjPtr(oObjeto) + (Indice * 4) + &H1C

Creo que así podrás obtener el puntero :D

Gracias por tu respuesta karcrack, no lo logré, probé de estas dos formas y mas variantes tambien, pero parece que el puntero no es el correcto.

cls
Código
  1. Option Explicit
  2.  
  3. Public Function llamame(ByVal jj, ByVal dd, ByVal tt, ByVal jaja) As Long
  4.    MsgBox "hola"
  5. End Function
  6.  
  7. Public Sub oo()
  8.    Dim dd As Long
  9.    Dim jj As Long
  10.  
  11.    dd = GetDWORD(ObjPtr(Me))
  12.    jj = GetDWORD(dd + (1 * 4) + &H1C)
  13.    MsgBox jj
  14.    Call CallWindowProc(ByVal jj, 0, 0, 0, 0)
  15. End Sub
  16.  
  17. Private Function GetDWORD(ByVal lAddr As Long) As Long
  18.    Call NtWriteVirtualMemory(-1, GetDWORD, ByVal lAddr, 4, ByVal 0&)
  19. End Function

cls
Código
  1. Option Explicit
  2.  
  3. Public Function llamame(ByVal jj, ByVal dd, ByVal tt, ByVal jaja) As Long
  4.    MsgBox "hola"
  5. End Function
  6.  
  7. Public Sub oo()
  8.    Dim dd As Long
  9.  
  10.    dd = GetDWORD(ObjPtr(Me) + (1 * 4) + &H1C)
  11.    MsgBox dd
  12.    Call CallWindowProc(ByVal dd, 0, 0, 0, 0)
  13. End Sub
  14.  
  15. Private Function GetDWORD(ByVal lAddr As Long) As Long
  16.    Call NtWriteVirtualMemory(-1, GetDWORD, ByVal lAddr, 4, ByVal 0&)
  17. End Function

El intento dos devuelve 3  :-X. Las apis usadas las puse en otro modulo, y a ese class lo llame desde un form. Voy a informarme de la vTable, pero no hay nada mejor que una ayuda de un experto :P

Saludos


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: Karcrack en 30 Abril 2011, 18:09 pm
El indice de la primera funcion es 0... de todas formas ahora abro el OllyDbg y le doy un vistazo ;)


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: F3B14N en 30 Abril 2011, 18:17 pm
El indice de la primera funcion es 0... de todas formas ahora abro el OllyDbg y le doy un vistazo ;)

Ya habia probado con 0 tambien, pero no va :P

Código
  1. Option Explicit
  2. Private Declare Function NtWriteVirtualMemory Lib "NTDLL" (ByVal hProcess As Long, ByRef lpBaseAddress As Any, ByRef lpBuffer As Any, ByVal nSize As Long, ByRef lpNumberOfBytesWritten As Long) As Long
  3. Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  4.  
  5. Public Function llamame()
  6.    MsgBox "hola"
  7. End Function
  8.  
  9. Public Sub oo()
  10.    Dim lVTE As Long
  11.    Dim lPtr As Long
  12.  
  13.    lVTE = GetDWORD(ObjPtr(Me))
  14.    lPtr = GetDWORD(lVTE + &H1C)
  15.    Call CallWindowProc(ByVal lPtr, 0, 0, 0, 0)
  16. End Sub
  17.  
  18. Private Function GetDWORD(ByVal lAddr As Long) As Long
  19.    Call NtWriteVirtualMemory(-1, GetDWORD, ByVal lAddr, 4, ByVal 0&)
  20. End Function

lPtr parece ser el puntero correcto. Pero da error 'No se establecio la variable object', pareciera que ObjPtr devuelve el puntero de la clase no inicializada, en vez de la clase establecida en el objecto y a eso se debe ese error!!?
El ejemplo de cobein, sobreescribe por el puntero a un ShellCode y por eso no hay error!?

Será posible esto?  :-(


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: Karcrack en 30 Abril 2011, 18:24 pm
Has de tener en cuenta que la forma en la que se llaman las funciones de las clases no es push,push,call... (Que es como el CallWindowProc hace) si no que son cosas raras de COM y yo-que-se :xD
Es decir, aunque consigas el puntero correcto no lo podras llamar asi... Al menos hasta donde yo se


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: BlackZeroX en 30 Abril 2011, 22:00 pm
.
Quisas ayuden estos....

 Cls  (http://infrangelux.sytes.net/filex/index.php?file=Cls_SubClassing%20in%20CLS.cls&dir=/BlackZeroX/Programacion/vb6/Modulos%20de%20Clase)
 Ctl  (http://infrangelux.sytes.net/filex/index.php?file=UserControl_SubClasificado.ctl&dir=/BlackZeroX/Programacion/vb6/Modulos%20de%20Clase)

En ambos se hace una sub-clasificacion pero hara eso se debe obtener el puntero a la función... pero bueno hay esta el código, igual ayuda en algo.

por otro lado un tienes la funcion CallByname de vb6 y tambien tienes la libreria TLI (http://foro.elhacker.net/programacion_visual_basic/source_callbynameex_y_argumentos_aleatorios-t288883.0.html;wap2=).

Dulces Lunas!¡.


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: raul338 en 3 Mayo 2011, 21:56 pm
Nadie destripo el clsSubClass de Paul Caton (la version modificada por LaVolpe muy usado por Leandro y por mi)?? :huh: . En la cual hay una funcion scb_GetCallBackAddr (o similar, estoy en el movil) y scb_ReleaseCallback que justamente devuelven un "AddressOf" del ordinal (nro de funcion en orden descendente, la ultima es 1, la anteultima es 2 y asi) de un objeto (por defecto es el que lo llama) y ademas solo hay que especificar el nro de parametros (se hace magia interna con Asm). Lo unico es que todos los parametros deben ser tipo long y la funcion debe devolver long tambien (los parametros en su mayoria son punteros si es que no son numericos).

Cuando tenga internet en casa (por eso estoy muy desaparecido :xD) subire un ejemplo y varios proyectos que tengo listos


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: F3B14N en 4 Mayo 2011, 00:18 am
Nadie destripo el clsSubClass de Paul Caton (la version modificada por LaVolpe muy usado por Leandro y por mi)?? :huh: . En la cual hay una funcion scb_GetCallBackAddr (o similar, estoy en el movil) y scb_ReleaseCallback que justamente devuelven un "AddressOf" del ordinal (nro de funcion en orden descendente, la ultima es 1, la anteultima es 2 y asi) de un objeto (por defecto es el que lo llama) y ademas solo hay que especificar el nro de parametros (se hace magia interna con Asm). Lo unico es que todos los parametros deben ser tipo long y la funcion debe devolver long tambien (los parametros en su mayoria son punteros si es que no son numericos).

Cuando tenga internet en casa (por eso estoy muy desaparecido :xD) subire un ejemplo y varios proyectos que tengo listos

Creo que hablás de esto: http://siccs.googlecode.com/svn-history/r2/trunk/classes/ClsRueda.cls. Ya habia logrado solucionarlo, pero muy buen codigo. Quizas le sirva a alguien.

Saludos y muchas gracias :D


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: BlackZeroX en 4 Mayo 2011, 03:56 am
Not Found

The requested URL /svn/!svn/bc/2/trunk/classes/ClsRueda.cls. was not found on this server.

Dulces Lunas!¡.


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: LeandroA en 4 Mayo 2011, 04:50 am
@BlackZerox: Quitale el punto al final

creo que lo mejor que veas estos links
http://www.activevb.de/tutorials/tut_subclass_asm/tut_subclass_asm.html

y descargate este .zip que esta muy bueno.

http://www.activevb.de/rubriken/klassen/windows/csubclasser/subclasser.zip

pd: yo estoy utilzando estas clases y uc pero me me suelen crashear cuando llama a VirtualFree, creo que esto ocurre cuando llega un msg a WindowProc  y llame a VirtualFree, no quiero dar un ejemplo exacto para no irme por las ramas pero si alguien le encuentra una solución o quiere que entre en detalles que chifle.

Saluods.



Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: raul338 en 4 Mayo 2011, 19:14 pm
@BlackZerox: Quitale el punto al final

creo que lo mejor que veas estos links
http://www.activevb.de/tutorials/tut_subclass_asm/tut_subclass_asm.html
No se aleman pero por lo que vi. Es similar a un codigo que vi de "AND ray" implementando las novedades de win7 en vb (busquen "iTaskBarList3" en planet source code) que llamaba a una interfaz (no probe con objetos) a partir de su ordinal y un maximo de 15 parametros (segun recuerdo) pero no se podia obtener el valor devuelto. Usaba un ASM similar


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: F3B14N en 5 Mayo 2011, 17:22 pm
Código
  1. Option Explicit
  2.  
  3. Private Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
  4. Private Declare Function SetWindowLongA Lib "USER32" (ByVal Hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
  5. Private Declare Function CallWindowProcA Lib "USER32" (ByVal lpPrevWndFunc As Long, ByVal Hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  6. Private Const GWL_WNDPROC As Long = -4
  7. Private Const WM_DESTROY As Long = &H2
  8. Private Const WM_MOUSEMOVE As Long = &H200
  9.  
  10. Private PrevWndProc As Long
  11. Private bvASM(103) As Byte
  12.  
  13. Public Function WindowProc(ByVal Hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  14.    WindowProc = CallWindowProcA(PrevWndProc, Hwnd, Msg, wParam, lParam)
  15.  
  16.    If Msg = WM_DESTROY Then
  17.        Call StopSubclassing(Me.Hwnd)
  18.    ElseIf Msg = WM_MOUSEMOVE Then
  19.        Me.Caption = Timer
  20.    End If
  21.  
  22. End Function
  23.  
  24. Private Sub SetSubclassing(Obj As Object, Hwnd As Long)
  25.    Dim pASMWrapper As Long
  26.    Dim pVar As Long
  27.    Dim pObj As Long
  28.    Dim CallbackFunction As Long
  29.    Dim i As Long
  30.  
  31.    pASMWrapper = VarPtr(bvASM(0))
  32.    pObj = ObjPtr(Obj)
  33.  
  34.    Call CopyMemory(pVar, ByVal pObj, 4)
  35.    pVar = (pVar + 1784) 'Form
  36.  
  37.    Call CopyMemory(CallbackFunction, ByVal pVar, 4)
  38.  
  39.    For i = 0 To 55
  40.        bvASM(i) = Choose(i + 1, &H90, &HFF, &H5, &H0, &H0, &H0, &H0, &H6A, &H0, &H54, &HFF, &H74, &H24, &H18, &HFF, &H74, &H24, _
  41.                                 &H18, &HFF, &H74, &H24, &H18, &HFF, &H74, &H24, &H18, &H68, &H0, &H0, &H0, &H0, &HB8, &H0, &H0, _
  42.                                 &H0, &H0, &HFF, &HD0, &HFF, &HD, &H0, &H0, &H0, &H0, &HA1, &H0, &H0, &H0, &H0, &H85, &HC0, &H75, _
  43.                                 &H4, &H58, &HC2, &H10, &H0, &HA1, &H0, &H0, &H0, &H0, &H85, &HC0, &H74, &H4, &H58, &HC2, &H10, _
  44.                                 &H0, &H58, &H59, &H58, &H58, &H58, &H58, &H68, &H0, &H80, &H0, &H0, &H6A, &H0, &H68, &H0, &H0, _
  45.                                 &H0, &H0, &H51, &HB8, &H0, &H0, &H0, &H0, &HFF, &HE0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0)
  46.    Next i
  47.  
  48.    'Zahler Variable setzen
  49.    pVar = pASMWrapper + 96
  50.    Call LongToByte(pVar, bvASM, 3)
  51.    Call LongToByte(pVar, bvASM, 40)
  52.    Call LongToByte(pVar, bvASM, 58)
  53.  
  54.    'Flag Variable setzen
  55.    pVar = pASMWrapper + 100
  56.    Call LongToByte(pVar, bvASM, 45)
  57.  
  58.    'Wrapper Adresse setzen
  59.    pVar = pASMWrapper
  60.    Call LongToByte(pVar, bvASM, 84)
  61.  
  62.    'Instanzzeiger setzen
  63.    pVar = pObj
  64.    Call LongToByte(pVar, bvASM, 27)
  65.  
  66.    'Funktionszeiger setze
  67.    pVar = CallbackFunction
  68.    Call LongToByte(pVar, bvASM, 32)
  69.  
  70.    'VirtualFree Adresse setzen
  71.    'pVar = GetProcAddress(GetModuleHandle("KERNEL32"), "VirtualFree")
  72.    'Call LongToByte(pVar, bvASM, 90)
  73.  
  74.    PrevWndProc = SetWindowLongA(Hwnd, GWL_WNDPROC, pASMWrapper)
  75. End Sub
  76.  
  77. Private Sub StopSubclassing(Hwnd)
  78.    Call SetWindowLongA(Hwnd, GWL_WNDPROC, PrevWndProc)
  79. End Sub
  80.  
  81. Private Sub LongToByte(ByVal lLong As Long, ByRef bReturn() As Byte, Optional i As Integer = 0)
  82.    bReturn(i) = lLong And &HFF
  83.    bReturn(i + 1) = (lLong And 65280) / &H100
  84.    bReturn(i + 2) = (lLong And &HFF0000) / &H10000
  85.    bReturn(i + 3) = ((lLong And &HFF000000) \ &H1000000) And &HFF
  86. End Sub
  87.  
  88. Private Sub Form_Load()
  89.    Call SetSubclassing(Me, 0, Me.Hwnd)
  90. End Sub
  91.  

Gracias por la data Leandro, ahi deje el codigo un poco mas limpio para quien lo necesite, igualmente simplificar mucho el asm.

Saludos


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: LeandroA en 5 Mayo 2011, 19:27 pm
muy bueno F3B14N, veo que eliminaste VirtualAlloc y VirtualFree con lo que se termino el problema que mencionaba anteriormente al parecer todo funciona de lujo  :), además se simplifico mucho mas.

Gracias por compartirlo.

PD: fijate quizas te guste mas para crear el ASM(), creo que asi lo hacia Cobein.

Código:
        Dim sCode As String

   
        sCode = "90FF05000000006A0054FF742418FF742418FF742418FF7424186800000000B800000000FFD0FF0D00000000A10000000085C075" & _
                "0458C21000A10000000085C0740458C2100058595858585868008000006A00680000000051B800000000FFE00000000000000000"
               
        For i = 0 To Len(sCode) - 1 Step 2
            bvASM(i / 2) = CByte("&h" & Mid$(sCode, i + 1, 2))
        Next
Saludos.


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: F3B14N en 6 Mayo 2011, 17:13 pm
muy bueno F3B14N, veo que eliminaste VirtualAlloc y VirtualFree con lo que se termino el problema que mencionaba anteriormente al parecer todo funciona de lujo  :), además se simplifico mucho mas.

Gracias por compartirlo.

PD: fijate quizas te guste mas para crear el ASM(), creo que asi lo hacia Cobein.

Código:
        Dim sCode As String

   
        sCode = "90FF05000000006A0054FF742418FF742418FF742418FF7424186800000000B800000000FFD0FF0D00000000A10000000085C075" & _
                "0458C21000A10000000085C0740458C2100058595858585868008000006A00680000000051B800000000FFE00000000000000000"
               
        For i = 0 To Len(sCode) - 1 Step 2
            bvASM(i / 2) = CByte("&h" & Mid$(sCode, i + 1, 2))
        Next
Saludos.

Por nada Leandro, aqui esta aun mas simple :-X :

Código
  1. Option Explicit
  2.  
  3. Private Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
  4. Private Declare Function SetWindowLongA Lib "USER32" (ByVal Hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
  5. Private Declare Function CallWindowProcA Lib "USER32" (ByVal lpPrevWndFunc As Long, ByVal Hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  6. Private Const GWL_WNDPROC As Long = -4
  7. Private Const WM_DESTROY As Long = &H2
  8. Private Const WM_MOUSEMOVE As Long = &H200
  9.  
  10. Private PrevWndProc As Long
  11. Private bvASM(40) As Byte
  12.  
  13. Public Function WindowProc(ByVal Hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  14.    WindowProc = CallWindowProcA(PrevWndProc, Hwnd, Msg, wParam, lParam)
  15.  
  16.    If Msg = WM_DESTROY Then
  17.        Call StopSubclassing(Me.Hwnd)
  18.    ElseIf Msg = WM_MOUSEMOVE Then
  19.        Me.Caption = Timer
  20.    End If
  21. End Function
  22.  
  23. Private Sub SetSubclassing(Obj As Object, Hwnd As Long)
  24.    Dim WindowProcAddress As Long
  25.    Dim pObj As Long
  26.    Dim pVar As Long
  27.  
  28.    Dim i As Long
  29.  
  30.    For i = 0 To 40
  31.        bvASM(i) = Choose(i + 1, &H55, &H8B, &HEC, &H83, &HC4, &HFC, &H8D, &H45, &HFC, &H50, &HFF, &H75, &H14, _
  32.                                 &HFF, &H75, &H10, &HFF, &H75, &HC, &HFF, &H75, &H8, &H68, &H0, &H0, &H0, &H0, _
  33.                                 &HB8, &H0, &H0, &H0, &H0, &HFF, &HD0, &H8B, &H45, &HFC, &HC9, &HC2, &H10, &H0)
  34.    Next i
  35.  
  36.    pObj = ObjPtr(Obj)
  37.  
  38.    Call CopyMemory(pVar, ByVal pObj, 4)
  39.    Call CopyMemory(WindowProcAddress, ByVal (pVar + 1784), 4)
  40.  
  41.    Call LongToByte(pObj, bvASM, 23)
  42.    Call LongToByte(WindowProcAddress, bvASM, 28)
  43.  
  44.    PrevWndProc = SetWindowLongA(Hwnd, GWL_WNDPROC, VarPtr(bvASM(0)))
  45. End Sub
  46.  
  47. Private Sub StopSubclassing(Hwnd)
  48.    Call SetWindowLongA(Hwnd, GWL_WNDPROC, PrevWndProc)
  49. End Sub
  50.  
  51. Private Sub LongToByte(ByVal lLong As Long, ByRef bReturn() As Byte, Optional i As Integer = 0)
  52.    bReturn(i) = lLong And &HFF
  53.    bReturn(i + 1) = (lLong And 65280) / &H100
  54.    bReturn(i + 2) = (lLong And &HFF0000) / &H10000
  55.    bReturn(i + 3) = ((lLong And &HFF000000) \ &H1000000) And &HFF
  56. End Sub
  57.  
  58. Private Sub Form_Load()
  59.    Call SetSubclassing(Me, 0, Me.Hwnd)
  60. End Sub


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: LeandroA en 7 Mayo 2011, 12:02 pm
Simplemente asombroso la verdad acostumbrado a utilizar la clase de Paul Caton  que son muchisimas lineas, con esto esta barbaro.

para informacion a todos, si quieren utilizarlo desde un modulo clase cambiar este valor en esta linea
Código:
Call CopyMemory(WindowProcAddress, ByVal (pVar + 1784), 4)
para un modulo clase cambiar 1784 por 28
y para un User Control  por 1956

Seguramente me surjan algunas dudas mas adelante sobre como implementar un subclass y un Api Timer en un mismo modulo o bien dos Sub para distintos hilos.
si tenes idea postealo para agendarlo.

Saludos.


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: BlackZeroX en 8 Mayo 2011, 02:22 am
.
ja ja ja por lo menos no me funciona este codigo creando una ventana con CreateWindowEx y despues sud-clásificandola TODO desde el modulo de clase xP.

cambiando como ya menciono LeandroA: 1784 por 28 en la linea ya indicada anteriormente.

Dulces Lunas!¡.


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: F3B14N en 8 Mayo 2011, 04:26 am
.
ja ja ja por lo menos no me funciona este codigo creando una ventana con CreateWindowEx y despues sud-clásificandola TODO desde el modulo de clase xP.

cambiando como ya menciono LeandroA: 1784 por 28 en la linea ya indicada anteriormente.

Dulces Lunas!¡.

jejerejerejoju


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: BlackZeroX en 8 Mayo 2011, 06:39 am
 :¬¬ :¬¬ :¬¬


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: LeandroA en 8 Mayo 2011, 09:30 am
Hola BlackZeroX si funciona quizas lo probaste con un STATIC y no recibe el WM_MouseMove proba con BUTTON

Class1
Código:
Option Explicit
Private Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function SetWindowLongA Lib "user32" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProcA Lib "user32" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const GWL_WNDPROC As Long = -4
Private Const WM_DESTROY As Long = &H2
 
Private PrevWndProc As Long
Private bvASM(40) As Byte

Private Declare Function DestroyWindow Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
Private Const WS_VISIBLE As Long = &H10000000
Private mWnd As Long

Public Function WindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    WindowProc = CallWindowProcA(PrevWndProc, hwnd, Msg, wParam, lParam)
 
    If Msg = WM_DESTROY Then
        Call StopSubclassing(hwnd)
    End If
   
    Debug.Print Msg, wParam, lParam
End Function
 
Private Sub SetSubclassing(Obj As Object, hwnd As Long)
    Dim WindowProcAddress As Long
    Dim pObj As Long
    Dim pVar As Long
 
    Dim i As Long
 
    For i = 0 To 40
        bvASM(i) = Choose(i + 1, &H55, &H8B, &HEC, &H83, &HC4, &HFC, &H8D, &H45, &HFC, &H50, &HFF, &H75, &H14, _
                                 &HFF, &H75, &H10, &HFF, &H75, &HC, &HFF, &H75, &H8, &H68, &H0, &H0, &H0, &H0, _
                                 &HB8, &H0, &H0, &H0, &H0, &HFF, &HD0, &H8B, &H45, &HFC, &HC9, &HC2, &H10, &H0)
    Next i
 
    pObj = ObjPtr(Obj)
 
    Call CopyMemory(pVar, ByVal pObj, 4)
    Call CopyMemory(WindowProcAddress, ByVal (pVar + 28), 4)
 
    Call LongToByte(pObj, bvASM, 23)
    Call LongToByte(WindowProcAddress, bvASM, 28)
 
    PrevWndProc = SetWindowLongA(hwnd, GWL_WNDPROC, VarPtr(bvASM(0)))
End Sub
 
Private Sub StopSubclassing(hwnd)
    Call SetWindowLongA(hwnd, GWL_WNDPROC, PrevWndProc)
End Sub
 
Private Sub LongToByte(ByVal lLong As Long, ByRef bReturn() As Byte, Optional i As Integer = 0)
    bReturn(i) = lLong And &HFF
    bReturn(i + 1) = (lLong And 65280) / &H100
    bReturn(i + 2) = (lLong And &HFF0000) / &H10000
    bReturn(i + 3) = ((lLong And &HFF000000) \ &H1000000) And &HFF
End Sub

Private Sub Class_Initialize()
    mWnd = CreateWindowEx(0&, "Button", "Hola Mundo", WS_VISIBLE, 0&, 0&, 300, 300, 0&, 0&, App.hInstance, ByVal 0&)
    If mWnd <> 0 Then Call SetSubclassing(Me, mWnd)
End Sub

Private Sub Class_Terminate()
    If mWnd <> 0 Then
        Call StopSubclassing(mWnd)
        DestroyWindow mWnd
    End If
End Sub

Saludos.


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: BlackZeroX en 8 Mayo 2011, 11:11 am
...
Edito:

Cuando declaro algunas cosas mas crashea  >:D... ya encontre el horror, es que el ASM modifica la 1ra cosa publica y como tenia una variable publica pues crasheaba ya que no era mi WinProc...

Código
  1.  
  2. Dim c As Class1
  3. Private Sub Form_Load()
  4.    Set c = New Class1
  5. End Sub
  6.  
  7.  

Código
  1.  
  2. Option Explicit
  3.  
  4. Private Const GWL_WNDPROC                   As Long = -4
  5. Private Const WM_DESTROY                    As Long = &H2
  6. Private Const WS_VISIBLE                    As Long = &H10000000
  7. Private Const MAX_PATH                      As Integer = 260
  8. Private Const MAXDWORD                      As Long = &HFFFF
  9. Private Const INVALID_HANDLE_VALUE          As Long = -1
  10.  
  11. Private Type FILETIME
  12.    dwLowDateTime                           As Long
  13.    dwHighDateTime                          As Long
  14. End Type
  15.  
  16. Private Type WIN32_FIND_DATA                                        '// Bytes...
  17.    dwFileAttributes                        As Long                 '// 4
  18.    ftCreationTime                          As FILETIME             '// 8
  19.    ftLastAccessTime                        As FILETIME             '// 8
  20.    ftLastWriteTime                         As FILETIME             '// 8
  21.    nFileSizeHigh                           As Long                 '// 4
  22.    nFileSizeLow                            As Long                 '// 4
  23.    dwReserved0                             As Long                 '// 4
  24.    dwReserved1                             As Long                 '// 4
  25.    cFileName                               As String * MAX_PATH    '// MAX_PATH*2 = 260*2 = 520
  26.    cAlternate                              As String * 14          '// 14*2 = 28
  27. End Type                                                            '// total bytes: 592 bytes...  = &H250
  28.  
  29. Private Declare Function WaitMessage Lib "user32" () As Long
  30. Private Declare Function lstrcmp Lib "KERNEL32" Alias "lstrcmpA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
  31. Private Declare Function FindFirstFile& Lib "KERNEL32" Alias "FindFirstFileA" (ByVal lpFileName$, lpFindFileData As WIN32_FIND_DATA)
  32. Private Declare Function FindNextFile& Lib "KERNEL32" Alias "FindNextFileA" (ByVal hFindFile&, lpFindFileData As WIN32_FIND_DATA)
  33. Private Declare Function GetFileAttributes Lib "KERNEL32" Alias "GetFileAttributesA" (ByVal lpFileName As String) As Long
  34. Private Declare Function FindClose Lib "KERNEL32" (ByVal hFindFile As Long) As Long
  35.  
  36. '   //  SubClassing
  37. Private Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
  38. Private Declare Function SetWindowLongA Lib "user32" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
  39. Private Declare Function CallWindowProcA Lib "user32" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  40. Private Declare Function DestroyWindow Lib "user32.dll" (ByVal hwnd As Long) As Long
  41. Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
  42.  
  43. Private bIni                                As Boolean
  44. Private sDir                                As String
  45. Private sCriterios()                        As String
  46. Private bIncludeFolders                     As Boolean
  47. Private bCancel                             As Boolean
  48. Private tVBFAFoundInDir                     As VbFileAttribute
  49. Private tVBFAFoundInFile                    As VbFileAttribute
  50. Private lhSearchF()                         As Long
  51. Private lsIndex(0 To 1)                     As Long
  52. Private dblBytesNow_                        As Double
  53. Private tWFDFound                           As WIN32_FIND_DATA
  54. Private bRun                                As Boolean
  55. Private bFound                              As Boolean
  56. Private bPause                              As Boolean
  57. 'public AllowEvents                        As Boolean ' // No pongan nada en modo publico xS.
  58. private bAllowEvents                        As Boolean ' // No pongan nada en modo publico xS.
  59.  
  60. Private PrevWndProc                         As Long
  61. Private bvASM(40)                           As Byte
  62. Private mWnd                                As Long
  63.  
  64. Event Folder(ByRef PathFolder As String)
  65. Event File(ByVal TypeOfFile As Long)
  66. Event Begin()
  67. Event Finish()
  68.  
  69. Public Function WindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  70.    WindowProc = CallWindowProcA(PrevWndProc, hwnd, Msg, wParam, lParam)
  71.  
  72.    If Msg = WM_DESTROY Then
  73.        Call StopSubclassing(hwnd)
  74.    End If
  75.  
  76.    Debug.Print Msg, wParam, lParam
  77. End Function
  78.  
  79. Private Sub SetSubclassing(Obj As Object, hwnd As Long)
  80.    Dim WindowProcAddress As Long
  81.    Dim pObj As Long
  82.    Dim pVar As Long
  83.  
  84.    Dim i As Long
  85.  
  86.    For i = 0 To 40
  87.        bvASM(i) = Choose(i + 1, &H55, &H8B, &HEC, &H83, &HC4, &HFC, &H8D, &H45, &HFC, &H50, &HFF, &H75, &H14, _
  88.                                 &HFF, &H75, &H10, &HFF, &H75, &HC, &HFF, &H75, &H8, &H68, &H0, &H0, &H0, &H0, _
  89.                                 &HB8, &H0, &H0, &H0, &H0, &HFF, &HD0, &H8B, &H45, &HFC, &HC9, &HC2, &H10, &H0)
  90.    Next i
  91.  
  92.    pObj = ObjPtr(Obj)
  93.  
  94.    Call CopyMemory(pVar, ByVal pObj, 4)
  95.    Call CopyMemory(WindowProcAddress, ByVal (pVar + 28), 4)
  96.  
  97.    Call LongToByte(pObj, bvASM, 23)
  98.    Call LongToByte(WindowProcAddress, bvASM, 28)
  99.  
  100.    PrevWndProc = SetWindowLongA(hwnd, GWL_WNDPROC, VarPtr(bvASM(0)))
  101. End Sub
  102.  
  103. Private Sub StopSubclassing(hwnd)
  104.    Call SetWindowLongA(hwnd, GWL_WNDPROC, PrevWndProc)
  105. End Sub
  106.  
  107. Private Sub LongToByte(ByVal lLong As Long, ByRef bReturn() As Byte, Optional i As Integer = 0)
  108.    bReturn(i) = lLong And &HFF
  109.    bReturn(i + 1) = (lLong And 65280) / &H100
  110.    bReturn(i + 2) = (lLong And &HFF0000) / &H10000
  111.    bReturn(i + 3) = ((lLong And &HFF000000) \ &H1000000) And &HFF
  112. End Sub
  113.  
  114. Private Sub Class_Initialize()
  115.    mWnd = CreateWindowEx(0&, "Button", "Hola Mundo", WS_VISIBLE, 0&, 0&, 300, 300, 0&, 0&, App.hInstance, ByVal 0&)
  116.    If mWnd <> 0 Then Call SetSubclassing(Me, mWnd)
  117. End Sub
  118.  
  119. Private Sub Class_Terminate()
  120.    If mWnd <> 0 Then
  121.        Call StopSubclassing(mWnd)
  122.        DestroyWindow mWnd
  123.    End If
  124. End Sub
  125.  
  126.  

Temibles Lunas!¡.


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: F3B14N en 8 Mayo 2011, 18:53 pm
En modulos clase:

Call CopyMemory(WindowProcAddress, ByVal (pVar + &H1C + (ProcIndex * 4&)), 4)


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: BlackZeroX en 8 Mayo 2011, 20:25 pm
En modulos clase:

Call CopyMemory(WindowProcAddress, ByVal (pVar + &H1C + (ProcIndex * 4&)), 4)

excelente con el ProcIndex podremos hacer varias subclasificaciones con el codigo xD

Dulces Lunas!¡.


Título: Re: Obtener puntero de funcion dentro de un form o class.
Publicado por: BlackZeroX en 9 Mayo 2011, 05:52 am
alguien tiene el ASM?, quiero ver que es lo que modifica/hace.

Dulces Lunas!¡.