Simple method to extract binary executable data with Poasm. The procedure WriteFileToDisc saves the code between the two labels, MsgBox and start. This method is useful to call assembly code from languages like RapidQ Basic with no inline assembly support.
.386
.model flat,stdcall
option casemap:none
ExitProcess PROTO :DWORD
WriteFileToDisc PROTO :DWORD,:DWORD,:DWORD
.data
fname db 'MsgBox.bin',0
.code
MsgBox:
call delta
delta:
pop edx
mov eax,OFFSET delta
sub edx,eax
lea eax,[edx+capt]
lea ecx,[edx+msg]
; call MessageBox
push 0
push eax
push ecx
push 0
call DWORD PTR [esp+20]
retn 16
capt db 'Hello',0
msg db 'This is a test.',0
start:
ProcLen EQU start-MsgBox
invoke WriteFileToDisc,ADDR fname,\
MsgBox,ProcLen
invoke ExitProcess,0
END start
Running the executable, it creates the file MsgBox.bin
RapidQ Basic code calling the embedded binary data :
$APPTYPE GUI
DIM s AS STRING
DIM pMessageBox as INTEGER
DECLARE FUNCTION CallWindowProc LIB "user32" ALIAS "CallWindowProcA" _
(Proc AS LONG, p1 AS LONG, p2 AS LONG, p3 AS LONG, _
p4 AS LONG) AS LONG
DECLARE FUNCTION GetProcAddress LIB "kernel32" ALIAS "GetProcAddress" (hModule AS LONG, lpProcName AS STRING) AS LONG
DECLARE FUNCTION LoadLibrary LIB "kernel32" ALIAS "LoadLibraryA" (lpFileName AS STRING) AS LONG
DefInt ptrMsgBox
FUNCTION MsgBox1(pointer As Long) As Long
Result=CallWindowProc(ptrMsgBox,pointer,0,0,0)
END FUNCTION
$RESOURCE ResourceName AS "MsgBox.bin"
DIM Mem AS QMEMORYSTREAM
Mem.ExtractRes(Resource(0))
Mem.Position=0
s=Mem.ReadBinStr(Mem.Size)
ptrMsgBox=varptr(s)
pMessageBox = GetProcAddress(LoadLibrary("user32.dll"), "MessageBoxA")
MsgBox1(pMessageBox)
Compiling the RapidQ code :
RC.EXE -LC:\Rapidq\lib MBox.bas