elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP)
| | | |-+  Programación Visual Basic (Moderadores: LeandroA, seba123neo)
| | | | |-+  Ayuda con CallAPIByName
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ayuda con CallAPIByName  (Leído 2,763 veces)
C0r3_

Desconectado Desconectado

Mensajes: 2


Ver Perfil
Ayuda con CallAPIByName
« en: 2 Febrero 2011, 01:08 am »

Código:
'---------------------------------------------------------------------------------------
' Module      : cCallAPIByName
' DateTime    : 31/08/2008 19:40
' Author      : Cobein
' Mail        : cobein27@hotmail.com
' WebPage     : http://www.advancevb.com.ar
' Purpose     : Call APIs by name
' Usage       : At your own risk
' Requirements: None
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce
'               or publish this code on any web site,
'               online service, or distribute as source
'               on any media without express permission.
'
' Credits     : Arne Elster, original callpointer function.
'
' History     : 31/08/2008 First Cut....................................................
'---------------------------------------------------------------------------------------
Option Explicit
 
Private Declare Sub CpyMem Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal dlen As Long)
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function LoadLibraryA Lib "kernel32" (ByVal lpLibFileName As String) As Long
 
Public Function DoNotCall() As Long
'
End Function
 
Public Function CallAPIByName(ByVal sLib As String, ByVal sMod As String, ParamArray Params()) As Long
    Dim lPtr                As Long
    Dim bvASM(&HEC00& - 1)  As Byte
    Dim i                   As Long
    Dim lMod                As Long
 
    lMod = GetProcAddress(LoadLibraryA(sLib), sMod)
    If lMod = 0 Then Exit Function
 
    lPtr = VarPtr(bvASM(0))
    CpyMem ByVal lPtr, &H59595958, &H4:            lPtr = lPtr + 4
    CpyMem ByVal lPtr, &H5059, &H2:                lPtr = lPtr + 2
    For i = UBound(Params) To 0 Step -1
        CpyMem ByVal lPtr, &H68, &H1:              lPtr = lPtr + 1
        CpyMem ByVal lPtr, CLng(Params(i)), &H4:   lPtr = lPtr + 4
    Next
    CpyMem ByVal lPtr, &HE8, &H1:                  lPtr = lPtr + 1
    CpyMem ByVal lPtr, lMod - lPtr - 4, &H4:       lPtr = lPtr + 4
    CpyMem ByVal lPtr, &HC3, &H1
 
    Dim lVTE                As Long
    Dim lRet                As Long
 
    CpyMem lVTE, ByVal ObjPtr(Me), &H4
    lVTE = lVTE + &H1C
    CpyMem lRet, ByVal lVTE, &H4
    CpyMem ByVal lVTE, VarPtr(bvASM(0)), &H4
    CallAPIByName = DoNotCall
    CpyMem ByVal lVTE, lRet, &H4
End Function

He empezado a estudiar este source para llamar a apis sin declararlas pero tengo problemas para entender como funciona. Parece que usa asm para pushear los parametros en el stack? Las instrucciones asm estan en opcodes? Me gustaria que alguien me ayudara un poco a entender por completo el codigo que me parece muy interesante.

Un saludo


En línea

Karcrack


Desconectado Desconectado

Mensajes: 2.416


Se siente observado ¬¬'


Ver Perfil
Re: Ayuda con CallAPIByName
« Respuesta #1 en: 2 Febrero 2011, 12:31 pm »

Este es uno de los códigos mas "simples" para llamar APIs de forma dinámica.

Como sabrás este código va en una clase. Las clases de Vb6 tienen una estructura interna donde almacenan la dirección de memoria donde se encuentran las funciones. A esta estructura se le llama vTable o Virtual Table...


Este código lo que hace es generar el código ASM para el pusheo de los parámetros y la llamada a la API, almacena ese código ASM en un array de bytes y parchea la vTable para que apunte al nuevo código ASM....

