Operation Code problem

New to FreeBASIC? Post your questions here.
Post Reply
Löwenherz
Posts: 235
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Operation Code problem

Post by Löwenherz »

hello.. I have a little Problem to get right Output for this Operation opcodestring example..
Produces instead a dll very Strange
Its an old example

Code: Select all

' test example and compiling ok, but without output result 1 and 42
' produces instead of it a 26 kb dll ;)
'
union opcodestring
s as byte ptr
f as function () as Long
' ------------- problem -------------------- // original Code next line
'f1 as function (ByVal long) as Long ' -> f1 as function (byval long) as long ' doesnt work
' ------------- problem -------------------- //
f1 as function (ByVal p As long) as Long ' go but without output result 1 and 42
end union

dim as string st,st1
dim as opcodestring act,act1

' clear the eax register, increment it  and return
st=chr(&h33)+chr(&hc0)+chr(&h40)+Chr(&hc3)  ' xor eax,eax inc eax ret

' extract the parameter from the stack into eax and return
st1=Chr(&h5a)+chr(&h58)+chr(&h52)+chr(&hc3) ' pop edx pop eax push edx ret

act.s=strptr(st): act1.s=strptr(st1)  ' set string pointers

' Test the strings
Print act.f()    ' answer 1
print act1.f1(42) ' answer 42

Sleep
srvaldez
Posts: 3559
Joined: Sep 25, 2005 21:54

Re: Operation Code problem

Post by srvaldez »

hello Löwenherz
why would you want to do such dirty programming anyway ?
Löwenherz
Posts: 235
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Operation Code problem

Post by Löwenherz »

hello Löwenherz
why would you want to do such dirty programming anyway ?
freebasic old example 2006 or 2007
' topic: calling opcode strings
'
Hello srvaldez...

1) This technique can be used in scripting languages to compile on-the-fly instead of
interpreting rext or byte code. This is especially useful for speeding up repetitive blocks of code.
It opens up all kinds of possibilities for high level language development, resolving the conflict between speed and flexibility.

2) You can execute opcodes from anywhere as long as there are no address dependencies
in the code itself. Since most x86 calls and jumps are 'relative' and variables are stack based or indexed from a register, this is very easy to do.

3) This shows how to call strings of x86 machine code. It shows how the EAX register is used to
return integer results and how to extract a parameter from the stack, replacing the return address. This assumes the SDECL calling protocol where the called function cleans the stack of any parameters before returning to the caller.

-> for example: This approach can be used for dynamic assembly or compilation during run time.

regards, loewenherz
srvaldez
Posts: 3559
Joined: Sep 25, 2005 21:54

Re: Operation Code problem

Post by srvaldez »

I don't think that this type of code will work in a modern OS without some means of marking the memory in the strings as executable
I don't approve/like this kind of coding, it's a recipe for malicious code 😒
Löwenherz
Posts: 235
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Operation Code problem

Post by Löwenherz »

I have Made a running Code example for Powerbasic too and all is working Well with some Translation Changes. In my eyes thats Not a Malicious Code but stuff for learning Things about programming language.. I dont agree with you.
srvaldez
Posts: 3559
Joined: Sep 25, 2005 21:54

Re: Operation Code problem

Post by srvaldez »

Löwenherz
I stick to my opinion, it's dirty programming
something just a little bit more acceptable in my opinion would be to use the FasmDLL https://board.flatassembler.net/topic.php?t=6239
years ago I made a test, 32-bit only

you will need to change the path of the FasmDLL in line 179 to wherever you placed it

Code: Select all

#Include "Windows.Bi"
#Include "Crt.Bi"

' the following structure resides at the beginning of memory block provided
' to the fasm_assemble function. the condition field contains the same value
' as the one returned by function.
'   when function returns fasm_ok condition, the output_length and
' output_data fields are filled - with pointer to generated output
' (somewhere within the provided memory block) and the count of bytes stored
' there.
'   when function returns fasm_error, the error_code is filled with the
' code of specific error that happened and error_line is a pointer to the
' line_header structure, providing information about the line that caused
' the error.

