Redirecting data to a DLL

I need to forward the character set from one DLL to another (to support some PEP 384 version control scheme if you're interested). It works great for functions; I am writing a module definition file saying

LIBRARY "python3"
EXPORTS
  PyArg_Parse=python32.PyArg_Parse
  PyArg_ParseTuple=python32.PyArg_ParseTuple
  PyArg_ParseTupleAndKeywords=python32.PyArg_ParseTupleAndKeywords
[...]

However, it does not work for data. If i say

PyBaseObject_Type=python32.PyBaseObject_Type

then the linker complains that PyBaseObject_Type is an unresolved symbol, although it is actually exported from python32.dll. Looking at the import library, I notice that there is only a symbol for the data _imp__, so I tried

PyBaseObject_Type=python32._imp__PyBaseObject_Type

DLL, DLL _imp__, . DATA ( _imp__); .

IIUC, , __declspec(dllimport) DLL, .

: DLL, ?

+5
4

, DATA DLL (DLL, ).

, , DllDataForward.c:

#include <Windows.h>

EXTERN_C __declspec(dllexport) int myData = 5;

#ifndef _DEBUG
EXTERN_C BOOL WINAPI _DllMainCRTStartup (HINSTANCE hinstDLL, DWORD fdwReason,
                                         LPVOID lpvReserved)
#else
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
#endif
{
    if (fdwReason == DLL_PROCESS_ATTACH)
        DisableThreadLibraryCalls(hinstDLL);

    return TRUE;
    UNREFERENCED_PARAMETER (lpvReserved);
}

EXTERN_C __declspec(dllexport) BOOL WINAPI MyFunc()
{
    return TRUE;
}

DllDataForward.def:

LIBRARY "DllDataForward"
EXPORTS
    myData
    MyFunc

"myData DATA" "myData".

ForwardingDll.c:

#include <Windows.h>

#ifndef _DEBUG
EXTERN_C BOOL WINAPI _DllMainCRTStartup (HINSTANCE hinstDLL, DWORD fdwReason,
                                         LPVOID lpvReserved)
#else
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
#endif
{
    if (fdwReason == DLL_PROCESS_ATTACH)
        DisableThreadLibraryCalls(hinstDLL);

    return TRUE;
    UNREFERENCED_PARAMETER (lpvReserved);
}

ForwardingDll.def:

LIBRARY "ForwardingDll" 
EXPORTS
    myNewData=DllDataForward.myData DATA
    MyNewFunc=DllDataForward.MyFunc

DllDataForward.lib, DllDataForward ForwardingDll.dll. , ForwardingDll.dll.

dumpbin.exe ForwardingDll.dll /EXPORTS

...
    ordinal hint RVA      name

          1    0          MyNewFunc (forwarded to DllDataForward.MyFunc)
          2    1          myNewData (forwarded to DllDataForward.myData)
...

DllDataForward.lib, test.c:

#include <Windows.h>
#include <stdio.h>
#include <tchar.h>

EXTERN_C __declspec(dllimport) int myNewData;
EXTERN_C __declspec(dllimport) BOOL WINAPI MyNewFunc();

int main()
{
    BOOL isSuccess = MyNewFunc();
    int i=myNewData;
    _tprintf (TEXT("i=%d\nisSuccess=%s\n"),
              i, isSuccess? TEXT("TRUE"): TEXT("FALSE"));
}

i=5
isSuccess=TRUE

. "myData DATA" "myData" DEF , DLL, python32.dll - python32.dll . , python32.lib , PyBaseObject_Type. , python32.lib, , .

, "myData DATA" "myData" DEF. DllDataForward.dll DEF, "myData DATA" , DllDataForward.LIB:

dumpbin.exe DllDataForward.lib /all >%TEMP%\DllDataForward-lib.txt
notepad %TEMP%\DllDataForward-lib.txt

, lib 6 :

  224 __IMPORT_DESCRIPTOR_DllDataForward
  46A __NULL_IMPORT_DESCRIPTOR
  5A8 DllDataForward_NULL_THUNK_DATA
  776 __imp__myData
  708 _MyFunc@0
  708 __imp__MyFunc@0

DEF "myData DATA" "myData", dll . , 7 (!!!) 6 :

  23A __IMPORT_DESCRIPTOR_DllDataForward
  480 __NULL_IMPORT_DESCRIPTOR
  5BE DllDataForward_NULL_THUNK_DATA
  78C __imp__myData
  78C _myData
  71E _MyFunc@0
  71E __imp__MyFunc@0

, DEF "myData DATA" , _myData.

DLL, "myData DATA" , , _myData . DllDataForward.dll, lib .

, DllDataForward.dll dumpbin.exe DllDataForward.dll /exports. :

...
    ordinal hint RVA      name

          1    0 00001020 MyFunc = _MyFunc@0
          2    1 00003000 myData = _myData
...

new DllDataForward.def , dumpbin.exe DllDataForward.dll /exports:

LIBRARY "DllDataForward"
EXPORTS
    myData = _myData

,

lib.exe /DEF:DllDataForward.def /OUT:DllDataForward.lib /MACHINE:X86

DllDataForward.lib ( - DllDataForward.lib). ForwardingDll.dll DllDataForward.lib DLL. Test.exe , .

python32.lib 3.2a3:

dumpbin.exe "C:\Program Files\Python32\libs\python32.lib" /all >python32-lib.txt
notepad python32-lib.txt

( )

1957 public symbols

1BCCC _PyArg_Parse
1BCCC __imp__PyArg_Parse

1BFF6 __imp__PyBaseObject_Type

dumpbin C:\Windows\system32\python32.dll /exports >%TEMP%\python32-exports.txt
notepad %TEMP%\python32-exports.txt

PyBaseObject_Type

 14    D 001DD5D0 PyBaseObject_Type

, python32.lib python32.def

LIBRARY "python32"
EXPORTS
    PyBaseObject_Type

lib /DEF:python32.def /OUT:python32.lib /MACHINE:X86

DEF DLL

LIBRARY "python3"
EXPORTS
  PyArg_Parse=python32.PyArg_Parse
  PyArg_ParseTuple=python32.PyArg_ParseTuple
  PyArg_ParseTupleAndKeywords=python32.PyArg_ParseTupleAndKeywords
  PyBaseObject_Type=python32.PyBaseObject_Type DATA

, , "C:\Program Files\Python32\libs\python32.lib" python32.lib, .

python PyBaseObject_Type, int

EXTERN_C __declspec(dllimport) int PyBaseObject_Type;

, PyBaseObject_Type 1. !

, .

+6

, .def. DLL:

#pragma comment(linker,"/export:_data=org.data,DATA")
#pragma comment(linker,"/export:_func=org.func")

. .

:

org.c

int data = 5;
int func(int a)
{
    return a * 2;
}

org.def

EXPORTS
    data DATA
    func

fwd.c

#pragma comment(linker,"/export:_data=org.data,DATA")
#pragma comment(linker,"/export:_func=org.func")

int func2(int a)
{
    return a + 2;
}

fwd.def

EXPORTS
    func2

example.c

#include <stdio.h>

__declspec(dllimport) int data;
__declspec(dllimport) int func(int a);
__declspec(dllimport) int func2(int a);

int main()
{
    printf("data=%d func(5)=%d func2(5)=%d\n",data,func(5),func2(5));
    return 0;
}

Makefile

all: example.exe org.dll

example.exe: example.c fwd.dll
    cl /W4 example.c /link fwd.lib

org.dll: org.c
    cl /LD /W4 org.c org.def

fwd.dll: fwd.c
    cl /LD /W4 fwd.c fwd.def

clean:
    del *.exe *.dll *.obj *.exp *.lib
+2

, .def __stdcall, . , stdcall = /export. fancier #include "fwd.h", DLL EXE.

org.c

#define ORGAPI __declspec(dllexport)

ORGAPI int data = 5;
ORGAPI int __stdcall func(int a)
{
    return a * 2;
}

fwd.c

#define FWDEXPORTS
#include "fwd.h"

int func2(int a)
{
    return a + 2;
}

fwd.h

#pragma once

#ifdef FWDEXPORTS
    #define FWDAPI __declspec(dllexport)
    // forwarded APIs exported here
    #pragma comment(linker,"/export:_func@4=org._func@4")
    #pragma comment(linker,"/export:_data=org.data")
#else
    #define FWDAPI __declspec(dllimport)
    // forwarded APIs imported here
    FWDAPI int __stdcall func(int a);
    FWDAPI int data;
#endif

// APIs unique to forwarding DLL here
FWDAPI int func2(int a);

example.c

#include <stdio.h>
#include "fwd.h"

int main()
{
    printf("data=%d func(5)=%d func2(5)=%d\n",data,func(5),func2(5));
    return 0;
}

Makefile

all: example.exe org.dll

example.exe: example.c fwd.h fwd.dll
   cl /nologo /W4 example.c /link /nologo fwd.lib

org.dll: org.c
    cl /nologo /LD /W4 org.c /link /nologo

fwd.dll: fwd.c fwd.h
    cl /nologo /LD /W4 fwd.c /link /nologo

clean:
    del *.exe *.dll *.obj *.exp *.lib
0

MS linker. 2 .

. DLL , imp__FooBar, FooBar - . __declspec (dllimport), __imp * ( dword ptr [ imp__FooBar]) . ​​ dllimport, , _imp. , ( "FooBar: jmp dword ptr [_imp__FooBar]" ). x86 , , stdcall, .

: , . , DLL dll . , DLL, , . dll. , FooBar, _imp_FooBar, , , - "" .

2 . : , . , jmp, . - , , . , dll.

The second solution does not even require the creation of an import library and may be easier in some cases. You just add the character to your dll forwarding. It can be any character. "char FooBar;" enough. When your export file contains "FooBar = otherdll.FooBar DATA", the dll will have an export of FooBar, which is redirected to otherdll.dll, the character in the forwardng dll will not be used.

0
source

All Articles