flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > fasm as DLL

Goto page Previous  1, 2, 3, 4, 5, 6  Next
Author
Thread Post new topic Reply to topic
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 21 Aug 2018, 20:15
sesey wrote:
How can I compile this source code as x64.dll?
This is a bit complex, it requires the same macros as Linux x64 version and rewrite of OS abstraction layer, I may take a look at this in the future.
Post 21 Aug 2018, 20:15
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 21 Aug 2018, 20:51
ProMiNick wrote:
But internal variable __FILE__ without value can produce bugs in virtual blocks (when they are as additional files).
Do not worry, the engine has it all figured out, you just need to be careful to use its functions properly (I did my best to well-document their interfaces).

As a quick demonstration I made a simplest DLL version of fasmg. It just exposes the main interfaces of engine (and uses hard-coded values for most of the settings). It operates on local variables, so should be thread-safe.

The attached files have to be in the source/windows/dll directory in fasmg source tree to assemble correctly. It can only be self-hosted with fasmg. Note that selfhost.inc has additional macros to convert MOV to LEA when EBP-relative addresses need to be put into a register.

The main function is:
fasmg_Assemble(source_string, source_path, reserved, output_path, stdout, stderr)
All arguments are optional, every one of them is allowed to be NULL.
  • source_string is the text to be assembled directly from memory. Normal versions of fasmg use this for the instructions added from command line with -I switch, but this can just as well be used to assemble complete source not stored in any file.
  • source_path is the path to source file. If both in-memory source and source file are provided, their concatenation is assembled.
  • reserved for a parameter that might be used to receive output in memory. Currently not implemented.
  • output_path is the path to file for the output. When not provided, the output path is generated from the input path (just like the command-line fasmg does it). When there is neither path provided, output is not written anywhere.
  • stdout should be a handle to file or pipe that receives the messages generated with DISPLAY command.
  • stderr should be a handle to file or pipe that receives the error messages.

Function returns the number of errors encountered in the assembly, so 0 indicates success. When there were errors, details have been written into stderr (if provided).
Negative values returned indicate fatal errors: -1 when assembler ran out of memory, -2 when maximum number of passes has been reached without a resolved assembly, -3 when writing output file has failed for some reason.

I kept this version as simple as possible, mainly to demonstrate how the bare engine can be used. If you wanted a pure memory-to-memory assembly, you'd need to add some special handling. You'd have to allocate a big enough memory block (get_output_length function can give the required size) and then perhaps use read_from_output to copy data.

EDIT: Attachment removed - see below.


Last edited by Tomasz Grysztar on 13 Sep 2018, 07:57; edited 3 times in total
Post 21 Aug 2018, 20:51
View user's profile Send private message Visit poster's website Reply with quote
sesey



Joined: 21 Aug 2018
Posts: 3
sesey 22 Aug 2018, 09:17
Tomasz Grysztar wrote:
sesey wrote:
How can I compile this source code as x64.dll?
This is a bit complex, it requires the same macros as Linux x64 version and rewrite of OS abstraction layer, I may take a look at this in the future.


I thank you for your help. I will wait for your future work.
Post 22 Aug 2018, 09:17
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 23 Aug 2018, 17:25
I have added a simple modification to the above FASMG.DLL to allow a pure memory-to-memory assembly.

The reserved argument became output_region which should either be a NULL (when no in-memory output is needed) or a pointer to this simple structure:
Code:
struct MEMORY_REGION
        address dd ?
        size dd ?
ends    
It should be initially zeroed or may be filled with information about a block of memory pre-allocated with VirtualAlloc. When the assembly is successful, the structure is filled with information about the size of generated output and the address where it is stored. If the structure provided a memory region but it was too small to hold the output, a region is re-allocated with VirtualAlloc, releasing the previous one with VirtualFree. This way you can keep calling fasmg_Assemble and have it re-use the same region of memory for output. You can also initialize the address field to point to a region prepared with VirtualAlloc with MEM_RESERVE flag and set the initial size to zero, fasmg_Assemble should then be able to keep using the reserved address, committing as much memory as needed for the generated output.

For pure memory-to-memory assembly both source_path and output_path should be NULL.

EDIT: Attachment removed - see below.


Last edited by Tomasz Grysztar on 13 Sep 2018, 07:57; edited 1 time in total
Post 23 Aug 2018, 17:25
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 31 Aug 2018, 15:30
I have now included the sources of this simple DLL in the main repository of fasmg: https://flatassembler.net/fossil/repo/fasmg/info/3d9126369323f2c7

EDIT: the sources are now also included in the basic package. The added files are small and I like them enough to show them in the official distribution as a demonstration how fasmg core can be used in multi-threaded environment.
Post 31 Aug 2018, 15:30
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 13 Sep 2018, 09:34
Tomasz Grysztar wrote:
sesey wrote:
How can I compile this source code as x64.dll?
This is a bit complex, it requires the same macros as Linux x64 version and rewrite of OS abstraction layer, I may take a look at this in the future.
I have made an experimental FASMX64.DLL that uses the same macros as Linux x64 version. It seems to work, but keep in mind that the limitation of this hack is that it is only going to work when all the memory blocks fit in the low 4G addressing space. When you allocate memory for fasm you need to make sure that allocation is in the low memory, also when you provide source text in memory, you need to ensure that is fits in low 4G.