Type Fasm_State
  As Integer Condition
  Union
    As Integer Output_Length
    As Integer Error_Code
  End Union
  Union
    As Any Ptr Output_Data
    As Any Ptr Error_Line
  End Union
End Type

' the following structure has two variants - it either defines the line
' that was loaded directly from source, or the line that was generated by
' macroinstruction. first case has the highest bit of line_number set to 0,
' while the second case has this bit set.
'   in the first case, the file_path field contains pointer to the path of
' source file (empty string if it's the source that was provided directly to
' fasm_assemble function), the line_number is the number of line within
' that file (starting from 1) and the file_offset field contains the offset
' within the file where the line starts.
'   in the second case the macro_calling_line field contains the pointer to
' line_header structure for the line which called the macroinstruction, and
' the macro_line field contains the pointer to line_header structure for the
' line within the definition of macroinstruction, which generated this one.

Type Line_Header
  As Integer File_Path
  As Integer Line_Number
  Union
    As Integer File_Offset
    As Integer Macro_Calling_Line
  End Union
  As Integer Macro_Line
End Type

' General Errors And Conditions
Function Fasm_Error(Byval Error_Code As Integer) As String
    Select Case Error_Code
        Case 0
            Return "Fasm Ok"
        Case 1
            Return "Fasm Working"
        Case 2
            Return "Fasm Error"
        Case -1
            Return "Fasm Invalid Parameter"
        Case -2
            Return "Fasm Out Of Memory"
        Case -3
            Return "Fasm Stack Overflow"
        Case -4
            Return "Fasm Source Not Found"
        Case -5
            Return "Fasm Unexpected End Of Source"
        Case -6
            Return "Fasm Cannot Generate Code"
        Case -7
            Return "Fasm Format Limitations Excedded"
        Case -8
            Return "Fasm Write Failed"

' Error Codes For Fasm Error Condition
        Case -101
            Return "Fasm error: File Not Found"
        Case -102
            Return "Fasm error: Error Reading File"
        Case -103
            Return "Fasm error: Invalid File Format"
        Case -104
            Return "Fasm error: Invalid Macro Arguments"
        Case -105
            Return "Fasm error: Incomplete Macro"
        Case -106
            Return "Fasm error: Unexpected Characters"
        Case -107
            Return "Fasm error: Invalid Argument"
        Case -108
            Return "Fasm error: Illegal Instruction"
        Case -109
            Return "Fasm error: Invalid Operand"
        Case -110
            Return "Fasm error: Invalid Operand Size"
        Case -111
            Return "Fasm error: Operand Size Not Specified"
        Case -112
            Return "Fasm error: Operand Sizes Do Not Match"
        Case -113
            Return "Fasm error: Invalid Address Size"
        Case -114
            Return "Fasm error: Address Sizes Do Not Agree"
        Case -115
            Return "Fasm error: Disallowed Combination Of Registers"
        Case -116
            Return "Fasm error: Long Immediate Not Encodable"
        Case -117
            Return "Fasm error: Relative Jump Out Of Range"
        Case -118
            Return "Fasm error: Invalid Expression"
        Case -119
            Return "Fasm error: Invalid Address"
        Case -120
            Return "Fasm error: Invalid Value"
        Case -121
            Return "Fasm error: Value Out Of Range"
        Case -122
            Return "Fasm error: Undefined Symbol"
        Case -123
            Return "Fasm error: Invalid Use Of Symbol"
        Case -124
            Return "Fasm error: Name Too Long"
        Case -125
            Return "Fasm error: Invalid Name"
        Case -126
            Return "Fasm error: Reserved Word Used As Symbol"
        Case -127
            Return "Fasm error: Symbol Already Defined"
        Case -128
            Return "Fasm error: Missing End Quote"
        Case -129
            Return "Fasm error: Missing End Directive"
        Case -130
            Return "Fasm error: Unexpected Instruction"
        Case -131
            Return "Fasm error: Extra Characters On Line"
        Case -132
            Return "Fasm error: Section Not Aligned Enough"
        Case -133
            Return "Fasm error: Setting Already Specified"
        Case -134
            Return "Fasm error: Data Already Defined"
        Case -135
            Return "Fasm error: Too Many Repeats"
        Case -136
            Return "Fasm error: Symbol Out Of Scope"
        Case -140
            Return "Fasm error: User Error"
        Case -141
            Return "Fasm error: Assertion Failed"
    End Select
