flat assembler
Message board for the users of flat assembler.

Index > Windows > "library" directive is an invalid instruction

Author
Thread Post new topic Reply to topic
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 07 Dec 2017, 00:11
I'm just a noob here, and I think this code should compile, but it tells me that the "library" directive is an invalid instruction.

Code:
format PE GUI 4.0
entry start

section ".text" code readable executable
        start:
        push 0
        pop eax
        ret

section ".idata" import data readable writeable
        library kernel32,"kernel32.dll"
        import kernel32,ExitProcess,"ExitProcess"    


According to the manual, the library directive is valid. I'm even putting it in the correct section (the import section). If anybody knows why this isn't working, please let me know. Thanks in advance.
Post 07 Dec 2017, 00:11
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20356
Location: In your JS exploiting you and your system
revolution 07 Dec 2017, 01:35
library is a macro. An easy way to define it is to include one of the base header files (eg. win32a.inc).
Code:
format PE GUI 4.0
entry start

include 'win32a.inc'

section '.text' code readable executable

  start:
        invoke  SetLastError,0
        invoke  ShowLastError,HWND_DESKTOP
        invoke  ExitProcess,0

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          errormsg,'ERRORMSG.DLL'

  import kernel,\
         SetLastError,'SetLastError',\
         ExitProcess,'ExitProcess'

  import errormsg,\
         ShowLastError,'ShowLastError'    
Post 07 Dec 2017, 01:35
View user's profile Send private message Visit poster's website Reply with quote
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 07 Dec 2017, 03:39
revolution wrote:
library is a macro. An easy way to define it is to include one of the base header files (eg. win32a.inc).
Code:
format PE GUI 4.0
entry start

include 'win32a.inc'

section '.text' code readable executable

  start:
        invoke  SetLastError,0
        invoke  ShowLastError,HWND_DESKTOP
        invoke  ExitProcess,0

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          errormsg,'ERRORMSG.DLL'

  import kernel,\
         SetLastError,'SetLastError',\
         ExitProcess,'ExitProcess'

  import errormsg,\
         ShowLastError,'ShowLastError'    


