Discussion:
MASM: How to statically import a DLL function by ordical?
(too old to reply)
JJ
2018-05-29 20:03:33 UTC
Permalink
Instead of by function name.

If it's not possible using ML or LINK, is there a tool to convert name
imports to ordinal imports?
R.Wieser
2018-05-30 07:39:15 UTC
Permalink
JJ,
How to statically import a DLL function by ordical?
The way I found it to be done is provide a .DEF file to the linker , in
which you mention which names are supposed to be bound to which ordinal
positions. Like this:

WS2_32.DEF
- - - - - - - -
LIBRARY WS2_32.dll

EXPORTS
accept @1
bind @2
closesocket @3
(etcetera)
- - - - - - - -

I'm not sure if it works the same for ML or LINK though.

Regards,
Rudy Wieser
JJ
2018-05-30 12:54:02 UTC
Permalink
Post by R.Wieser
JJ,
How to statically import a DLL function by ordical?
The way I found it to be done is provide a .DEF file to the linker , in
which you mention which names are supposed to be bound to which ordinal
WS2_32.DEF
- - - - - - - -
LIBRARY WS2_32.dll
EXPORTS
(etcetera)
- - - - - - - -
I'm not sure if it works the same for ML or LINK though.
Regards,
Rudy Wieser
The only related LINK option I've found is the /DEF:file.def option, but
it's for defining what functions are exported by the main module.
R.Wieser
2018-05-30 13:24:02 UTC
Permalink
JJ,
Post by JJ
The only related LINK option I've found is the /DEF:file.def option,
but it's for defining what functions are exported by the main module.
Although I thought that was what you wanted to do (I misread), AFAIK you can
do the above as well. It than supplements the "by name" imports a LIB file
offers (but can also fully replace it) (it also allows you create alternate
names for existing "by name" entries).

Another (better im(ns)ho) solution would be to create a new LIB file, by
using (something like) IMPLIB.EXE provinding it the DLL as well as the DEF
file. With that new LIB file you than can refer to the (erstwhile) "by
ordinal only" entries by the names as specified in that DEF file.

Ofcourse, you can also retrieve the address for an ordinal entry dynamically
(using GetProcAddress). But I would not advice that for normal usage
(cumbersome).

Regards,
Rudy Wieser
JJ
2018-05-31 18:56:12 UTC
Permalink
Post by R.Wieser
Another (better im(ns)ho) solution would be to create a new LIB file, by
using (something like) IMPLIB.EXE provinding it the DLL as well as the DEF
file. With that new LIB file you than can refer to the (erstwhile) "by
ordinal only" entries by the names as specified in that DEF file.
OK. I've managed to get the program to import the functions by ordinal.

I noticed that the Microsoft SDK import library files have the function
names appended with the argument size. e.g. "***@4". I know that DLL
files don't have the information that specifies the size of function
arguments. So, how did Microsoft made those LIB files? Did they typed them
manually into the DEF files? Or is there a Microsoft equivalent of Borland's
IMPDEF? Which does more such as accepting a C header file in order to
retrieve function argument sizes.
Post by R.Wieser
Ofcourse, you can also retrieve the address for an ordinal entry dynamically
(using GetProcAddress). But I would not advice that for normal usage
(cumbersome).
That's true. Moreover, I needed to import by ordinal in order to minimize
the file size. It's for tiny programs which are not bigger than 4KB, so
every byte matters. Without using any EXE compressor.
Kaz Kylheku
2018-05-31 19:51:01 UTC
Permalink
Post by JJ
the file size. It's for tiny programs which are not bigger than 4KB, so
every byte matters. Without using any EXE compressor.
So it goes without saying that the only place you can get help is Usnenet.
R.Wieser
2018-05-31 20:30:13 UTC
Permalink
JJ,
Post by JJ
I noticed that the Microsoft SDK import library files have the
function names appended with the argument size. e.g.
Yep. The so-called "mangled (function) names".
Post by JJ
I know that DLL files don't have the information that specifies
the size of function arguments.
No, not as a seperate section. But if you look in such DLLs (exported
functions) you can see that those mangled names are being used for the
functions themselves.
Post by JJ
So, how did Microsoft made those LIB files? Did they typed them
manually into the DEF files?
Probably exactly the same way you make yours: by providing the DLL as an
argument to IMPLIB (or an MS equivalent), and let it extract the mangled
names from there and subsequently stuff them into the LIB file.