End Function

#Define Lf Chr(10)
#Define Cr Chr(13)

Dim Fasm_Getversion As Function   Stdcall () As Integer
Dim Fasm_Assemble   As Function   Stdcall _
                                                  (Byval Lpsource As Any Ptr, _
                                                   Byval Lpmemory As Any Ptr, _
                                                   Byval Cbmemorysize As Integer, _
                                                   Byval Npasslimit As Integer, _
                                                   Byval Hdisplaypipe As Any Ptr ) As Integer

Dim Fasm_Assemblefile As Function Stdcall _
                                                  (Byval Lpsourcefile As Any Ptr, _
                                                   Byval Lpmemory As Any Ptr, _
                                                   Byval Cbmemorysize As Integer, _
                                                   Byval Npasslimit As Integer, _
                                                   Byval Hdisplaypipe As Any Ptr ) As Integer

Dim As Any Ptr Library

'Library = Dylibload("F:\FreeBASIC Programs\fasmDLL\DEMO\FASM" )
Library = Dylibload("D:\MyDocuments\FreeBASIC Programs\fasmDLL\DEMO\FASM.DLL" )
If( Library = 0 ) Then
    Print "Cannot Load The Fasm Dynamic Library, Aborting Program..."
    Print "Press Return To End ";
    Sleep
Else
    Fasm_Getversion = Dylibsymbol( Library, "fasm_GetVersion")
    If Fasm_Getversion = 0 Then
      Print "Cannot Get Fasm_Getversion Function Address From Fasm Library, Aborting Program..."
        Print "Press Return To End ";
        Sleep
      End 1
   End If
    Fasm_Assemble = Dylibsymbol( Library, "fasm_Assemble")
    If Fasm_Assemble = 0 Then
      Print "Cannot Get Fasm_Assemble Function Address From Fasm Library, Aborting Program..."
        Print "Press Return To End ";
        Sleep
      End 1
   End If
    Fasm_Assemblefile = Dylibsymbol( Library, "fasm_AssembleFile")
    If Fasm_Assemblefile = 0 Then
      Print "Cannot Get Fasm_Assemblefile Function Address From Fasm Library, Aborting Program..."
        Print "Press Return To End ";
        Sleep
      End 1
   End If
End If

Dim Asm_Source As Zstring Ptr = Allocate(1024)
Dim Buffer As Fasm_State Ptr = Allocate(8388608)
Dim Line_Error As Line_Header Ptr
Dim Machine_Code As Any Ptr
Dim As Integer Result
Dim As Integer I

Dim Myfunction As Function Cdecl() As Integer

*Asm_Source="use32"+Lf
*Asm_Source+="Org 100H"+Lf
*Asm_Source+=Lf
*Asm_Source+="Mov Eax,100"+Lf
*Asm_Source+="Add Eax,20"+Lf
*Asm_Source+="Ret"+Lf      'Of Myfunction Is Changed To Double Then It Returns Pi

Result=Fasm_Assemble(Asm_Source, Buffer,8388608,100,0)

