The MASM Forum

Projects => Poasm => Pelle's C compiler and tools => Topic started by: Vortex on June 07, 2014, 07:07:01 PM

Title: Functions exported by ordinals
Post by: Vortex on June 07, 2014, 07:07:01 PM
Here is a quick example :

#include <windows.h>
#include <stdio.h>

int main(int argc,char *argv[])

{
HMODULE hModule;

// define the function pointer to call the function #2

int __stdcall (*Sum)(int,int);

hModule=LoadLibrary("DllDemo.dll");

// Get the address of the function identified by ordinal number 2

Sum=(void *)GetProcAddress(hModule,MAKEINTRESOURCE(2));

// Simple test

printf("90 + 10 = %d",Sum(90,10));

FreeLibrary(hModule);

return 0;
}


DllDemo.def :

LIBRARY DllDemo
EXPORTS
Difference @1 NONAME
Sum @2 NONAME
Multiply @3 NONAME
Square @4 NONAME

Title: Re: Functions exported by ordinals
Post by: Gunther on June 07, 2014, 08:19:30 PM
Thank you Erol for the instructive example. Will that work with other compilers, too?

Gunther

Title: Re: Functions exported by ordinals
Post by: Vortex on June 07, 2014, 08:54:32 PM
Hi Gunther,

Second version built with Microsoft Visual C++ Toolkit 2003 and Server 2003 R2 PSDK. The only difference is the declaration of the function pointer :

int (__stdcall *Sum)(int,int);
Title: Re: Functions exported by ordinals
Post by: Gunther on June 07, 2014, 09:21:23 PM
 :t Is clear now.

Gunther
Title: Re: Functions exported by ordinals
Post by: MichaelW on June 07, 2014, 09:41:10 PM
After changing the function declaration and renaming dllmain.c to dlldemo.c, and building with the VC++ Toolkit 2003 compiler and this batch file:

set PATH=C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin;%PATH%

set INCLUDE=C:\Program Files\Microsoft Platform SDK\include;C:\Program Files\Microsoft Visual C++ Toolkit 2003\include;%INCLUDE%

set LIB=C:\Program Files\Microsoft Platform SDK\lib;C:\Program Files\Microsoft Visual C++ Toolkit 2003\lib;C:\masm32\lib;%LIB%

cl /W3 /FA /c dlldemo.c

pause

link /DLL /DEF:dlldemo.def dlldemo.obj

pause

cl /W3 /FA CallByOrdinal.c DllDemo.lib

pause


The assembly output shows that the exported functions are using cdecl:

; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077

TITLE dlldemo.c
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
$$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif

INCLUDELIB LIBC
INCLUDELIB OLDNAMES

PUBLIC _DllMain@12
; Function compile flags: /Odt
_TEXT SEGMENT
_hInstDLL$ = 8 ; size = 4
_fdwReason$ = 12 ; size = 4
_lpvReserved$ = 16 ; size = 4
_DllMain@12 PROC NEAR
; File c:\program files\microsoft visual c++ toolkit 2003\my\vortex\callbyordinal\dlldemo.c
; Line 5
push ebp
mov ebp, esp
; Line 6
mov eax, 1
; Line 7
pop ebp
ret 12 ; 0000000cH
_DllMain@12 ENDP
_TEXT ENDS
PUBLIC _Sum
; Function compile flags: /Odt
_TEXT SEGMENT
_a$ = 8 ; size = 4
_b$ = 12 ; size = 4
_Sum PROC NEAR
; Line 10
push ebp
mov ebp, esp
; Line 11
mov eax, DWORD PTR _a$[ebp]
add eax, DWORD PTR _b$[ebp]
; Line 12
pop ebp
ret 0
_Sum ENDP
_TEXT ENDS
PUBLIC _Difference
; Function compile flags: /Odt
_TEXT SEGMENT
_a$ = 8 ; size = 4
_b$ = 12 ; size = 4
_Difference PROC NEAR
; Line 15
push ebp
mov ebp, esp
; Line 16
mov eax, DWORD PTR _a$[ebp]
sub eax, DWORD PTR _b$[ebp]
; Line 17
pop ebp
ret 0
_Difference ENDP
_TEXT ENDS
PUBLIC _Multiply
; Function compile flags: /Odt
_TEXT SEGMENT
_a$ = 8 ; size = 4
_b$ = 12 ; size = 4
_Multiply PROC NEAR
; Line 20
push ebp
mov ebp, esp
; Line 21
mov eax, DWORD PTR _a$[ebp]
imul eax, DWORD PTR _b$[ebp]
; Line 22
pop ebp
ret 0
_Multiply ENDP
_TEXT ENDS
PUBLIC _Square
; Function compile flags: /Odt
_TEXT SEGMENT
_a$ = 8 ; size = 4
_Square PROC NEAR
; Line 25
push ebp
mov ebp, esp
; Line 26
mov eax, DWORD PTR _a$[ebp]
imul eax, DWORD PTR _a$[ebp]
; Line 27
pop ebp
ret 0
_Square ENDP
_TEXT ENDS
PUBLIC _func
; Function compile flags: /Odt
_TEXT SEGMENT
_a$ = 8 ; size = 4
_b$ = 12 ; size = 4
_func PROC NEAR
; Line 30
push ebp
mov ebp, esp
; Line 31
mov eax, DWORD PTR _a$[ebp]
mov ecx, DWORD PTR _b$[ebp]
lea eax, DWORD PTR [ecx+eax*2]
; Line 32
pop ebp
ret 0
_func ENDP
_TEXT ENDS
END


Is there a way to link with the import library and call a function by ordinal, without GetProcAddress?
Title: Re: Functions exported by ordinals
Post by: jj2007 on June 08, 2014, 12:46:56 AM
Nice example, Erol :t

Here is the assembler equivalent - requires version 7 June or later (http://masm32.com/board/index.php?topic=94.0) ;)

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Dll "DllDemo.dll"
  Declare #2=TheSum, 2
  Inkey Str$("90+10=%i", TheSum(90, 10))
  Exit
end start


(actually, when trying this, it choked; the VB style ordinal option has been included a long time ago, but I've never used it, and a regression crept in :(... but now it works)

Note you can use any alias name, like MySum etc; if you try TheSum(90, 10, 123) or The Sum(90), the macro will throw an assembly time error message explaining that TheSum expects exactly 2 parameters.

Quote from: MichaelW on June 07, 2014, 09:41:10 PM
The assembly output shows that the exported functions are using cdecl
The DemoDll.dll in Erol's attachment uses stdcall. If it was cdecl, the syntax above would change to Declare #2=TheSum, C:2
Title: Re: Functions exported by ordinals
Post by: Vortex on June 08, 2014, 02:36:47 AM
Hi Jochen,

Thanks for your kind words. By the way, my fault was not specify the correct calling convention __stdcall. I corrected this:

#ifndef WINAPI
#define WINAPI  __stdcall
#endif
.
.
.
int WINAPI Sum(int a, int b)
{
    return a+b;
}


No need of GetProcAddress now :


extern int __stdcall Sum(int x,int y);

int main(int argc,char *argv[])

{
printf("90 + 10 = %d",Sum(90,10));

return 0;
}


New upload at the top.