News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Creating a DLL with forwarded functions

Started by Vortex, October 02, 2006, 01:15:09 PM

Previous topic - Next topic

Vortex

Here is an attempt to make a DLL with forwarded functions. fwdfunctions.dll exports two functions forwarded to Console.dll

fwdfuncs.inc :

Cls     PROTO           ; forwarded to Console.ClearScreen
ConOut  PROTO :DWORD    ; forwarded to Console.StdOut
szUpper PROTO :DWORD


fwdfuncs.def :

LIBRARY fwdfuncs
EXPORTS

szUpper
ConOut=Console.StdOut
Cls=Console.ClearScreen


Forwarding functions to another DLL is easy, create dummy procedure declarations with the original function names.

fwdfuncs.asm :


.code

LibMain     PROC instance:DWORD,reason:DWORD,unused:DWORD

    mov eax,1
    ret

LibMain     ENDP

.
.
.

ClearScreen PROC                ; forwarded to Console.ClearScreen
ClearScreen ENDP

StdOut      PROC lpszText:DWORD ; forwarded to Console.StdOut
StdOut      ENDP

END LibMain


A demo project calling forwarded functions :


.386
.model flat,stdcall
option casemap:none

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     fwdfuncs.inc

includelib \masm32\lib\kernel32.lib
includelib fwdfuncs.lib

.data
message     db 'Hello from the forwarded function',0
function    db 'ConOut',13,10,0

.code

start:

    invoke  Cls                     ; forwarded to Console.ClearScreen
    invoke  szUpper,ADDR message
    mov     BYTE PTR [function-1],32
    invoke  ConOut,ADDR message     ; forwarded to Console.StdOut
    invoke  ExitProcess,0       

END start

[attachment deleted by admin]

gwapo

Thanks for the information Vortex  :U

This and the the other thing are the ones I'm looking for. The other thing I wanted to know (but afraid to ask is), is, how to export a nameless function (exported by ordinal) in MASM? There, I've already asked it  :toothy

Cheers,

-chris

asmrixstar

im not sure how to export functions only by ordinal but exported functions always output an ordinal.
I wrote a program a while back for killing the exported name in a finished dll.
Ill see if i can dig it out,bear with me.......

Vortex

gwapo,

You are welcome. As asmrixstar said,exported functions can be identified by an ordinal number assaigned by the building process of the DLL.

gwapo

I'm actually doing the same thing as asmrixtar, killing the "name" of the exported function from Export Table (I'm using a tool developed by a friend of mine), but I was wondering if there's actually an easier way to do this? A switch in  MASM maybe, or some kind of tweak in a DEF file?

I'm also wondering what kind of food you guys eat, to gain this level of skills you have :P

Cheers,

-chris

japheth


Hi,

> how to export a nameless function (exported by ordinal) in MASM?

the MS linker understands "NONAME" in the .DEF file:

EXPORTS
MyProc   @1 NONAME

IIRC newer versions of POLINK also accept this.




Vortex


PBrennick

Japheth,
That is really good to know.

I have what may be a dumb question, but I am going to doggedly plod on ahead, anywho.  What would be the purpose of killing the name of an exported function?

Also, I think that although MASM can do the NONAME thing, I do not think that ordinal calling is supported by masm. IIRC, Donkey said something about this as being a good reason to use GOASM instead of MASM.

gwapo,
It is not 'what' we eat but how we eat it.  We eat bits of it by taking bytes although some just nybble away at their food (the finicky eaters, of course).  :cheekygreen:

Paul
The GeneSys Project is available from:
The Repository or My crappy website

japheth

> I have what may be a dumb question, but I am going to doggedly plod on ahead, anywho.  What would be the purpose of killing the name of an exported function?

I have a thing called hx dos extender and one binary of this extender emulates win9x kernel32, which exports some dozen functions just by ordinal. Advantage: you can save a handful of bytes :), and it may be faster.

> I do not think that ordinal calling is supported by masm

This is more a linker/library issue. IIRC the functions of OLEAUT32 and some other libs are usually linked by ordinal, or at least this was the case in the "good old days". As far as MASM is involved, it of course can call GetProcAddress with a number instead of a string as second parameter, which will then be kind of "dynamically link by ordinal".

Regards

Japheth



hutch--

