1. To visit protected / private sections of the forum you must be connected with your user account. If you are not yet a member of our forum, you can create it now for free!.

User Tag List

Thread: Dynamic API Calls - Using Reflection.Emit

Results 1 to 3 of 3

  1. #1
    Junior Member
    Join Date Nov 2011
    Posts 1
    Like (Stats)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quoted
    0 Post(s)

    Dynamic API Calls - Using Reflection.Emit

    I coded this class which can dynamically call a windows API function at runtime using reflection.emit.

    Code:
    Code:
    Imports System.Reflection
    Imports System.Reflection.Emit
    Imports System.Runtime.InteropServices
    
    'CharSet Codes :
    
    ' None - 1
    ' ANSI - 2
    ' Unicode - 3
    ' Auto - 4
    
    'Calling Conventions Codes (System.Reflection) :
    
    ' Standard - 1
    ' VarArgs - 2
    ' Any - 3
    ' HasThis - 32
    ' ExplicitThis - 64
    
    'Native Calling Convention Codes (System.Runtime.InteropServices) :
    
    ' Winapi - 1
    ' Cdecl - 2
    ' StdCall - 3
    ' ThisCall - 4
    ' FastCall - 5
    
    'Author : Salmoneus
    
    Public Class DynamicAPIs
    
        Private WindowsLibrary, MethodName, AssemblyName, ModuleName, ClassName As String
        Private CharacterSet, CallingConventions, NativeCallingConvention As Integer
        Private ReturnType As Type
        Private Parameters As Object()
    
        Public Sub New(ByVal wLibrary$, ByVal mName$, ByVal asmName$, ByVal modName$, ByVal cName$, _
         ByVal cSet%, ByVal cConventions%, ByVal nCallingConvention%, _
         ByVal rType As Type, _
         ByVal Params As Object())
    
      WindowsLibrary = wLibrary
      MethodName = mName
      AssemblyName = asmName
      ModuleName = modName
      ClassName = cName
      CharacterSet = cSet
      CallingConventions = cConventions
      NativeCallingConvention = nCallingConvention
      ReturnType = rType
      Parameters = Params
    
      CreateDynamicAPI()
    
        End Sub
    
        Private Function CreateDynamicAPI() As Object
    
      Dim ASMB As AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(New AssemblyName(AssemblyName), AssemblyBuilderAccess.RunAndSave)
      Dim MODB As ModuleBuilder = ASMB.DefineDynamicModule(ModuleName)
      Dim TB As TypeBuilder = MODB.DefineType(ClassName, TypeAttributes.Public)
    
      Dim ParameterTypes As [Type]() = New [Type](Parameters.Length - 1) {}
    
      For i% = 0 To Parameters.Length - 1
        ParameterTypes(i) = Parameters(i).[GetType]()
      Next
    
      Dim MB As MethodBuilder = TB.DefinePInvokeMethod(MethodName, _
         WindowsLibrary, _
         MethodAttributes.Public Or MethodAttributes.Static Or MethodAttributes.PinvokeImpl, _
         CallingConventions, _
         ReturnType, _
         ParameterTypes, _
         NativeCallingConvention, _
         CharacterSet)
    
      MB.SetImplementationFlags(MB.GetMethodImplementationFlags() Or _
         MethodImplAttributes.PreserveSig)
    
      Return TB.CreateType().GetMethod(MethodName).Invoke(Nothing, Parameters)
    
        End Function
    
    End Class
    Usage:

    Code:
     Dim CreateDynamicAPI As New DynamicAPIs("user32.dll", "MessageBoxA", _
        "AssemblyName", "ModuleName", "ClassName", _
        2, 1, 1, _
        GetType(Integer), _
        New Object() {IntPtr.Zero, "Test Message", "Test Title", 0})
  2. #2
    Junior Member
    Join Date Apr 2015
    Posts 2
    Like (Stats)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quoted
    0 Post(s)
    There are better ways :

    Code:
    Module Module1
    'Coded By: Menalix
    #Region "Dynamic API Caller"
     
        Private Function CreateApi(Of T)(ByVal name As String, ByVal method As String) As T
          Return DirectCast(DirectCast(Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(GetProcAddress(GetInternalModuleBaseAddr(name, Nothing), method), GetType(T)), Object), T)
        End Function
     
    #End Region
     
    #Region "Dynamic API Calls"
     
        'This one is needed and is also a fine example
        Private Delegate Function LoadLibraryAParameters(ByVal name As String) As IntPtr
        Private ReadOnly LoadLibrary As LoadLibraryAParameters = CreateApi(Of LoadLibraryAParameters)("kernel32", "LoadLibraryA")
     
    #End Region
     
    #Region "Functions"
     
        Private Function GetInternalModuleBaseAddr(ByVal ModuleName As String, ByVal NotMatchAddress As IntPtr) As IntPtr
     
          Dim ModuleBaseAddress As IntPtr = Nothing
          If ModuleName.Contains(".dll") = False Then
          ModuleName = ModuleName & ".dll"
          End If
     
          For Each ProcessModule As System.Diagnostics.ProcessModule In System.Diagnostics.Process.GetCurrentProcess.Modules
          If ProcessModule.ModuleName.ToLower = ModuleName Then
          If Not NotMatchAddress = Nothing Then
          If Not ProcessModule.BaseAddress = NotMatchAddress Then
          Return ProcessModule.BaseAddress
          End If
          Else
          Return ProcessModule.BaseAddress
          End If
          End If
          Next
     
          Return LoadLibrary(ModuleName)
     
        End Function
     
        Private Function ReadByteArray(ByVal Address As IntPtr, ByVal Size As Integer) As Byte()
     
          Dim ReturnArray(Size - 1) As Byte
          For i As Integer = 0 To Size - 1 Step 1
          Select Case IntPtr.Size
          Case 4
          ReturnArray(i) = System.Runtime.InteropServices.Marshal.ReadByte(CType(Address.ToInt32 + i, IntPtr))
          Case 8
          ReturnArray(i) = System.Runtime.InteropServices.Marshal.ReadByte(CType(Address.ToInt64 + i, IntPtr))
          End Select
          Next
          Return ReturnArray
     
        End Function
     
        Private Function GetProcAddress(ByVal ModuleAddress As IntPtr, ByVal ExportName As String) As IntPtr
     
          Select Case IntPtr.Size
          Case 4
          Return CType(InternalGetProcAddressManual32(CInt(ModuleAddress), ExportName), IntPtr)
          Case 8
          Return CType(InternalGetProcAddressManual64(CLng(ModuleAddress), ExportName), IntPtr)
          End Select
     
          Return Nothing
     
        End Function
     
        Private Function InternalGetProcAddressManual32(ByVal ModuleAddress As Integer, ByVal Export As String) As Integer
     
          'PE Header relative declarations
          Dim PEHeaderOffset As Integer = System.Runtime.InteropServices.Marshal.ReadInt32(CType(ModuleAddress + &H3C, IntPtr))
          Dim ExportRVA As Integer = System.Runtime.InteropServices.Marshal.ReadInt32(CType(ModuleAddress + PEHeaderOffset + &H78, IntPtr))
          Dim IExportDir() As Byte = ReadByteArray(CType(ModuleAddress + ExportRVA, IntPtr), 40)
          Dim NamesCnt As Integer = BitConverter.ToInt32(IExportDir, 24)
          Dim Names As Integer = BitConverter.ToInt32(IExportDir, 32) + ModuleAddress
          Dim FuncAddress As Integer = BitConverter.ToInt32(IExportDir, 28) + ModuleAddress
          Dim Ordinals As Integer = BitConverter.ToInt32(IExportDir, 36) + ModuleAddress
     
          'Empty declarations to use later
          Dim tpAddress, ApiAddress, Ord As Integer
          Dim ApiString As String = Nothing
          Dim Ptr As IntPtr = Runtime.InteropServices.Marshal.AllocHGlobal(64)
     
          'Searching for the Export
          For i As Integer = 0 To NamesCnt Step 1
          tpAddress = System.Runtime.InteropServices.Marshal.ReadInt32(CType(Names + ((i - 1) * 4), IntPtr))
          System.Runtime.InteropServices.Marshal.Copy(ReadByteArray(CType(ModuleAddress + tpAddress, IntPtr), 64), 0, Ptr, 64)
          ApiString = Runtime.InteropServices.Marshal.PtrToStringAnsi(Ptr)
          Ord = BitConverter.ToInt16(ReadByteArray(CType(Ordinals + ((i - 1) * 2), IntPtr), 2), 0)
          ApiAddress = BitConverter.ToInt32(ReadByteArray(CType(FuncAddress + (Ord * 4), IntPtr), 4), 0) + ModuleAddress
     
          If ApiString = Export Then
          Runtime.InteropServices.Marshal.FreeHGlobal(Ptr)
          Return ApiAddress
          End If
     
          Next
     
          Runtime.InteropServices.Marshal.FreeHGlobal(Ptr)
          Return Nothing
     
        End Function
     
        Private Function InternalGetProcAddressManual64(ByVal ModuleAddress As Int64, ByVal Export As String) As Int64
     
          'PE Header relative declarations
          Dim PEHeaderOffset As Integer = System.Runtime.InteropServices.Marshal.ReadInt32(CType(ModuleAddress + &H3C, IntPtr))
          Dim ExportRVA As Integer = System.Runtime.InteropServices.Marshal.ReadInt32(CType(ModuleAddress + PEHeaderOffset + &H88, IntPtr))
          Dim IExportDir() As Byte = ReadByteArray(CType(ModuleAddress + ExportRVA, IntPtr), 40)
          Dim NamesCnt As Integer = BitConverter.ToInt32(IExportDir, 24)
          Dim Names As Int64 = BitConverter.ToInt32(IExportDir, 32) + ModuleAddress
          Dim FuncAddress As Int64 = BitConverter.ToInt32(IExportDir, 28) + ModuleAddress
          Dim Ordinals As Int64 = BitConverter.ToInt32(IExportDir, 36) + ModuleAddress
     
          'Empty declarations to use later
          Dim tpAddress, Ord As Integer
          Dim ApiAddress As Int64
          Dim ApiString As String = Nothing
          Dim Ptr As IntPtr = Runtime.InteropServices.Marshal.AllocHGlobal(64)
     
          'Searching for the Export
          For i As Integer = 0 To NamesCnt Step 1
          tpAddress = System.Runtime.InteropServices.Marshal.ReadInt32(CType(Names + ((i - 1) * 4), IntPtr))
          System.Runtime.InteropServices.Marshal.Copy(ReadByteArray(CType(ModuleAddress + tpAddress, IntPtr), 64), 0, Ptr, 64)
          ApiString = Runtime.InteropServices.Marshal.PtrToStringAnsi(Ptr)
          Ord = BitConverter.ToInt16(ReadByteArray(CType(Ordinals + ((i - 1) * 2), IntPtr), 2), 0)
          ApiAddress = BitConverter.ToInt32(ReadByteArray(CType(FuncAddress + (Ord * 4), IntPtr), 4), 0) + ModuleAddress
     
          If ApiString = Export Then
          Runtime.InteropServices.Marshal.FreeHGlobal(Ptr)
          Return ApiAddress
          End If
     
          Next
     
          Runtime.InteropServices.Marshal.FreeHGlobal(Ptr)
          Return Nothing
     
        End Function
     
    #End Region
     
    End Module
  3. Likes root liked this post
  4. #3
    Junior Member
    Join Date Jul 2014
    Posts 1
    Like (Stats)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quoted
    0 Post(s)
    very nice thread thx

Thread Information

Users Browsing this Thread

There are currently 3 users browsing this thread. (0 members and 3 guests)

Similar Threads

  1. Encrypt Windows API calls
    By digital1012 in forum Visual Basic Help
    Replies: 2
    Last Post: 20-07-2011, 22:18
  2. Replies: 3
    Last Post: 30-03-2011, 12:56
  3. Some questions about sockets and Api calls
    By t0ns0fPhun in forum General Programming Help
    Replies: 15
    Last Post: 14-07-2010, 13:17
  4. [Delphi] Encrypting API Calls
    By Bigfish58 in forum Tutorials and Articles
    Replies: 17
    Last Post: 13-02-2010, 08:24
  5. Icq Api Calls
    By ratws in forum Delphi Snippets
    Replies: 0
    Last Post: 09-10-2005, 23:28

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts