flat assembler
Message board for the users of flat assembler.

Index > Windows > extrn definitions in ms coff object file

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
uglyhunK



Joined: 21 Jan 2010
Posts: 3
Location: Bangalore, India
uglyhunK 21 Jan 2010, 03:26
Hi, following is an example to make ms coff object file. This will not be assembled unless each API function is defined using extrn. Surely there should be a better way than listing each API function in its cryptic form.

Thanks

Code:
format MS COFF
include 'win32a.inc'
extrn '__imp__MessageBoxA@16' as MessageBox:dword

section '.text' code readable executable
public demo
demo:
        invoke  MessageBox, NULL, msg, title, MB_OK
        ret

section '.data' data readable writeable
        title db 'Title', 0
        msg db 'Message', 0
    
Post 21 Jan 2010, 03:26
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20454
Location: In your JS exploiting you and your system
revolution 21 Jan 2010, 03:34
What better way are you suggesting?

There is the possibility of using a macro to define the external labels but it doesn't look to me that is would save much at all. You will still need to define the base name and the number of parameters in some form to make the "cryptic" external name.
Code:
extrnFuncMacro MessageBox,4    
?
Post 21 Jan 2010, 03:34
View user's profile Send private message Visit poster's website Reply with quote
uglyhunK



Joined: 21 Jan 2010
Posts: 3
Location: Bangalore, India
uglyhunK 21 Jan 2010, 03:39
Revolution, so you say for each API function that is used, one needs to find out its exported name and list it as extrn. Then one can might as well shun creating an object file and include all that code in one single file. Just not worth the time.
Post 21 Jan 2010, 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: 20454
Location: In your JS exploiting you and your system
revolution 21 Jan 2010, 03:43
uglyhunK wrote:
Revolution, so you say for each API function that is used, one needs to find out its exported name and list it as extrn.
Yes, of course. How else does fasm know what to put in the COFF file?
uglyhunK wrote:
Then one can might as well shun creating an object file and include all that code in one single file. Just not worth the time.
No. Why?

COFF is used for output to a linker. If you mix HLLs with assembly then you pretty much are forced to create some sort of object file for linking.
Post 21 Jan 2010, 03:43
View user's profile Send private message Visit poster's website Reply with quote
uglyhunK



Joined: 21 Jan 2010
Posts: 3
Location: Bangalore, India
uglyhunK 21 Jan 2010, 03:53
Yup....understood. Just like imported data section that lists dlls and functions when creating executable.
Post 21 Jan 2010, 03:53
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 21 Jan 2010, 09:35
revolution: there's already lists of argument counts for a lot of APIs shipped with fasm, those could be used... or an "apicall" macro could be made that counts arguments, and automatically generates the extern.

I've played around with this, but either I'm really missing something, or the fasm macro system is even more limited than I thought. Is there really no way to get a textual representation of a numeric-constant? Ie., if I have the numeric-constant 100, I want the string '100' and not the ascii char 'd'.
Post 21 Jan 2010, 09:35
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: 20454
Location: In your JS exploiting you and your system
revolution 21 Jan 2010, 11:51
f0dder: Building arbitrary strings for use not designed to be plain data is really hard to do in fasm. Now that the preprocessor can do computations it is easier but still tricky. Do you need a solution for this? Show your general outline and perhaps it can be coded up.

If you want to see how it might be done before the preprocessor was able to internally do arithmetic see here
Post 21 Jan 2010, 11:51
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 21 Jan 2010, 12:57
I remember I did macros with parameter count without any trouble in FASM, but unfortunatelly I don't have my old dev dir here.

But I think I had to parse existing includes to something like
Code:
apidef MessageBoxA, 16
apidef ExitProcess, 4
    


And yeah, string manipulation is really poor in FASM macro system.
Post 21 Jan 2010, 12:57
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20454
Location: In your JS exploiting you and your system
revolution 21 Jan 2010, 13:19
Maybe this:
Code:
format MS COFF
include 'win32a.inc'

macro apicall func,[params] {
    common
    local .count,.here
        if ~ defined func | defined .here
           .here = 1
           .count equ 0
                match q,params\{irp p,q\\{rept 1 r:.count+4 \\\{.count equ r\\\}\\}\}
         match p,.count \{extrn '__imp__'\#`func\#'A@'\#\`p as func:dword\}
  end if
      invoke  func,params
}

section '.text' code readable executable

public demo
demo:
     apicall Function0
   apicall Function1,1
 apicall Function2,1,2
       apicall Function3,1,2,4
     apicall Function4,1,2,3,4
   ret

section '.data' data readable writeable
        title   db 'Title',0
      msg     db 'Message',0    
Post 21 Jan 2010, 13:19
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 21 Jan 2010, 15:02
There is another approach: assume the library is available. Several utilities combined, as shown
Code:
dumpbin /exports user32.lib | sed -r -n "s/^ +([_@]([A-Za-z_][A-za-z0-9_]*)(@[0-9]+)?)/if used \2\n  extrn '__imp_\1' as \2:dword\nend if/p"    
will output this:
Code:
if used ActivateKeyboardLayout
  extrn '__imp__ActivateKeyboardLayout@8' as ActivateKeyboardLayout:dword
end if
if used AddClipboardFormatListener
  extrn '__imp__AddClipboardFormatListener@4' as AddClipboardFormatListener:dword
end if
if used AdjustWindowRect
  extrn '__imp__AdjustWindowRect@12' as AdjustWindowRect:dword
end if
if used AdjustWindowRectEx
  extrn '__imp__AdjustWindowRectEx@16' as AdjustWindowRectEx:dword
end if
if used AllowSetForegroundWindow
  extrn '__imp__AllowSetForegroundWindow@4' as AllowSetForegroundWindow:dword
end if
if used AnimateWindow
  extrn '__imp__AnimateWindow@12' as AnimateWindow:dword
end if
...    
Probably not 100% bullet-proof. x64 import libraries in VS 2008 export undecorated names for thunks (without _ and @), regexp can be modified to accept that.
Post 21 Jan 2010, 15:02
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 21 Jan 2010, 17:21
revolution: the "rept 1 r:.count+4" part fails, "invalid value" (fasm 1.6Cool. Is that block supposed to produce different behavior from ".count equ .count+4" ? The

Also, the match block doing the extrn fails as well, "invalid argument" - seems to be because of the nesting-backslash. Removing those makes it work, but! - the idea still doesn't work, because the ` operator evaluates .count to char representation of it's value... rather than giving the quoted-string value. In other words, if you call a FooBarFun with 17 arguments, the generated extrn symbol will be __imp__FooBarFunA@D, not __imp__FooBarFun@68.

And I haven't been able to find a way to append "count" to the extrn string in one go - with the ` operator I get the name of the count variable appended, without it I get an assemble error.

My attempt yesterday ended up something like the following... which doesn't work, seems like extrn doesn't consider the value of .xname as a single symbol? - use of match doesn't seem to help, either. For now, ignore the fact that there's no A/W name decoration nor check for multiple definitions of the same extrn - it's getting the string built and extrn'ed that's the primary focus Smile

Code:
macro docall name, [arg]
{
common
   local .count, .xname
        .count = 0
reverse
       .count = .count + 4
 push    arg
common
       .xname equ '__imp__'#`name#'@',.count

       extrn .xname as name:dword
      call    name
}
    
Post 21 Jan 2010, 17:21
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: 20454
Location: In your JS exploiting you and your system
revolution 21 Jan 2010, 17:27
f0dder: Use 1.69.11 and it all works well.

See my link above for how to do it on the fasm versions without the preprocessor arithmetic.

[edit]
Here is the link. http://board.flatassembler.net/topic.php?t=8021


Last edited by revolution on 21 Jan 2010, 17:31; edited 1 time in total
Post 21 Jan 2010, 17:27
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 21 Jan 2010, 17:29
f0dder, it would end up as something like this: extrn '__imp__funcname@,.count as funcname:dword

revolution's code needs FASM 1.69 and something like that is required because the number must be in string form and in the assembler layer you can't get that.
Post 21 Jan 2010, 17:29
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20454
Location: In your JS exploiting you and your system
revolution 21 Jan 2010, 17:47
WHATSNEW.TXT wrote:
version 1.69.00 (Jun 23, 2009)

[+] Extended the syntax of "rept" directive to allow numerical expressions
to be calculated by preprocessor in its arguments.
Post 21 Jan 2010, 17:47
View user's profile Send private message Visit poster's website Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 22 Jan 2010, 00:03
LocoDelAssembly wrote:
f0dder, it would end up as something like this: extrn '__imp__funcname@,.count as funcname:dword
Yes, if you add the ` operator, it would...

LocoDelAssembly wrote:
revolution's code needs FASM 1.69 and something like that is required because the number must be in string form and in the assembler layer you can't get that.
Well, it ought to be possible to do so in the preprocessing layer without so much fuss! (the ".count = .count+4" would be assembly layer I guess, but change "=" to "equ" and assembly layer isn't involved?).

revolution: can you explain to me how your code manages to translate a "number" to a "string" so they can be concatenated? Does the rept iteration-argument get treated magically?

It's all pretty hacky :/ - I know thre's limits to what can be done with the current FASM macro system (iirc Tomasz said it would be pretty much impossible to get MASM style EXITM support without more or less a rewrite?), but better string support at preprocessor time, perhaps some (limited?) support for using the assembler's evaluator, and a way to "collapse" a list into either a string or identifier... those would be useful, and I assume possible to implement in FASM 1.x without too much trouble?

_________________
Image - carpe noctem
Post 22 Jan 2010, 00:03
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: 20454
Location: In your JS exploiting you and your system
revolution 22 Jan 2010, 02:16
f0dder wrote:
(the ".count = .count+4" would be assembly layer I guess, but change "=" to "equ" and assembly layer isn't involved?).
But that only ends up defining .count as '0+4+4+4+4+4' without evaluating the value. At present only rept has the capability to evaluate an expression at preprocessor time. Did you see the link I posted? That may give you some insight into how the preprocessor handles things.
Post 22 Jan 2010, 02:16
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 22 Jan 2010, 07:32
uglyhunK,

Will single include file (implib32.inc, containing/including all extrns for import libraries in your %LIB% folder) solve the problem?
Post 22 Jan 2010, 07:32
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20454
Location: In your JS exploiting you and your system
revolution 22 Jan 2010, 07:48
f0dder wrote:
revolution: can you explain to me how your code manages to translate a "number" to a "string" so they can be concatenated? Does the rept iteration-argument get treated magically?
I have added comments trying to explain what each command does.
Code:
format MS COFF
include 'win32a.inc'

macro apicall func,[params] {
    common
    local .count,.here
  .count equ 0
        match q,params \{                 ;if 'params' is empty then skip this block
                irp p,q \\{                      ;iterate through each parameter
                     rept 1 r:.count+4 \\\{      ;evaluate r=.count+4
                                .count equ r    ;set .count=.count+4
                        \\\}
                \\}
  \}
    if ~ defined func | defined .here       ;only allow one definition of extrn func
            .here = 1
           match p,.count \{         ;transfer value of .count into p
                    extrn '__imp__'\#`func\#'A@'\#\`p as func:dword
         \}
    end if
      invoke  func,params                     ;do the call
}