At the same time I also added a mutex in FASM.DLL. I think I have been making a bad example by not using something like that when the core is obviously and dangerously not thread-safe.

I believe it might also be possible to make FASMX64.DLL not require mutex and just use a per-thread memory block for all variables by addressing it with a base register like R14 (similarly to how FASMG.DLL addresses everything relative to EBP). However this would require some careful setup, to allocate locals block in low 4G space for every function call. For now I used a mutex there, too.
Post 13 Sep 2018, 09:34
View user's profile Send private message Visit poster's website Reply with quote
bazizmix



Joined: 15 Jan 2016
Posts: 51
bazizmix 02 Nov 2018, 14:45
So. I made a 64-bit fasm. Exe and dll. Tested only for PE and PE64.
It can be compiled as 32-bit from 64-bit and versa.


Description: Source and example
Download
Filename: fasmdll64.7z
Filesize: 230.33 KB
Downloaded: 1381 Time(s)

Post 02 Nov 2018, 14:45
View user's profile Send private message Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 817
Location: Russian Federation, Sochi
ProMiNick 18 Nov 2018, 19:12
Because of my attachments limit exceded - https://yadi.sk/d/OED0phH1DFaeMg
There are located use of fasm.dll previously posted above, and added use of fasmarm.dll (ofcource with fasmarm.dll inside)

P.S. sorry guys - no sources for fasmarm.dll. Source looks ugly - I adapt them just to get working out.
For normal sources to fasmarm.dll ask revolution.
Post 18 Nov 2018, 19:12
View user's profile Send private message Send e-mail Reply with quote
Sewer56



Joined: 23 Dec 2018
Posts: 2
Sewer56 23 Dec 2018, 18:11
Quite recently, I started work on my own minimal C#/.NET wrapper to try and leverage the recently released "FASMX64" so I could make 64-bit development with FASM a possibility in the high-level world.

I have had some serious problems getting FASMX64 (from the first post/1.73 core) to run myself; no matter what I did - the .NET Core / .NET Framework process would crash the moment FASMX64.dll was loaded.

I have tried the following methods of loading the library into the process:
1. P/Invoke (uses LoadLibrary under the hood).
2. LoadLibraryA/W
3. Dll Injection
4. Manual Mapping DLL Injection (using an external library)

To no avail. Immediate crash with every attempt after ~4-6 hours of attempts.

Seeing that in the post above, bazizmix also posted his attempt at experimental X64 FASM, I tried his solution and it fortunately loaded without problems. It worked for fasm_GetVersion, but fasm_Assemble was broken 100% of the time for assembling ASM with errors and Random% of the time otherwise.

-----------------------------------------

The good news at least is that in the end, after 2-3 hours of debugging with Cheat Engine and the source open beside in Notepad++, I did manage to make things work.

I took the modified source uploaded by bazizmix and have made the following changes/fixes:

1. I changed how hDisplayPipe is retrieved for x64 from the function parameters as the stack offset used was incorrect and pointed into the "shadow space" of the Microsoft X64 calling convention.

This caused random crashes as FASMDLL would sometimes try to read uninitialized memory when trying to obtain the display pipe handle because the contents of the "shadow space" are undefined (it is not zero filled and typically contains old stack data),

2. The esp_save variable was marked as a qword but when it was backed up, the value 32-bit register was stored as opposed to the full length 64-bit register. This led to issues if the stack was in the 64-bit address range.

3. In assemble.inc, the error_handler which jumps the assembler to the error table was not using the full width registers for esp, eax. This became an issue when adding a negative value was involved, as the high bits of the register were not set - only half a register. I changed them to the _esp, _eax macros respectively and confirmed the solution still compiles and works for x86 as well as x64.

This led to crashes 100% of the time there was an error because of a bad jump to uninitialized/random memory.

All changes are commented with [CHANGE] in the source files fasmdll.asm and assemble.inc where they are applied. I also left some general comments

My modified version is linked in the attachments.
As for the .NET wrapper library, you can find it here: https://github.com/Reloaded-Project/Reloaded.Assembler

Merry Christmas everyone!

PS.
My solution still adheres to the original given limitations of FASMX64, I did not modify the actual assembler itself as that would be a rather large undertaking. This means that 64bit pointers for lpSource, lpMemory are a no-go; they must be addressed in the first 4G of Memory (32bit pointers).


Description:
Download
Filename: fasmdll64mod.7z
Filesize: 221.45 KB
Downloaded: 1145 Time(s)