Print "Buffer->Condition = ";Buffer->Condition
If Buffer->Condition=0 Then
    Print "Buffer->Output_Length = ";Buffer->Output_Length

	If Result=0 Then
		Machine_Code=Virtualalloc(Null, Buffer->Output_Length, Mem_Commit, Page_Execute_Readwrite)
		?"Machine_Code = ";Machine_Code
		Memcpy(Machine_Code, Buffer->Output_Data, Buffer->Output_Length)
		For I=0 To Buffer->Output_Length-1
			'Poke ubyte,(Machine_Code+I),peek(ubyte,@Buffer->Output_Data+i)
			Print hex(peek(ubyte,Buffer->Output_Data+i),2)
		Next
		Print
		Print "Asm Source"
		Print *Asm_Source
		Print "Machine Code ";
		For I=0 To Buffer->Output_Length-1
			Print Hex(Peek(Ubyte,Machine_Code+I),2);" ";
		Next
		Print
		Print
		Myfunction=Machine_Code
		Print "Result Of Myfunction = ";
		Print Myfunction() 
	End If

ElseIf Buffer->Condition=2 Then
	Line_Error=Buffer->Error_Line
	Print Fasm_Error(Buffer->Error_Code);" In Line ";Line_Error->Line_Number
End If
/'
'Another Way Of Calling The Asm Code
I=0
If Buffer->Condition=0 Then
    Asm
        Call [Machine_Code]
        Mov [I],Eax
    End Asm
End If
Print "Result From Calling Machine Code = ";I
'/
Deallocate(Buffer)
Deallocate(Asm_Source)
Virtualfree(Machine_Code,0,Mem_Release)
Dylibfree(Library)
Print "Press Return To End ";
Sleep
output
Buffer->Condition = 0
Buffer->Output_Length = 9
Machine_Code = 83165184
B8
64
00
00
00
83
C0
14
C3

Asm Source
use32
Org 100H

Mov Eax,100
Add Eax,20
Ret

Machine Code B8 64 00 00 00 83 C0 14 C3

Result Of Myfunction = 120
Press Return To End
Löwenherz
Posts: 235
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Operation Code problem

Post by Löwenherz »

Thanks for your example srvaldez but I havent checked yet.. coming Back Just from Work ...

But I think I can fix myself my example First part IS going correct with ... Ulong

Code: Select all

' test example and compiling ok
' part two, half of result is going well ;)
'
union opcodestring
s as byte ptr
f as function () as Long
f1 as function (Byref p As ulong) as uLong ' my idea
'f1 as function (ByVal long) as Long ' original code from 2007
end union

dim as string st,st1
dim as opcodestring act,act1

Print "Hello"

' clear the eax register, increment it  and return
st=chr(&h33)+chr(&hc0)+chr(&h40)+Chr(&hc3)  ' xor eax,eax inc eax ret

' extract the parameter from the stack into eax and return
st1=Chr(&h5a)+chr(&h58)+chr(&h52)+chr(&hc3) ' pop edx pop eax push edx ret

Print "Hello2"

act.s=strptr(st): act1.s=strptr(st1)  ' set string pointers

' Test the strings
Print act.f()    ' answer 1 ok
'print act1.f1(42) ' answer 42
Print "ok ends"
Sleep
I can remember this example Works correct in 2007 or 2008 when I was learning First time freebasic and was making some Tests with hex values and Assembler Code..
Löwenherz
Posts: 235
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: (solved) operation Code problem

Post by Löwenherz »

OK Here is my solution AS wished :-)
The Trick was ulong .. F1 AS function (byval p AS ulong) AS ulong

Code: Select all

' test example and compiling ok
' part three all is running fine 
'
union opcodestring
s as byte ptr
f as function () as Long
f1 as function (Byval p As ULong) as uLong ' my idea
'f1 as function (ByVal long) as Long ' original code from 2007
end union

dim as string st,st1
dim as opcodestring act,act1

Print "Hello"

' clear the eax register, increment it  and return
st=chr(&h33)+chr(&hc0)+chr(&h40)+Chr(&hc3)  ' xor eax,eax inc eax ret

' extract the parameter from the stack into eax and return
st1=Chr(&h5a)+chr(&h58)+chr(&h52)+chr(&hc3) ' pop edx pop eax push edx ret

Print "Hello2"

act.s=strptr(st): act1.s=strptr(st1)  ' set string pointers

' Test the strings
Print act.f()    ' answer 1 ok
print act1.f1(42) ' answer 42 ok
Print "ok ends"
Sleep
Post Reply