section '.text' code readable executable

public demo
demo:
    apicall Function0                       ;test zero parameters
       apicall Function1,1                     ;test one parameters
        apicall Function2,1,2                   ;test two parameters
        apicall Function3,1,2,4                 ;test three parameters
      apicall Function4,1,2,3,4               ;test four parameters
       apicall Function4,1,2,3,4               ;test multiple calls
        apicall Function4,1,2,3,4               ;test multiple calls
        ret    
Post 22 Jan 2010, 07:48
View user's profile Send private message Visit poster's website Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 22 Jan 2010, 13:00
revolution wrote:
But that only ends up defining .count as '0+4+4+4+4+4' without evaluating the value.
Ah, that was one of my missing links! Smile - I had assumed that it did (limited) expression evaluation as well... a combination of the lack of a way to see preprocessed output, and misreading the docs:
fasm dox wrote:
If the value of symbolic constant contains other symbolic constants, they are replaced with their values before assigning this value to the new constant.


It's kinda dirty having to use rept and match for these things... an eval operator would be kinda nice - would that be possible to implement in the current codebase, or is equate-expansion done in a way that makes this impossible?

Ie, instead of the rept and match trick above, you would either use irp or a forward block to do ".count equ .count + 4" (gathering up the symbolic string above). Then, you'd do...
extrn '__imp__'#func'A@'#§.count as func:dword (assuming § is used for evalute-equate-and-replace). Wouldn't that be a lot nicer syntax and effort-wise? Smile

Thanks for commenting the example above - I understood most of it without, it was rept-magic (and lack of equ doing it) I was missing. One thing I'm still missing though: are the nesting-slashes necessary inside the match block? Or are you adding them just for good measures?

Anyway, I'm thinking it might be possible to rework the Windows includes so they can be used with both COFF+linker and PE formatters, but I'd definitely have to get more comfortable with the preprocessor befor trying my hand at it Smile - and I don't think I'd bother if people don't think it's a good idea.
Post 22 Jan 2010, 13:00
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: 20454
Location: In your JS exploiting you and your system
revolution 22 Jan 2010, 13:51
f0dder wrote:
Ie, instead of the rept and match trick above, you would either use irp or a forward block to do ".count equ .count + 4" (gathering up the symbolic string above). Then, you'd do...
extrn '__imp__'#func'A@'#§.count as func:dword (assuming § is used for evalute-equate-and-replace). Wouldn't that be a lot nicer syntax and effort-wise? Smile
Sure, looks fine except that I don't have a "§" key on my keyboard Confused
f0dder wrote:
... are the nesting-slashes necessary inside the match block? Or are you adding them just for good measures?
The only slashes you can eliminate are the ones preceding the open curly brackets ({), I put those for good measure to remind me how deep we are in the rabbit hole. Notice that `func has no leading backslash but `p does. That is important. The func must be replaced by the outer macro and the p must be replaced by the inner match. The #'s must not concatenate too early so you need the backslashes there also.
Post 22 Jan 2010, 13:51
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:  
Goto page 1, 2  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.