Post 23 Dec 2018, 18:11
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 23 Dec 2018, 18:58
Unless DLL ends up loaded at high (above 4G) base address, it should not be needed to modify the core fasm (like "error_handler" routine). But perhaps bazimix's version does not use the same tricks - my macros (originally written to make the x64 Linux executable) redefine ESP to always mean RSP, for example.

Interestingly, even though your notes concern bazimix's version, my version also had a bug in how the value of hDisplayPipe was retrieved - I have corrected it now (the attachment in first post is updated).

As for "esp_save", my version does not have it, the value of RSP is preserved in R12 (not used by fasm's core).
Post 23 Dec 2018, 18:58
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 23 Dec 2018, 19:37
Please try the updated version of my (official) adaptation. I have noticed and corrected a bug in "invoke" macro, perhaps this is what was causing crash on load (DLLEntryPoint in my version calls CreateMutex with "invoke").
Post 23 Dec 2018, 19:37
View user's profile Send private message Visit poster's website Reply with quote
Sewer56



Joined: 23 Dec 2018
Posts: 2
Sewer56 23 Dec 2018, 20:26
I've tested the updated official version with 50 runs of the assembler by hand and can confirm that everything works perfectly now. Very Happy
Post 23 Dec 2018, 20:26
View user's profile Send private message Visit poster's website Reply with quote
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 26 May 2019, 02:38
@Tomasz Grysztar

I know this is an old thread, but it appears to be the official post for the DLL version of FASM. So I'm going to ask here.

Why is FASM.dll not letting me use labels? I have code like this to test it:
Code:
USE32
org 0x400000
call [zzzz]
zzzz: dd 0x12345678    


Although it will assemble to machine-language code that will end up crashing when executed, it is valid assembly language code that any assembler should be able to handle. It has an actual machine-language equivalent that an x86 processor can attempt to execute (and crash when doing so). It means get the value stored at the label called "zzzz", and then use that value as the address to jump to with the call opcode. This works in normal FASM.exe but not the DLL version of FASM. Please fix this.

And while this specific example would crash, you could put other values at the label "zzzz" that would be valid addresses (such as addresses of other functions) and would NOT end up crashing when executed. Again, there is NO REASON for an assembler to reject the use of labels as I'm using them here, and in fact the EXE version of FASM does assemble this code. It's just that your DLL version of FASM is buggy, and refuses to accept this particular type of syntax. Please fix your DLL version of FASM.
Post 26 May 2019, 02:38
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4161
Location: vpcmpistri
bitRAKE 26 May 2019, 03:48
I'd guess the error is because the type of "zzzz" is not sufficient to select among the many CALL instructions possible. Please, use:
Code:
zzzz dd 0x12345678    
...and it will assemble just fine.

It's the same as if you did something like:
Code:
movzx eax,[zzzz]    
...what is "zzzz"?

The ":" signifies an untyped label.

It's also possible to specify the type inline:
Code:
call dword [zzzz]    
Post 26 May 2019, 03:48
View user's profile Send private message Visit poster's website Reply with quote
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 26 May 2019, 03:58
So without the : it means a function pointer? But with the : it means it doesn't know what it is?
Post 26 May 2019, 03:58
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4161
Location: vpcmpistri
bitRAKE 26 May 2019, 04:41
Function pointers are a high-level language concept not explicitly supported by fasm. The label is just a number - do with it what you will. When it comes to instructions the assembler needs to know what you want - it doesn't assume you are working in a particular environment beyond the processor mode specified.

It's probably not what you are used to, but it closely complements the processor instructions.

Code:
call [zzzz]
zzzz df $0123:$01234567    
fasm doesn't know if you intend the above instruction.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 26 May 2019, 04:41
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20517
Location: In your JS exploiting you and your system
revolution 26 May 2019, 07:53
So to summarise:

Code:
zzzz:                                   ; plain number with no associated size
zzzz db 'hello world'                   ; still a plain number with associated byte size addressing
zzzz rd 10                              ; still a plain number with associated dword size addressing
label zzzz word at ebx + 8 * eax + 6    ; register based value (not a plain number anymore) with word size addressing    
Post 26 May 2019, 07:53
View user's profile Send private message Visit poster's website Reply with quote
masm



Joined: 10 Oct 2014
Posts: 6
masm 09 Aug 2019, 00:27
64 bit code assembler no worke for exemple mov rax,rbx give me error ?
Post 09 Aug 2019, 00:27
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20517
Location: In your JS exploiting you and your system
revolution 09 Aug 2019, 00:52
masm wrote:
64 bit code assembler no worke for exemple mov rax,rbx give me error ?
Do you have use64 in your code?
Code:
use64
mov rax,rbx    
Post 09 Aug 2019, 00:52
View user's profile Send private message Visit poster's website Reply with quote
masm



Joined: 10 Oct 2014
Posts: 6
masm 09 Aug 2019, 09:45
thank you revolution it is worke perfectly
Post 09 Aug 2019, 09:45
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3, 4, 5, 6  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.