Te comento el código linea por linea:
Código
  1. Public Function DoNotCall() As Long
  2. 'FUNCION VACIA QUE SERA PARCHEADA
  3. End Function
  4.  
  5. Public Function CallAPIByName(ByVal sLib As String, ByVal sMod As String, ParamArray Params()) As Long
  6.    Dim lPtr                As Long
  7.    Dim bvASM(&HEC00& - 1)  As Byte
  8.    Dim i                   As Long
  9.    Dim lMod                As Long
  10.  
  11.    lMod = GetProcAddress(LoadLibraryA(sLib), sMod) 'OBTENEMOS EL PUNTERO DEL API
  12.    If lMod = 0 Then Exit Function
  13.  
  14.    lPtr = VarPtr(bvASM(0)) 'OBTENEMOS EL PUNTERO DEL ARRAY DE BYTES VACIO
  15.    CpyMem ByVal lPtr, &H59595958, &H4:            lPtr = lPtr + 4 'COPIAMOS EN EL ARRAY CODIGO ASM
  16.    CpyMem ByVal lPtr, &H5059, &H2:                lPtr = lPtr + 2 'COPIAMOS EN EL ARRAY CODIGO ASM
  17.    For i = UBound(Params) To 0 Step -1 'POR CADA PARAMETRO...
  18.        CpyMem ByVal lPtr, &H68, &H1:              lPtr = lPtr + 1 'METEMOS UN PUSH...
  19.        CpyMem ByVal lPtr, CLng(Params(i)), &H4:   lPtr = lPtr + 4 '...CON EL VALOR
  20.    Next
  21.    CpyMem ByVal lPtr, &HE8, &H1:                  lPtr = lPtr + 1 'METEMOS EL OPCODE DEL CALL
  22.    CpyMem ByVal lPtr, lMod - lPtr - 4, &H4:       lPtr = lPtr + 4 ' Y LA DIRECCION RELATIVA
  23.    CpyMem ByVal lPtr, &HC3, &H1 'AHORA METEMOS EL RET
  24.  
  25.    Dim lVTE                As Long
  26.    Dim lRet                As Long
  27.  
  28.    CpyMem lVTE, ByVal ObjPtr(Me), &H4 'OBTENEMOS EL PUNTERO A LA vTABLE
  29.    lVTE = lVTE + &H1C 'OBTENEMOS EL PUNTERO A LA DIRECCION DE LA FUNCION "zDoNotCall"
  30.    CpyMem lRet, ByVal lVTE, &H4 ' SACAMOS LA DIRECCION ORIGINAL
  31.    CpyMem ByVal lVTE, VarPtr(bvASM(0)), &H4 'PARCHEAMOS LA FUNCION PARA QUE EJECUTE NUESTRO CODIGO ASM
  32.    CallAPIByName = DoNotCall
  33.    CpyMem ByVal lVTE, lRet, &H4 'RESTAURAMOS LA FUNCION
  34. End Function
  35.  

Respecto a los primeros OPCODES que se introducen... Resulta que las llamadas a las funciones no siguen un convencion stdcall, si no que la posicion de los parametros en el stack varia segun la cantidad y el tipo de estos, ademas que para devolver valores tambien varia dependiendo del tipo variable...
Asi que los Opcodes iniciales se encargan de parchear el stack para dejar la direccion de retorno correcta ;)


Ante cualquier duda ya sabes ;)


« Última modificación: 2 Febrero 2011, 12:32 pm por Karcrack » En línea

Dessa


Desconectado Desconectado

Mensajes: 624



Ver Perfil
Re: Ayuda con CallAPIByName
« Respuesta #2 en: 2 Febrero 2011, 18:01 pm »

Karcrack, sos un capo !!!
En línea

Adrian Desanti
Karcrack


Desconectado Desconectado

Mensajes: 2.416


Se siente observado ¬¬'


Ver Perfil
Re: Ayuda con CallAPIByName
« Respuesta #3 en: 2 Febrero 2011, 19:20 pm »

Dessa, harás que me sonroje !!! :P
En línea

C0r3_

Desconectado Desconectado

Mensajes: 2


Ver Perfil
Re: Ayuda con CallAPIByName
« Respuesta #4 en: 4 Febrero 2011, 22:52 pm »

Muchas gracias Karcrack me lo has dejado mucho mas claro. Ahora no estoy en mi ordenador lo he estado actualizando y he tenido que formatear. Le echare otra ojeada cuando este en el mio y tenga mas tiempo si hay algo ya se a quien acudir.
Como te han dicho eres un capo  ;-)
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines