Título: puntero de una funcion con dos parametros. Publicado por: LeandroA en 4 Septiembre 2011, 20:47 pm Hola, estoy intentando obtener el puntero de una funcion dentro de una clase tal como se habló dentro de este post (http://foro.elhacker.net/programacion_visual_basic/obtener_puntero_de_funcion_dentro_de_un_form_o_class-t326036.0.html), pero mi problema es que la funcion no tiene cuatro paramentros sino dos y cuando intento llamar a la funcion llega a funcionar pero inmediatamente revienta el vb bien, no se como hay que modificar el ASM para indicar que la funcion tiene dos long como parametro.
esto es lo que estoy haciendo, intento disparar el callback de una webcam dentro de un modulo clase 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 capCreateCaptureWindowA Lib "avicap32.dll" (ByVal lpszWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Integer, ByVal hWndParent As Long, ByVal nID As Long) As Long Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long Private Const WM_USER As Long = &H400 Private Const WM_CAP_START As Long = WM_USER Private Const WM_CAP_SET_CALLBACK_FRAME As Long = WM_CAP_START + 5 Private Const WM_CAP_DRIVER_CONNECT As Long = WM_CAP_START + 10 Private Const WM_CAP_DRIVER_DISCONNECT As Long = WM_CAP_START + 11 Private Const WM_CAP_GET_VIDEOFORMAT As Long = WM_CAP_START + 44 Private Const WM_CAP_GRAB_FRAME As Long = WM_CAP_START + 60 Private Type VIDEOHDR lpData As Long dwBufferLength As Long dwBytesUsed As Long dwTimeCaptured As Long dwUser As Long dwFlags As Long dwReserved(3) As Long End Type Private bvASM(40) As Byte Private hwndCap As Long Public Function FrameCallBack(ByVal lWnd As Long, ByVal lpVHdr As Long) As Long Debug.Print "FUNCIONA!" End Function Public Function Capture() Call SendMessage(hwndCap, WM_CAP_GRAB_FRAME, ByVal 0&, ByVal 0&) End Function Public Function CreateCaptureWindow() As Boolean hwndCap = capCreateCaptureWindowA(vbNullString, 0&, 0&, 0&, 0&, 0&, 0&, 0&) If hwndCap Then Call SendMessage(hwndCap, WM_CAP_SET_CALLBACK_FRAME, 0, GetAdressMe(Me)) CreateCaptureWindow = True End If End Function Function capGetVideoFormat(ByVal hCapWnd As Long, ByVal CapFormatSize As Long, ByVal BmpFormat As Long) As Long capGetVideoFormat = SendMessage(hCapWnd, WM_CAP_GET_VIDEOFORMAT, CapFormatSize, BmpFormat) End Function Public Function DestroyCaptureWindow() As Boolean If hwndCap Then DestroyCaptureWindow = DestroyWindow(hwndCap): hwndCap = 0 End Function Public Function ConnectDriver() As Boolean If hwndCap Then ConnectDriver = SendMessage(hwndCap, WM_CAP_DRIVER_CONNECT, 0&, 0&) End Function Public Function DisconnectDriver() As Boolean If hwndCap Then Call SendMessage(hwndCap, WM_CAP_SET_CALLBACK_FRAME, 0&, vbNull) DisconnectDriver = SendMessage(hwndCap, WM_CAP_DRIVER_DISCONNECT, 0&, 0&) End If End Function Private Function GetAdressMe(Obj As Object) 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) GetAdressMe = VarPtr(bvASM(0)) End Function 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 en el formulario con un boton Código: Option Explicit Dim C1 As Class1 Private Sub Command1_Click() C1.Capture End Sub Private Sub Form_Load() Set C1 = New Class1 C1.CreateCaptureWindow C1.ConnectDriver End Sub Private Sub Form_Unload(Cancel As Integer) C1.DisconnectDriver C1.DestroyCaptureWindow Set C1 = Nothing End Sub Título: Re: puntero de una funcion con dos parametros. Publicado por: Karcrack en 12 Septiembre 2011, 00:34 am Tristemente no tengo tiempo ahora para ponerme a debuggear esto... De todas formas no veo donde estas parcheando la vTable... :S Es decir... la función FrameCallBack() no tienes porque declararla si estas usando código ASM... puedes pasar directamente el puntero al array de Bytes que contiene el código y se ejecutará... Que es lo que hace ese código ASM?
Por otra parte, las funciones que hay en las clases no funcionan del mismo método a la hora de recibir y devolver variables... el stack guarda otra información despues de los punteros.. y para devolver variables no se mete el resultado en EAX sin más... se mete en otra dirección y se indica el tipo en EAX... es algo extraño xD De aquí unos días tendré tiempo libre... entonces lo miraré :) |