[PREGUNTA] Convertir una declaracion API de C# a VB6 (problema con punteros)

Iniciado por el_c0c0, 16 Marzo 2012, 19:01 PM

0 Miembros y 3 Visitantes están viendo este tema.

el_c0c0

Buenas, la pregunta es simple. Tengo una api declarada en C# (en una clase).. y la quiero pasar a VB6. Es stdcall por lo que probe, asi que no habria dramas.
El tema es que usa un puntero a un array de bytes, y probe de mil y 1 formas y sigue crasheando.

Código (c#) [Seleccionar]
       [DllImport("TPMCtrl_WinBond.dll")]
       public static extern unsafe int ReadDataFromTPM(byte* UserData);


probe con cada caso de estas declaraciones:
Código (vb) [Seleccionar]

Private Declare Function ReadDataFromTPM Lib "TPMCtrl_WinBond.dll" (UserData As Any) As Long
Private Declare Function ReadDataFromTPM Lib "TPMCtrl_WinBond.dll" (UserData As Byte) As Long
Private Declare Function ReadDataFromTPM Lib "TPMCtrl_WinBond.dll" (ByVal UserData As Byte) As Long
Private Declare Function ReadDataFromTPM Lib "TPMCtrl_WinBond.dll" (UserData As Long) As Long
Private Declare Function ReadDataFromTPM Lib "TPMCtrl_WinBond.dll" (ByVal UserData As Long) As Long

Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Var() As Any) As Long

Private c_bvUserData(24)       As Byte


con sus respectivos varptr al array de bytes (en los casos que hay ByVal). tambien probe con VarPtrArray, y lo mismo... hasta hice un odl: (obviamente era 1 solo, no todos juntos)
[entry("ReadDataFromTPM")]
long ReadDataFromTPM([in] long UserData);
long ReadDataFromTPM([in] byte *UserData);
long ReadDataFromTPM([in] byte * UserData[24]);


y sigue crasheando...

Recalco que, el error NO ES DE CONVERSION DE LLAMADAS NO VALIDO (se ve que no es cdecl).
el tamaño del array de bytes esta bien, viene de esto:
Código (c#) [Seleccionar]

private byte[] m_UserData = new byte[0x18];

y originalmente se llama asi:
Código (c#) [Seleccionar]
       public unsafe void GetUserData()
       {
           fixed (byte* numRef = this.m_UserData)
           {
               try
               {
                   ReadDataFromTPM(numRef);
               }
               catch
               {
                   throw;
               }
           }
       }


apreciaria ayuda...
saludos

'-     coco
"Te voy a romper el orto"- Las hemorroides

x64core

Y esa DLL adonde la encuentro? :P subirla
has probado con esto:

Private Declare Function ReadDataFromTPM Lib "TPMCtrl_WinBond.dll" (UserData As any) As Long

dim mybytes(9) as byte
...
ReadDataFromTPM(byval varptr(mybytes(0)))

Karcrack

Código (vb) [Seleccionar]
Private Declare Function ReadDataFromTPM Lib "TPMCtrl_WinBond.dll" (UserData As Byte) As Long
Código (vb) [Seleccionar]
Dim m_UserData(0x18) As Byte
Call ReadDataFromTPM(mybytes(0))


Sería equivalente al code de RHL pero sin necesidad de llamar a VarPtr()... tal y como está aquí arriba debería de funcionarte a la perfección.

el_c0c0

Hola , gracias por responder @Karcrack y @RHL.

Probe de las 2 formas recien (antes ya las habia probado), y sigue explotando.


La dll la puedo subir, no hay drama.
El tema es que no funciona si no se ejecuta bajo una Classmate netbook (por el acceso a drivers del TPM).

Basicamente ya no entiendo mas nada!!! O bien el codigo fuente en el que me estoy basando esta mal, o no se. (Tecnicamente esta bien, ya que esa aplicacion funciona).

Me es dificil andar debugueando con el olly, porque las llamadas en C# se generan en el framework, y no en el .exe principal.

Gracias
'-     coco
"Te voy a romper el orto"- Las hemorroides

Karcrack

Comprueba que realmente la convención de llamada sea __stdcall. Comprueba también que la DLL generada por C# sea una librería estándar (no ActiveX).

el_c0c0

@Karcrack:

Si la declaracion del C# esta asi, yo asumo que es stdcall. Ademas, llamo a otras funciones que NO llevan parametros y devuelven siempre lo mismo (y no joden el stack).
Ademas NO ES ActiveX:



PD: la DLL mencionada NO ESTA hecha en C#... La aplicacion que la usa, SI.

Voy a probar de hacer algo en C# que llame a esa dll, para ver que onda... Realmente me tiene atonito esto
'-     coco
"Te voy a romper el orto"- Las hemorroides

el_c0c0

Bueno, creo que ya esta. Probe con el modulo cCDECL de Paul Caton, y no explota. Esto fue gracias al IDA, porque no veia que se popearan los parametros, o que se usara retn xxx.

Gracias y disculpas por la molestia...
Proximamente vamos a estar probando esto en el foro de seguridad, referido a las Netbooks del Gobierno (argentina) y otras netbooks basadas en Intel Classmate. Gracias
'-     coco
"Te voy a romper el orto"- Las hemorroides

x64core

Yo no veo que en la imagen diga nada de stdcall o la convencion de llamada :P
Y que yo sepa siempre se eliminan los parametros al retorno con la RETN

el_c0c0

Cita de: RHL en 18 Marzo 2012, 22:58 PM
Yo no veo que en la imagen diga nada de stdcall o la convencion de llamada :P
Y que yo sepa siempre se eliminan los parametros al retorno con la RETN

No, yo me referia a la declaracion de C#... no dice CDECL (y las llamadas a APIs comunes, se declaran igual... por eso, pense que era STDCALL).
2º, en el RETN no se eliminaban los parametros, pero arriba del RETN habia varios POP, que luego vi que no tenian nada que ver con el stack... Misteriosamente el VB no decia nada de la convencion de llamadas (normalmente lo hace)...

'-     coco
"Te voy a romper el orto"- Las hemorroides

x64core

Cita de: el_c0c0 en 19 Marzo 2012, 00:22 AM
No, yo me referia a la declaracion de C#... no dice CDECL (y las llamadas a APIs comunes, se declaran igual... por eso, pense que era STDCALL).
2º, en el RETN no se eliminaban los parametros, pero arriba del RETN habia varios POP, que luego vi que no tenian nada que ver con el stack... Misteriosamente el VB no decia nada de la convencion de llamadas (normalmente lo hace)...



Es raro entonces es como decir que la funcion esta mal porque el RETN forma parte de ella  :silbar:
pues los POP por algo deben estar no seguramente usaba registros o variables locales...
cuanto era el valor de RETN?