At least, that is what IMPLIB does for me (but which I can't use, because my
assembler does not accept the mangled function names, and I have to create a
DEF file to "rename" them, and from that generate a new LIB)
Post by JJ
Or is there a Microsoft equivalent of Borland's IMPDEF?
Probably (never looked for it though, so I'm not sure). But you do not
need to go the DEF file way. IMPLIB can generate a LIB directly from the
DLL. And IIRC you can even tell the importing process to return ordinals
only (doing a translation from function name to ordinal by way of the LIB
file)
Post by JJ
Which does more such as accepting a C header file in order
to retrieve function argument sizes.
You give MS to much credit I'm afraid. :-)

You *cannot* retrieve that argument data (type, size) from anywhere else
than the sourcefile the program (DLL) is created from. After that (in the
resulting machine code - the DLL) all that info is gone. But for in the
mangled function names ofcourse.

Though there might be a possibility that a program/DLL is created with
simple (non-mangled) function names, and that a preparser generates the
actually used mangled ones from the simple names and what it can parse from
the functions argument declaration. Who knows (I don't) :-)
Post by JJ
It's for tiny programs which are not bigger than 4KB, so every byte
matters.
:-)

If that is what you want to do, why don't you come over to the dark side and
write some Assembly, instead of that foul white-wizzards (rather wastefull)
C{something} ? :-D

By the way, I just thought of something: IIRC I can force my linker to
import everything by ordinal. Maybe your compiler can do the same ? That
way you do not even need to bother with recreating LIBs ...

Though I hope you are aware that you would bump into problems when DLLs on
different versions of Windows carry the functions with the same names, but
at different ordinals (as I've seen with W98se and XP).

Regards,
Rudy Wieser
JJ
2018-06-01 09:15:35 UTC
Permalink
Post by R.Wieser
JJ,
Post by JJ
I noticed that the Microsoft SDK import library files have the
function names appended with the argument size. e.g.
Yep. The so-called "mangled (function) names".
Post by JJ
I know that DLL files don't have the information that specifies
the size of function arguments.
No, not as a seperate section. But if you look in such DLLs (exported
functions) you can see that those mangled names are being used for the
functions themselves.
Most Windows API (flat) function names (such as ExitProcess) in the DLL are
not mangled. And since I use the INVOKE directive to call the imported
function, that directive uses function names appended with argument size -
as defined by the PROTO directive. I could use the primitive CALL
instruction to call the function so that I don't have to use mangled
function names in the DEF/LIB file, but I'll have to PUSH the function
arguments manually. I was just hoping that INVOKE is a better way to call a
function, but things suggest that I was wrong.
Post by R.Wieser
At least, that is what IMPLIB does for me (but which I can't use, because my
assembler does not accept the mangled function names, and I have to create a
DEF file to "rename" them, and from that generate a new LIB)
Probably (never looked for it though, so I'm not sure). But you do not
need to go the DEF file way. IMPLIB can generate a LIB directly from the
DLL. And IIRC you can even tell the importing process to return ordinals
only (doing a translation from function name to ordinal by way of the LIB
file)
What compiler are using? Cause IIRC, IMPLIB is available only for Borland
compiler.
Post by R.Wieser
You give MS to much credit I'm afraid. :-)
You *cannot* retrieve that argument data (type, size) from anywhere else
than the sourcefile the program (DLL) is created from. After that (in the
resulting machine code - the DLL) all that info is gone. But for in the
mangled function names ofcourse.
Though there might be a possibility that a program/DLL is created with
simple (non-mangled) function names, and that a preparser generates the
actually used mangled ones from the simple names and what it can parse from
the functions argument declaration. Who knows (I don't) :-)
Perhaps it would be easier to create a "builder" script that tries to
compiles a project to retrieve "unsatisfied external symbol" errors and use
that information to create the DEF file and make the LIB file. Then compiles
the project again.
Post by R.Wieser
If that is what you want to do, why don't you come over to the dark side and
write some Assembly, instead of that foul white-wizzards (rather wastefull)
C{something} ? :-D
Too late. I've gone to the dark side before I see the bright side - almost 3
decades ago. >8D
Post by R.Wieser
By the way, I just thought of something: IIRC I can force my linker to
import everything by ordinal. Maybe your compiler can do the same ? That
way you do not even need to bother with recreating LIBs ...
Please do tell. Maybe it's time I stop trying to use what most people use,
and use anything to achieve what I need.
Post by R.Wieser
Though I hope you are aware that you would bump into problems when DLLs on
different versions of Windows carry the functions with the same names, but
at different ordinals (as I've seen with W98se and XP).
I know. I'm being careful of this case.

... and this leads me to another question.
How would you do if you want to mix both by name and by ordinal function
importing? I know that it's possible, because I've seen some applications
linking to (mostly) WSOCK32.DLL functions by both name and ordinal.
R.Wieser
2018-06-01 11:37:33 UTC
Permalink
JJ,
Post by JJ
Most Windows API (flat) function names (such as ExitProcess) in
the DLL are not mangled.
Correct. (I, wrongly, assumed you where talking about C{something}
libraries)
Post by JJ
And since I use the INVOKE directive to call the imported function,
that directive uses function names appended with argument size -
as defined by the PROTO directive.
And that is what the .H (or .INC) files are for: they describe *how* the
functions have to be called (and what kind of result you can expect).
Post by JJ
I could use the primitive CALL instruction to call the function so
that I don't have to use mangled function names in the DEF/LIB
file, but I'll have to PUSH the function arguments manually.
I wanted to go for a plain "no", but I guess it depends on the used
compiler/assembler itself.

For instance, I can call functions (inside my own program or DLLs) without a
PROTO (or in my case, a PROCDESC) in sight anywhere (and have done so for
many years). Though having them means that a compile/assemble time check
on the number and type of arguments can be performed.

But you could always create a .H file yourself for the DLL/LIB in question.
The only problem will than be where you get that "how many arguments does
this function take, what types are they" info from (welcome to my world by
the way. Its what I need to do for every DLL I want to use ...).

Luckily the MSDN has got a wealth of of information in that regard.
Post by JJ
I was just hoping that INVOKE is a better way to call a function,
but things suggest that I was wrong.
No, you're right, it is (see above). It just needs a bit more work to be
able to keep using them.
Post by JJ
What compiler are using? Cause IIRC, IMPLIB is available only for
Borland compiler.
I'm not. I'm using Borlands TASM32 v5 assembler, which was long ago used as
the backend for their C compiler. I bought it as a stand-alone package
though (which includes both IMPLIB and IMPDEF as well as a resource compiler
and other tools - it even included a few books. You know, real paper. :-) )
Post by JJ
Perhaps it would be easier to create a "builder" script that tries to
compiles a project to retrieve "unsatisfied external symbol" errors
and use that information to create the DEF file and make the LIB file.
I don't think that that will be possible. Although you will probably be
able to filter the "huh? I don't recognise this function name" entries from
the error listing, it won't include information to which DLL it expects the
name to be in. And you really need that for the DEF file.

Personally I would, for a "plain" DLL, opt to just generate the LIB file
from the DLL, and than either define the way the function needs to be called
(PROTO / PROCDESC) in the sourcefile itself, or in a (new) .H / .INC file.

But please do remember that the DEF vs LIB is an "or" thing. You can use
both at the same time, but you only *need* one of them (at least, with
Tasm32. YMMV).
Post by JJ
Too late. I've gone to the dark side before I see the bright side -
almost 3 decades ago. >8D
Shucks. Thats what happened to me too (4 decades ago). :-)
Post by JJ
IIRC I can force my linker to import everything by ordinal.
Please do tell. Maybe it's time I stop trying to use what most people
use, and use anything to achieve what I need.
I'm sorry. I just went back and checked. And although the TLINK32 "o" flag
is defined as "Import by ordinals" I could still see, when doing a hexdump,
the DLL function names in all their glory. I must have misunderstood (or
simply forgotten) something there. :-\
Post by JJ
How would you do if you want to mix both by name and by ordinal
function importing?
I don't think its something you can control - from within the sourcecode I
mean. AFAIK its gouverned by the LIB and/or DEF file: if the function name
symbol is linked to a "by ordinal" import that will be used, if its linked
to a "by name" import, than it will be used.

Hmmm ... That makes me wonder: is the above "o" switch maybe ment for a LIB
entry where both a symbol as well as an ordinal entry are available. I'll
have to check that out some day.
Post by JJ
I know that it's possible, because I've seen some applications linking
to (mostly) WSOCK32.DLL functions by both name and ordinal.
True. But thats than caused by the LIB file for WS2_32 than containing
both "by name" and "by ordinal" entries (and your function symbols
referencing them).

Do you have something like TDUMP - to "dump" the contents of a LIB (or DLL)
file with ? You can than see the different entries yourself.

Though I must say that WS2_32.DLL on my machine (XPsp3) does not seem to
contain any "by ordinal only" entries. But that does not mean the LIB could
not be constructed with both though.

Regards,
Rudy Wieser
JJ
2018-06-02 06:10:50 UTC
Permalink
Post by R.Wieser
Luckily the MSDN has got a wealth of of information in that regard.
You wish... They only have minimum documentations on MASM. C/C++ on the
other hand, is abundant.
Post by R.Wieser
No, you're right, it is (see above). It just needs a bit more work to be
able to keep using them.
But the fact that it can only use mangled function name, is a restriction.
Post by R.Wieser
I don't think that that will be possible. Although you will probably be
able to filter the "huh? I don't recognise this function name" entries from
the error listing, it won't include information to which DLL it expects the
name to be in. And you really need that for the DEF file.
Ah, you're right.
Post by R.Wieser
But please do remember that the DEF vs LIB is an "or" thing. You can use
both at the same time, but you only *need* one of them (at least, with
Tasm32. YMMV).
Unfortunately, Microsoft LINK can't use DEF files, in place of LIB files.
Post by R.Wieser
I'm sorry. I just went back and checked. And although the TLINK32 "o" flag
is defined as "Import by ordinals" I could still see, when doing a hexdump,
the DLL function names in all their glory. I must have misunderstood (or
simply forgotten) something there. :-\
I know. I've been there too.
Post by R.Wieser
I don't think its something you can control - from within the sourcecode I
mean. AFAIK its gouverned by the LIB and/or DEF file: if the function name
symbol is linked to a "by ordinal" import that will be used, if its linked
to a "by name" import, than it will be used.
Yes, I've just noticed that.
Post by R.Wieser
Hmmm ... That makes me wonder: is the above "o" switch maybe ment for a LIB
entry where both a symbol as well as an ordinal entry are available. I'll
have to check that out some day.
Do you have something like TDUMP - to "dump" the contents of a LIB (or DLL)
file with ? You can than see the different entries yourself.
For Microsoft import LIB files, each function exports always have both the
function name and ordinal, but there's a flag which indicates whether it's
available by name or ordinal. Not both.
R.Wieser
2018-06-02 08:55:01 UTC
Permalink
JJ,
Post by JJ
Post by R.Wieser
Luckily the MSDN has got a wealth of of information in that regard.
You wish... They only have minimum documentations on MASM. C/C++
on the other hand, is abundant.
I know. They also have zero info in regard to my Borlands Tasm32. :-)

But when given the choice between MSDN pages and pretty-much nothing else
than I think I may call MSDN info rather abundant - especially in regard to
description for functions in the common Windows DLLs.

But yes, I always have to extract information from the available C/C++/other
examples and than re-implement them in Assembly (no simple copy-paste).
I've been doing that for so long that I do not even register that anymore.

Than again, most of my information searches are about how to use a certain
DLL function, and much less about how to solve a problem.
Post by JJ
But the fact that it can only use mangled function name, is a restriction.
I'm not sure from which direction you mean that ...

- Yes, you cannot change the names in the DLL (well, you can. But its
certainly not advicable :-) ).