Here is a simple example of making a DLL by ordinal. I have used LoadLibrary/GetProcAddress which works fine but vaguely I remember there being a method of loading it at app start rather than dynamically but I forget how its done.

[attachment deleted by admin]
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jorgon


QuoteAlso, I think that although MASM can do the NONAME thing, I do not think that ordinal calling is supported by masm. IIRC, Donkey said something about this as being a good reason to use GOASM instead of MASM.

For the sake of completeness for those of you who from time to time may use the Go tools, here is a reminder about the GoAsm and GoLink syntax which applies:-

CALL MyDll:6              ;example of import by ordinal from DLL
CALL Main.exe:15          ;example of import by ordinal from an EXE (DLL calling a function in an EXE)



EXPORTS CALCULATE:2, DATA_VALUE:6       ;in the assembler source file, list the exports by ordinal like this
;
EXPORT:2 CALCULATE:                     ;alternatively you can declare the ordinal at the function's code label
                   ;code goes here
RET


To hide the name, use

EXPORT:2:NONAME
CALCULATE:
                   ;code goes here
RET


Here the value of the code label CALCULATE will be exported as ordinal number 2, but the name of the export will not appear in the final executable. This means that if another program tried to call the CALCULATE function it would fail. The function can only be called by ordinal.

You can also use GoAsm and GoLink to import and export pointers to data.  See the GoAsm help file for that.
Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)

Vortex

Jorgon,

Thanks for the info. You wrote :

;example of import by ordinal from an EXE (DLL calling a function in an EXE)

How do you build an executable exporting functions like a DLL? Is it possible to do this with any assembler?

hutch--

making the DLL is the easy part, its done in the DEF file with this,


LIBRARY testdll
EXPORTS
  func1 @1  NONAME
  func2 @2  NONAME
  func3 @3  NONAME


I knew there was a way of doing it but I have not played with this stuff for a long time. It involves getting the imports from the library that is created with the DLL and using the name with a single leading underscore removed.


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    includelib testdll.lib

    externdef _imp__func1@0:PTR pr0
    func1 equ <_imp__func1@0>

    externdef _imp__func2@0:PTR pr0
    func2 equ <_imp__func2@0>

    externdef _imp__func3@0:PTR pr0
    func3 equ <_imp__func3@0>

    .code

start:
   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    call main
    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

main proc

    call func1
    call func2
    call func3

    ret

main endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Vortex

Quote from: hutch-- on October 07, 2006, 05:40:22 AM
Here is a simple example of making a DLL by ordinal. I have used LoadLibrary/GetProcAddress which works fine but vaguely I remember there being a method of loading it at app start rather than dynamically but I forget how its done.

Hi Hutch,

I didn't see that method but I guess it should operate similar to InitCommonControls, the load-time initializer. Here is my demo.

.386
.model flat, stdcall
option casemap :none

include             \masm32\include\windows.inc
include             \masm32\include\kernel32.inc
includelib         \masm32\lib\kernel32.lib
includelib         console.lib

InitLoadTimeDynLink PROTO

.data
library             db 'Console.dll',0
message             db 'Hello from function with ordinal number 3',13,10,0

.code

start:
    invoke  GetModuleHandle,ADDR library
    invoke  GetProcAddress,eax,3        ; Ordinal number of the "NONAME StdOut" function
                                        ; exported by Console.dll
    invoke  pr1 PTR eax,ADDR message    ; eax holds the address of the function
    invoke  ExitProcess,0
    invoke  InitLoadTimeDynLink         ; dummy function to enable Load-time dynamic linking
                                        ; This function works like InitCommonControls
END start


We could define an equate to improve the readability of the source code :

StdOut EQU <pr1 PTR eax>

InitLoadTimeDynLink PROC    ; dummy function operating like InitCommonControls

    ret

InitLoadTimeDynLink ENDP


Console.def :

LIBRARY console
EXPORTS

StrLen @1 NONAME
locate @2 NONAME
StdOut @3 NONAME
ClearScreen @4 NONAME
InitLoadTimeDynLink

[attachment deleted by admin]

jorgon

Hi Vortex

QuoteHow do you build an executable exporting functions like a DLL? Is it possible to do this with any assembler?

I don't know.  It probably depends more on the linker.  GoLink is capable of putting the export information in the EXE in the same way as a DLL.  Its the same PE format.  The "Go" test programme Testbug demonstrates this.
Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)