News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Is is possible to export a variable from a dll without using a def file?

Started by xanatose, February 18, 2016, 04:57:29 PM

Previous topic - Next topic

xanatose

A proc can be exported to a dll using the export word
example

MyProc proc export
  xor eax,eax
  ret
MyProc endp


Will be exported  without the need of a module definition file.

Is there any way to do the same with a variable? Something like


g_myGlobal dd ?

public g_myGlobal ; But instead of public, make it to export. export word does not seem to work.


I know that the linker can do it. As I can export variables from C without a problem. Bot do not want to separate the asm variables from its code. And want to avoid using a def file as well.

__declspec(dllexport) int g_myVar;




TWell

With MS link look here
Quote/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]

xanatose

Quote from: TWell on February 18, 2016, 09:50:49 PM
With MS link look here
Quote/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]

I just hoped there was a way to do it directly from the .asm (Just like proc export).

Well at least that allows me to avoid the .def file. Thanks.

jj2007

Quote from: xanatose on February 19, 2016, 01:57:51 PM
I just hoped there was a way to do it directly from the .asm (Just like proc export).

proc export seems not to work for me. How exactly are you doing that? Special options? Can you post an example?

Vortex

Here is my attempt :

ExportSym.asm :

.386
.model flat,stdcall
option casemap:none

.code

start:

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

    mov     eax,1
    ret

LibMain ENDP

variable PROC EXPORT

    dd 1000

variable ENDP

teststring PROC EXPORT

    db 'This is a test.',0

teststring ENDP

END LibMain


Test.asm :

.386
.model flat,stdcall
option casemap:none

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\msvcrt.inc

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\msvcrt.lib
includelib  ExportSym.lib

variable    PROTO                   ; exported by the DLL
teststring  PROTO                   ; exported by the DLL

.data

str1 db 'Exported variable = %u',13,10,0
str2 db 'Exported string = %s',0

.code

start:

    mov     eax,variable
    mov     ecx,DWORD PTR [eax+2]   ; read the jump table of the executable
    mov     edx,DWORD PTR [ecx]     ; read the variable
    inc     DWORD PTR [edx]         ; modify the variable
   
    invoke  crt_printf,ADDR str1,\
            DWORD PTR [edx]

    mov     eax,teststring
    mov     ecx,DWORD PTR [eax+2]
    mov     edx,DWORD PTR [ecx]
    invoke  crt_printf,ADDR str2,edx

    invoke  ExitProcess,0

END start

jj2007

Thanks, Erol :t

Correct me if I am wrong: It seems that with the proc export method, variables get exported in their decorated form, as _somevar@0
When used with the *.lib file, the decoration is not needed, but when used with the *.dll, you need the decoration for the GetProcAddress call.

With the def file, there is no need for decoration.

P.S.: http://stackoverflow.com/questions/1467144/how-do-i-stop-name-mangling-of-my-dlls-exported-function

sinsi

    inc     DWORD PTR [edx]         ; modify the variable
Access violation, can't write to a code segment?

Would it be easier to use the _imp__ version of the export?

jj2007

Quote from: sinsi on February 20, 2016, 04:58:53 PM
Access violation, can't write to a code segment?

Indeed. But you can place the proc in the .data section.

Work in progress:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Dll "MbMicroDll"                 ; the MasmBasic equivalent for LoadLibrary
  Declare MyDwords As DWORD        ; declare variables or arrays defined in the DLL's data section
  Print "An array of dwords:"      ; print an array of three dwords defined in the DLL
  For_ ecx=0 To 2
      Print Chr$(13, 10, "Dw", ecx+"A", "="), Str$("\t%i", MyDwords(ecx))
  Next
EndOfCode


Output:
An array of dwords:
DwA=    111111111
DwB=    222222222
DwC=    333333333

Vortex

Quote from: jj2007 on February 20, 2016, 02:46:22 PM
Thanks, Erol :t

Correct me if I am wrong: It seems that with the proc export method, variables get exported in their decorated form, as _somevar@0
When used with the *.lib file, the decoration is not needed, but when used with the *.dll, you need the decoration for the GetProcAddress call.

With the def file, there is no need for decoration.

P.S.: http://stackoverflow.com/questions/1467144/how-do-i-stop-name-mangling-of-my-dlls-exported-function

Hello Jochen,

Exactly. There are decorated symbols in the DLL :


\masm32\bin\dumpbin.exe /EXPORTS ExportSym.dll

Microsoft (R) COFF Binary File Dumper Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file ExportSym.dll

File Type: DLL

  Section contains the following exports for ExportSym.dll

           0 characteristics
    56C77DCE time date stamp Fri Feb 19 22:40:46 2016
        0.00 version
           1 ordinal base
           3 number of functions
           3 number of names

    ordinal hint RVA      name

          1    0 00002000 _LibMain@12
          2    1 00002010 _teststring@0
          3    2 0000200C _variable@0



Vortex

Quote from: sinsi on February 20, 2016, 04:58:53 PM
    inc     DWORD PTR [edx]         ; modify the variable
Access violation, can't write to a code segment?

Would it be easier to use the _imp__ version of the export?

Hello sinsi,

To avoid the access violation, the characteristics of the code section can be modified, you can check my attachment above :

\masm32\bin\ml /c /coff ExportSym.asm
\masm32\bin\polink /SUBSYSTEM:WINDOWS /DLL /SECTION:.text,ERW ExportSym.obj


The code section is now executable, readable and writeable.

Vortex

Solving the decorated symbols problem :

The functions can be exported as SYSCALL :

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

    mov     eax,1
    ret

LibMain ENDP

variable PROC SYSCALL EXPORT

    dd 1000

variable ENDP

teststring PROC SYSCALL EXPORT

    db 'This is a test.',0

teststring ENDP

END LibMain


Testing the DLL :

.data

library db 'ExportSym.dll',0
var1    db 'variable',0
str1    db 'Exported variable = %u',13,10,0
str2    db 'Exported string = %s',0
str3    db 'teststring',0

.data?

hDLL    dd ?

.code

start:
   
    invoke  LoadLibrary,ADDR library
    mov     hDLL,eax

    invoke  GetProcAddress,eax,ADDR var1

    inc     DWORD PTR [eax]         ; modify the variable
   
    invoke  crt_printf,ADDR str1,\
            DWORD PTR [eax]

    invoke  GetProcAddress,hDLL,ADDR str3

    invoke  crt_printf,ADDR str2,eax

    invoke  FreeLibrary,hDLL

    invoke  ExitProcess,0



dedndave

i think the best solution is to use a DEF file
i know - you didn't want to hear that