Jump to content

Recommended Posts

Posted (edited)

This UDF is similar to my previous Inline Assembly UDF, but only better. Because this one uses flat assembler, a open source and powerful assembler. See http://flatassembler.net/. Thanks to XDa from http://www.opensc.ws/ provide a "fasm.dll". So my job is just easy, warp it using my MemoryDll UDF.

 

The usage is also similar to previously, but a kind of different. FasmGetFuncPtr() will compile the source and return the address ready to be call. And FasmGetBasePtr() only return the base address without compiling and error handling. FasmGetBasePtr() is added for "org" directive.

 

Have fun. Maybe also take a look at AndyG's Fractals script.

 

FASM.zip (55.47K)

Number of downloads: 127

 

2010/03/19 Update Note:

# Embedded FASM version update to v1.68

# Add OOP version using AutoItObject, thanks to AutoItObject-Team

# New examples

# Better error handling, can handle errors in macro now

FASM.zip (141.76K)

Number of downloads: 601

 

2011/06/14 Update Note:

# Embedded FASM version update to v1.69

# AutoItObject UDF version update to v1.2.8.0

# MemoryDLL UDF update to X64 supported version

# New BinaryCall UDF to run a machine code in "Binary" format

# Add FASMServer and FASMServerDemo, demonstrate embedded assembly in AutoIt X64

# Add fast BinaryXOR function (Both X86/X64) as an example (in FASMServerDemo2)

FASM.zip

Edited by Ward

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Posted

Thanks a lot for this sharing this ward. Great little examples too. Very helpful. 5*. :(

Posted

Do you know if there is a way I can pass parameters to the autoit functions?

Posted

  On 3/16/2010 at 5:51 PM, 'Beege said:

Do you know if there is a way I can pass parameters to the autoit functions?

Check out DllCallbackRegister.

Broken link? PM me and I'll send you the file!

Posted

  On 3/16/2010 at 5:51 PM, 'Beege said:

Do you know if there is a way I can pass parameters to the autoit functions?

It is easy:

#include "FASM.au3"
Dim $Fasm = FasmInit()
Demo7()

Func Demo7()
    ; Demo 7: Call AutoIt Func From Assembly And Pass Parameters
    $AutoItFunc = DllCallbackRegister("AutoItFunc2", "int", "str;uint;uint")
    FasmReset($Fasm)
    FasmAdd($Fasm, "use32") 
    FasmAdd($Fasm, "org " & FasmGetBasePtr($Fasm))
    FasmAdd($Fasm, "rdtsc")
    FasmAdd($Fasm, "push eax")
    FasmAdd($Fasm, "push edx")
    FasmAdd($Fasm, "push s1")
    FasmAdd($Fasm, "call " & DllCallbackGetPtr($AutoItFunc))
    FasmAdd($Fasm, "ret")
    FasmAdd($Fasm, "s1: db 'RDTSC = %08X%08X', 0")
    ConsoleWrite(String(FasmGetBinary($Fasm)) & @CRLF)
    $Ret = MemoryFuncCall("int", FasmGetFuncPtr($Fasm))
    DllCallbackFree($AutoItFunc)
EndFunc

Func AutoItFunc2($String, $Edx, $Eax)
    MsgBox(0, "AutoItFunc", StringFormat($String, $Edx, $Eax))
EndFunc

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Posted (edited)

Thanks ward. That helped a lot. :(

But now I'm confused on why the data in s1 gets set after the 'ret'. I figured it would be the other way around.

FasmAdd($Fasm, "s1: db 'RDTSC = %08X%08X', 0")
FasmAdd($Fasm, "ret")

Anyway, just another item on the list of "things to read and learn about." Thanks again.

Edited by Beege
Posted

Excellent job again Ward.

Out of curiosity, since FASM supports x64 code ('use64'), what would you say the chances are of someday compiling & integrating a 64-bit DLL. I'm getting well versed in x64 code so I'd be able to provide 64-bit versions of the Examples for ya.

Thanks again for all your work

Ascend4nt

My contributions:

  Reveal hidden contents

Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFsProcess CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen)Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery

Wrappers/Modifications of others' contributions:

_DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity)

UDF's added support/programming to:

_ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne)

(All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)

  • 1 year later...
Posted

