Author Topic: Calling an asmc module from Rapid-Q  (Read 310 times)

Vortex

  • Member
  • *****
  • Posts: 1712
Calling an asmc module from Rapid-Q
« on: April 19, 2017, 04:56:21 AM »
Some Basic language dialects does not support object modules and this makes difficult incorporating them with assembly code. A method to solve this problem is to use the CallWindowProc API :

Code: [Select]
LRESULT WINAPI CallWindowProc(
  _In_ WNDPROC lpPrevWndFunc,
  _In_ HWND    hWnd,
  _In_ UINT    Msg,
  _In_ WPARAM  wParam,
  _In_ LPARAM  lParam
);

The lpPrevWndFunc parameters points the procedure to call and the other three ones can be optional for our purpose.

Code: [Select]
.386
.model flat,stdcall
option casemap:none

include     CallBinaryCode.inc

.data

kernel32    db 'kernel32.dll',0
GetProcAdr  db 'GetProcAddress',0
msg         db 'This is a test application.',0

.code

start:

    invoke  GetModuleHandle,ADDR kernel32
    push    eax

    invoke  GetProcAddress,eax,ADDR GetProcAdr
    pop     edx

    invoke  CallWindowProc,ADDR testfunc,eax,edx,\
            ADDR msg,0

    invoke  ExitProcess,0

testfunc PROC GetProcAddr:DWORD,hKernel32:DWORD,message:DWORD,lParam:DWORD

LOCAL  _LoadLibrary:DWORD
LOCAL   hDll:DWORD
LOCAL  _FreeLibrary:DWORD
LOCAL   msvcrt:DWORD
LOCAL   printf:DWORD
LOCAL   LoadLib:DWORD
LOCAL   FreeLib:DWORD

;   Copy the NULL terminated strings to the stack

    mov     msvcrt,@StrToStack(msvcrt.dll)
    mov     printf,@StrToStack(printf)
    mov     LoadLib,@StrToStack(LoadLibraryA)
    mov     FreeLib,@StrToStack(FreeLibrary)

   _invoke  GetProcAddr,hKernel32,FreeLib
    mov    _FreeLibrary,eax

   _invoke  GetProcAddr,hKernel32,LoadLib
    mov    _LoadLibrary,eax

   _invoke  eax,msvcrt
    mov     hDll,eax

   _invoke  GetProcAddr,eax,printf

   _invoke  eax,message
    add     esp,4       ; Balance the stack after
                        ; calling printf

   _invoke _FreeLibrary,hDll

    ret

testfunc ENDP

END start

testfunc can be assembled as a binary module with the /bin option of asmc. This binary output must be converted to a sequence of bytes to be inserted to the Basic source code.

Code: [Select]
Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Declare Function GetProcAddress Lib "kernel32" Alias "GetProcAddress" (ByVal hModule As Long, ByVal lpProcName As String) As Long

Declare Function CallAsmProc LIB "user32" ALIAS "CallWindowProcA" _
      (Func As Long, p1 As Long, p2 As Long, ByVal p3 as string, _
                  p4 As Long) As Long

DefByte testfunc (0 To 131) = _
{85,139,236,131,236,28,104,108,108,0,0,104,114,116,46,100, _
104,109,115,118,99,137,101,240,104,116,102,0,0,104,112,114, _
105,110,137,101,236,106,0,104,97,114,121,65,104,76,105,98, _
114,104,76,111,97,100,137,101,232,104,97,114,121,0,104,76, _
105,98,114,104,70,114,101,101,137,101,228,255,117,228,255,117, _
12,255,85,8,137,69,244,255,117,232,255,117,12,255,85,8, _
137,69,252,255,117,240,255,208,137,69,248,255,117,236,80,255, _
85,8,255,117,16,255,208,131,196,4,255,117,248,255,85,244, _
201,194,16,0}

Defstr mystring = "This is a test."

hKernel32=GetModuleHandle("kernel32.dll")

testfuncPtr = VarPtr (testfunc(0))

CallAsmProc(testfuncptr,GetProcAddress(hKernel32,"GetProcAddress"),hKernel32,mystring,0)