- No, you are free to come up with your own names, make a DEF file to link
your names to the mangled ones, and than create a LIB file from the DEF.

Now I think of it, it would be best to create a LIB file with a different
name. (the LIB file still points to the right DLL, as it has been provided
at the top of the DEF file).

After that copy the origional .H file to match the above .LIB filename, and
rename the mangled names in it to match the ones in the DEF.

And as a last step import the new LIB and H file instead of, or even along
side the origional ones.

From this point on you have than nothing to do with the mangled function
names anymore.

... or am I missing something here ?

By the way, here is an example of such a "rename" I did (VSSAPI):

DEF file (all on a single line):
- - - - -
CreateVssBackupComponents =
?CreateVssBackupComponents@@YGJPAPAVIVssBackupComponents@@@Z
- - - - -
TDUMP of the entry in the resulting LIB:
- - - - -
0002B0 THEADR CreateVssBackupComponents
0002CE COMENT Purge: Yes, List: Yes, Class: 160 (0A0h)
Dynamic link import (IMPDEF)
Imported by: name
Internal Name: CreateVssBackupComponents
Module Name: VSSAPI.DLL
Imported name:
?CreateVssBackupComponents@@YGJPAPAVIVssBackupComponents@@@Z
000338 MODEND
- - - - -
Post by JJ
Unfortunately, Microsoft LINK can't use DEF files, in place of LIB files.
Well, luckily a LIB is only a single implib step away from a DEF. :-)
Post by JJ
For Microsoft import LIB files, each function exports always have both
the function name and ordinal, but there's a flag which indicates whether
it's available by name or ordinal. Not both.
Bummer.

Although ... Now I think of it it would be a bit silly for a LIB entry to
have both the name as well as the ordinal: The first allows us to use
other versions of the DLL even if the order of the functions in them have
changed, and the latter makes sure we would *not* be able to do so. (also,
remember the warning I gave about using ordinals instead of names ? Yeah,
such a LIB would stumble into that pitfall, and possibly worse. :-( :-) )

Regards,
Rudy Wieser

Loading...