This UDF is updated to support AutoIt X86/X64.

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

  • 1 year later...
Posted (edited)

I like this UDF. It generates very fast and compact code. To see some working examples where it's used to optimize loops and fix x64 issues take a look at this example. See section 1.6 and 1.7. If you have downloaded the examples and want to take a closer look at one of the optimizations go to "OpenGL 1.1TexturesTunnelsutilitiesfasm". I have left the test files (with -a and -b in the names) to optimize loops in "Tunnel effect 2.au3".

When I write assembler source I like to write it in a format like shown in the code boxes.

This is an example with MessageBoxA:

; FASM assembler code

        ; MessageBoxA( hWnd, lpText, lpCaption, uType )

        ; $tData = DllStructCreate( "byte[80];byte[16];handle;ptr[3]" )
        ; Element 3, index 1, offset  96 ( 96) : handle hWnd
        ; Element 4, index 1, offset 100 (104) : ptr    lpText
        ; Element 4, index 2, offset 104 (112) : ptr    lpCaption
        ; Element 4, index 3, offset 108 (120) : ptr    MessageBoxA
        ; (Numbers in brackets are x64 offsets)

        ; Parameters:
        ; [ebp + 08] : uType
        ; [ebp + 12] : $pData

        use32
        push       ebp
        mov        ebp,                esp

        mov        eax,                [ebp + 12]          ; eax is pointer in $tData table

        ; Call MessageBoxA
        ;pusha                                              ; Save registers on stack
        push       dword [ebp +  08]                       ; 4. parameter: uType
        push       dword [eax + 104]                       ; 3. parameter: lpCaption
        push       dword [eax + 100]                       ; 2. parameter: lpText
        push       dword [eax +  96]                       ; 1. parameter: hWnd
        call       dword [eax + 108]                       ; Call MessageBoxA
        ;popa                                               ; Restore registers

        pop        ebp
        ret        08
And the x64 code:

; FASM assembler code

        ; MessageBoxA( hWnd, lpText, lpCaption, uType )

        ; $tData = DllStructCreate( "byte[80];byte[16];handle;ptr[3]" )
        ; Element 3, index 1, offset  96 ( 96) : handle hWnd
        ; Element 4, index 1, offset 100 (104) : ptr    lpText
        ; Element 4, index 2, offset 104 (112) : ptr    lpCaption
        ; Element 4, index 3, offset 108 (120) : ptr    MessageBoxA
        ; (Numbers in brackets are x64 offsets)

        ; Parameters:
        ; rcx : uType
        ; rdx : $pData

        ; x64 function calling convention for parameter passing:
        ; First  parameter: int/ptr -> rcx,  float -> xmm0
        ; Second parameter: int/ptr -> rdx,  float -> xmm1
        ; Third  parameter: int/ptr -> r8,   float -> xmm2
        ; Fourth parameter: int/ptr -> r9,   float -> xmm3
        ; The rest goes onto the stack

        use64

        mov        rax,                rdx                 ; rax is pointer in $tData table

        ; Call MessageBoxA
        sub        rsp,                40                  ; Stack space and alignment
        mov        r9,                 rcx                 ; 4. parameter: uType
        mov        rcx,                qword [rax +  96]   ; 1. parameter: hWnd
        mov        rdx,                qword [rax + 104]   ; 2. parameter: lpText
        mov        r8,                 qword [rax + 112]   ; 3. parameter: lpCaption
        call       qword [rax + 120]                       ; Call MessageBoxA
        add        rsp,                40                  ; Restore stack pointer

        ret
Note that FASM.au3 cannot be run as a 64 bit program. But it certainly can generate 64 bit code. To generate the binary code run MessageBoxA-x64-mk-bin.au3.

This is the AutoIt program to call the assembler functions:

#include "Includes\Utilities.au3"

Opt( "MustDeclareVars", 1 )

Global $hGui = GUICreate( "MessageBoxA demo with FASM", 400, 300 )

Global $pCode, $pData, $tData

GetFasmCode()
GUISetState()
MessageBoxA1()
MessageBoxA2()