But doesn't including win32a.inc automatically import all of the Windows API dll files, thus removing the need to ever call the library macro?
Post 07 Dec 2017, 03:39
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20356
Location: In your JS exploiting you and your system
revolution 07 Dec 2017, 03:55
Ben321 wrote:
But doesn't including win32a.inc automatically import all of the Windows API dll files, thus removing the need to ever call the library macro?
win32a will only define macros. You still need to place the library and import data into your code at the place you need it (usually at the end of the file, but it doesn't have to be there).
Post 07 Dec 2017, 03:55
View user's profile Send private message Visit poster's website Reply with quote
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 07 Dec 2017, 08:11
revolution wrote:
Ben321 wrote:
But doesn't including win32a.inc automatically import all of the Windows API dll files, thus removing the need to ever call the library macro?
win32a will only define macros. You still need to place the library and import data into your code at the place you need it (usually at the end of the file, but it doesn't have to be there).


I just opened win32a.inc in a text editor, and found it also loaded a bunch of other stuff than just macros. It also loaded definitions of Windows API structures (like BitmapInfoHeader, and other similar things). That's a bunch of unnecacary overhead, so I found a work around. I can directly Include the required file by doing:
Code:
include "macro\import32.inc"    


This includes the 2 macros required for importing DLL functions, which are "library" and "import".

Really though, these 2 statements ("library" and "import") should be built-in compiler directives, not macros defined in a .inc file, so that you don't need to add them in every program you write. Having to use the same "include" statement in every single program you write, just so you can import DLL functions in your program (which is very basic functionality in a compiler) seems like unnecessary extra lines of code.
Post 07 Dec 2017, 08:11
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 07 Dec 2017, 12:01
Ben321 wrote:
Really though, these 2 statements ("library" and "import") should be built-in compiler directives, not macros defined in a .inc file, so that you don't need to add them in every program you write. Having to use the same "include" statement in every single program you write, just so you can import DLL functions in your program (which is very basic functionality in a compiler) seems like unnecessary extra lines of code.
The main focus of fasm in the control over low level, thus almost all the higher level constructs are implemented with macros.

Even the "basic functionality" of constructing import table that you mentioned is something that may be done in different ways depending on the requirements of an environment. Note that PE format is used by different systems and for various purposes (and anyone playing with OS development may also add new ones to the growing list). What is a good way to construct an import section in most of the regular Win32 programming, may not be enough in other cases. Some PE loaders may expect the structures to be set up differently (the PE specification leaves a lot of room for variation) and some people may prefer to simply set up an import generation in an entirely different way (the syntax that is used by the "library" and "import" macros is a legacy from the times when fasm's macro abilities were less developed).

I tried to provide a set of robust building blocks that can be used to construct supplementary layers of the language with a high degree of control (it is something I once called "complex solutions with simple features") and I have seen people using it with very interesting results. This lead to the development of fasm even further in this direction, and fasmg is the ultimate manifestation of that.
Post 07 Dec 2017, 12:01
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: 20356
Location: In your JS exploiting you and your system
revolution 07 Dec 2017, 14:59
Ben321 wrote:
Really though, these 2 statements ("library" and "import") should be built-in compiler directives, not macros defined in a .inc file, so that you don't need to add them in every program you write. Having to use the same "include" statement in every single program you write, just so you can import DLL functions in your program (which is very basic functionality in a compiler) seems like unnecessary extra lines of code.
With great power comes great responsibility. So this provides you with absolute control (the great power), and it also requires you to tell it exactly what you need (the great responsibility).

For most uses it is only one extra line in the source. But compare that to some other assembler that requires you to make ancillary files for "make" and/or "link", plus all that extra typing on the command line with all sorts of switches and things every time you want to assemble something. All-in-all I think the amount of work and cognitive load is less when dealing with fasm. But your usage may vary. Wink
Post 07 Dec 2017, 14:59
View user's profile Send private message Visit poster's website Reply with quote
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 07 Dec 2017, 21:47
revolution wrote:
Ben321 wrote:
Really though, these 2 statements ("library" and "import") should be built-in compiler directives, not macros defined in a .inc file, so that you don't need to add them in every program you write. Having to use the same "include" statement in every single program you write, just so you can import DLL functions in your program (which is very basic functionality in a compiler) seems like unnecessary extra lines of code.
With great power comes great responsibility. So this provides you with absolute control (the great power), and it also requires you to tell it exactly what you need (the great responsibility).

For most uses it is only one extra line in the source. But compare that to some other assembler that requires you to make ancillary files for "make" and/or "link", plus all that extra typing on the command line with all sorts of switches and things every time you want to assemble something. All-in-all I think the amount of work and cognitive load is less when dealing with fasm. But your usage may vary. Wink


Those 2 things though are common to every EXE file ever. You need a library and import statement, just to get to the ExitProcess function, which is the correct way to terminate a Windows program (not a RET opcode, as that only terminates the current thread, and if your process has more than one thread the rest of them will keep running in the background).
Post 07 Dec 2017, 21:47
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20356
Location: In your JS exploiting you and your system
revolution 08 Dec 2017, 00:15
If you use 'win32ax.inc' (note the extra 'x') then you can use the .end macro instead of library and import.
Code:
; example of simplified Windows programming using complex macro features

include 'win32ax.inc' ; you can simply switch between win32ax, win32wx, win64ax and win64wx here

.code

  start:
        invoke  MessageBox,HWND_DESKTOP,"Hi! I'm the example program!",invoke GetCommandLine,MB_OK
        invoke  ExitProcess,0

.end start    
Post 08 Dec 2017, 00:15
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 08 Dec 2017, 07:19
Ben321 wrote:
Those 2 things though are common to every EXE file ever.
This is technically not true. Even on the same day that you posted this, someone else reported a bug with a sample that shows one of the cases when features of PE format are used differently and without import table. And even if sticking just to Windows, there are examples to the contrary in this system, too.
Post 08 Dec 2017, 07:19
View user's profile Send private message Visit poster's website Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2519
Furs 08 Dec 2017, 13:06
Ben321 wrote:
Really though, these 2 statements ("library" and "import") should be built-in compiler directives, not macros defined in a .inc file, so that you don't need to add them in every program you write. Having to use the same "include" statement in every single program you write, just so you can import DLL functions in your program (which is very basic functionality in a compiler) seems like unnecessary extra lines of code.
Nah. You realize imports require including stuff anyway for the APIs.

Or do you want to make kernel32's API also "builtin" into the assembler because it's "common" to any exe file? Confused
Post 08 Dec 2017, 13:06
View user's profile Send private message Reply with quote
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 08 Dec 2017, 19:41
Furs wrote:
Ben321 wrote:
Really though, these 2 statements ("library" and "import") should be built-in compiler directives, not macros defined in a .inc file, so that you don't need to add them in every program you write. Having to use the same "include" statement in every single program you write, just so you can import DLL functions in your program (which is very basic functionality in a compiler) seems like unnecessary extra lines of code.
Nah. You realize imports require including stuff anyway for the APIs.

Or do you want to make kernel32's API also "builtin" into the assembler because it's "common" to any exe file? Confused


Actually they don't. To enable imports, all you need to to have this one include line:
Code:
include "macro\import32.inc"    


Unlike most code examples shown for FASM, there's no need to include anything related to the Windows API.
Post 08 Dec 2017, 19:41
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2519
Furs 09 Dec 2017, 00:02
Yes, but I was replying to what you said. No Windows program can function without kernel32 API (at the very least) if it uses any imports at all, so using that logic, we should also include it in the compiler. Wink
Post 09 Dec 2017, 00:02
View user's profile Send private message Reply with quote
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 09 Dec 2017, 01:40
Nope. It's even more basic than this. Import and Library should both be internal commands in fasm. With those 2 commands, you can then import any dll functions that you need.
Post 09 Dec 2017, 01:40
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 09 Dec 2017, 09:28
Ben321 wrote:
Import and Library should both be internal commands in fasm.
This seems inconsistent to me. On the one hand you asked for more control over parts of header that are generated by fasm's internal formatter. On the other hand you say that imports should be generated by internal commands - which would give much less control over their structure.

It would be possible to allow both alternatives - to use an internal command or construct the structures manually. But an effort dedicated to implementing this would feel like a waste of time when the macros are so simple and easy to maintain (they also serve an additional educational purpose by showing how simple it is to generate these structures). The general direction of the development of fasm was always in the direction of more control, and after I made a PE formatter for fasmg, entirely a macro, I no longer feel a need to look back.

If I ever come to make a fasm 2 based on fasmg engine, I'm pretty sure that I would want to preserve the formatters in the macro form that are already made for fasmg (this would require making instruction handlers call a user-defined macros to generate the immediate/displacement fields in cases when relocations are needed, but fasmg engine already has tools for this), They allow for all the control one might ever need, and maintaining them is a pleasure.
Post 09 Dec 2017, 09:28
View user's profile Send private message Visit poster's website Reply with quote
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 10 Dec 2017, 16:50
Tomasz Grysztar wrote:
Ben321 wrote:
Import and Library should both be internal commands in fasm.
This seems inconsistent to me. On the one hand you asked for more control over parts of header that are generated by fasm's internal formatter. On the other hand you say that imports should be generated by internal commands - which would give much less control over their structure.

It would be possible to allow both alternatives - to use an internal command or construct the structures manually. But an effort dedicated to implementing this would feel like a waste of time when the macros are so simple and easy to maintain (they also serve an additional educational purpose by showing how simple it is to generate these structures). The general direction of the development of fasm was always in the direction of more control, and after I made a PE formatter for fasmg, entirely a macro, I no longer feel a need to look back.

If I ever come to make a fasm 2 based on fasmg engine, I'm pretty sure that I would want to preserve the formatters in the macro form that are already made for fasmg (this would require making instruction handlers call a user-defined macros to generate the immediate/displacement fields in cases when relocations are needed, but fasmg engine already has tools for this), They allow for all the control one might ever need, and maintaining them is a pleasure.


What if the import and library macros were built into fasm, and then by default they were included automatically (prepended to the source code) when you hit the compile button? You don't have to use them if you don't want but they should always be available without having to manually include an external file containing these 2 macros.

As for more flexibility, maybe just allow one to declare a special named section like .peheader, and anything put there automatically starts at the beginning of the file, instead of the code section.
Post 10 Dec 2017, 16:50
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 10 Dec 2017, 17:02
Ben321 wrote:
What if the import and library macros were built into fasm, and then by default they were included automatically (prepended to the source code) when you hit the compile button? You don't have to use them if you don't want but they should always be available without having to manually include an external file containing these 2 macros.
Automatically including the macros would kind of defeat their purpose (and could needlessly interfere with fasm's uses outside of the Windows world).

However, avoiding an INCLUDE directive in the source could be possible with something like fasmg's "-i" command line switch (this is a feature that I actually considered for backporting).

Ben321 wrote:
As for more flexibility, maybe just allow one to declare a special named section like .peheader, and anything put there automatically starts at the beginning of the file, instead of the code section.
Any substantial rewrite of fasm's formatter is off the limits now, I prefer to use the little time I have to work on more important features. And fasmg's macros already provide everything needed to generate a highly customized PE files.
Post 10 Dec 2017, 17:02
View user's profile Send private message Visit poster's website Reply with quote
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 11 Dec 2017, 04:19
Tomasz Grysztar wrote:
Ben321 wrote:
What if the import and library macros were built into fasm, and then by default they were included automatically (prepended to the source code) when you hit the compile button? You don't have to use them if you don't want but they should always be available without having to manually include an external file containing these 2 macros.
Automatically including the macros would kind of defeat their purpose (and could needlessly interfere with fasm's uses outside of the Windows world).

However, avoiding an INCLUDE directive in the source could be possible with something like fasmg's "-i" command line switch (this is a feature that I actually considered for backporting).

Ben321 wrote:
As for more flexibility, maybe just allow one to declare a special named section like .peheader, and anything put there automatically starts at the beginning of the file, instead of the code section.
Any substantial rewrite of fasm's formatter is off the limits now, I prefer to use the little time I have to work on more important features. And fasmg's macros already provide everything needed to generate a highly customized PE files.


Would it really require a rewrite of fasm's formatter? It would seem to only require adding a few lines of code to add the new features. You wouldn't need to change any existing features. As for different versions, the Linux version should have linux-specific features, and the windows version should have windows-specific features.
Post 11 Dec 2017, 04:19
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20356
Location: In your JS exploiting you and your system
revolution 11 Dec 2017, 05:47
Ben321 wrote:
As for different versions, the Linux version should have linux-specific features, and the windows version should have windows-specific features.
The Windows version can assemble all formats. The Linux version can assemble all formats. Indeed, all versions can assemble all other formats.
Post 11 Dec 2017, 05:47
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.