Func GetFasmCode()

    ; --- Fasm data ---

    ; MessageBoxA( hWnd, lpText, lpCaption, uType )

    ; Use a struct to pass data from AutoIt to the assembler function. uType will be passed as a parameter.

    $tData = DllStructCreate( "byte[80];byte[16];handle;ptr[3]" )
    ; To make things easier add extra space in tables in the structure until they are 8-bytes aligned. It's also 
    ; nice to have a little bit of extra space. Then you can use this space for an intermediate result, if that
    ; should be necessary. Without the need to change all the offsets. It seems also to be easier to put the
    ; x86/x64 dependant data e.g. handle and ptr in the end of the structure.

    DllStructSetData( $tData, 3, $hGui )                           ; Element 3, index 1, offset  96 ( 96) : handle hWnd
    DllStructSetData( $tData, 4, DllStructGetPtr( $tData, 1 ), 1 ) ; Element 4, index 1, offset 100 (104) : ptr    lpText
    DllStructSetData( $tData, 4, DllStructGetPtr( $tData, 2 ), 2 ) ; Element 5, index 2, offset 104 (112) : ptr    lpCaption
    Local $ptr = GetProcAddress( "user32.dll", "MessageBoxA" )
    DllStructSetData( $tData, 4, $ptr, 3 )                         ; Element 4, index 3, offset 108 (120) : ptr    MessageBoxA
                                                                   ; (Numbers in brackets are x64 offsets)
    $pData = DllStructGetPtr( $tData )

    ; --- Fasm code ---

    Local $sCode, $tCode

    If @AutoItX64 Then
        If Not ReadX64code( "MessageBoxA-x64.bin", "MessageBoxA-x64-mk-bin.au3", $sCode ) Then Exit
    Else
        Local $oFasm = FasmInit()
        If Not ReadFasmCode( "MessageBoxA.asm", $oFasm, $sCode ) Then Exit
        FasmExit( $oFasm )
    EndIf
    $pCode = _MemVirtualAlloc( 0, 128, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE )
    $tCode = DllStructCreate( "byte[128]", $pCode )
    DllStructSetData( $tCode, 1, $sCode )

EndFunc

Func MessageBoxA1()

    SetTextCaption( "This is the first test.", "Test 1" )

    DllCallAddress( "none", $pCode, "uint", 0, "ptr", $pData )

EndFunc

Func MessageBoxA2()

    SetTextCaption( "This is the second test.", "Test 2" )

    Local $aRet = DllCallAddress( "int", $pCode, "uint", 33, "ptr", $pData ), $sText
    If $aRet[0] = 1 Then                               ; 33 = OK + Cancel + Question-mark icon
        $sText = "OK button."
    Else
        $sText = "Cancel button (or close)."
    EndIf
    SetTextCaption( $sText, "Clicked" )
    DllCallAddress( "none", $pCode, "uint", 0, "ptr", $pData )

EndFunc

Func SetTextCaption( $sText, $sCaption )
    ; MessageBoxA( hWnd, lpText, lpCaption, uType )
    ; $tData = DllStructCreate( "byte[80];byte[16];uint[2];handle;ptr[3]" )
    DllStructSetData( $tData, 1, $sText )                          ; Element 1, index 1, offset   0       : byte   $sText
    DllStructSetData( $tData, 1, 0, StringLen( $sText ) + 1 )      ; Null-terminated string
    DllStructSetData( $tData, 2, $sCaption )                       ; Element 2, index 1, offset  80       : byte   $sCaption
    DllStructSetData( $tData, 2, 0, StringLen( $sCaption ) + 1 )   ; Null-terminated string
EndFunc
You find the utility functions GetProcAddress, ReadFasmCode, MakeX64code, ReadX64code and the MessageBoxA files here:

MessageBoxA.7z

Copy BinaryCall.au3, FASM.au3 and MemoryDll.au3 from Ward's UDF to the Includes folder when you extract the 7z-file.

Links

flat assembler

Programmer's Manual

Intel® 64 and IA-32 Architectures Software Developer Manuals

Introduction to 64 Bit Intel Assembly Language

x64 Software Conventions

The Art of Assembly Language

Edited by LarsJ
  • 2 years later...
Posted (edited)
Posted
  On 12/8/2015 at 7:27 AM, LarsJ said:

I found FASM.zip on my old XP. Downloaded october 2012.

FASM.zip

File is corrupted ?

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

  • 3 months later...
  • 1 year later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...