 |
|
 |
Thanks for the tip. I manage to find it out.
First you need to create a .LIB from the original DLL
LIB /MACHINE:X86 /DEF:original.def
where original.def goes something like this
LIBRARY original
EXPORTS
ExpFunc1 @1 NONAME
ExpFunc2 @2 NONAME
...
WlxShutdown @48
WlxStartApplication @49
WlxWkstaLockedSAS @50
Then you need to create a forwarding .def file which goes into your project and goes something like this
LIBRARY stub
EXPORTS
ExpFunc1=original.@1 @1 NONAME
ExpFunc2=original.@2 @2 NONAME
...
WlxShutdown=original.WlxShutdown @48
WlxStartApplication=original.WlxStartApplication @49
WlxWkstaLockedSAS=original.WlxWkstaLockedSAS @50
Also, link the LIB file which you have created previously.
Thats all.
|
|
|
|
 |
|
 |
If this works, I will change my article so all inline assembly can be avoided.
M.X.
|
|
|
|
 |
|
 |
Would you send me your test project ?
xmic@freemail.gr
Because I am doing something wrong and the result DLL doesn't export anything.
M.C.
|
|
|
|
 |
|
 |
Never/Mind ; Found it.
I am about to start a new article for this technique.
M.C.
|
|
|
|
 |
|
 |
I haven't tried it throughly yet. I tried for to stub a DLL for WM5 on ARM processor, but it seemed to crash my whole PDA when i tried to stub a dll that was called upon boot time. Not sure if my command line to stub an ARM processor dll was wrong or stubbing that will work on my PDA.
Hope it works for you.
|
|
|
|
 |
|
 |
Hi,
For one specific DLL I've found that dumpbin /exports generates something like this:
...
112 61 0007E0E9 Init3
14 62 0000C11B Init@4
...
Wrapit then generates such def file part:
Init3=__E__97__ @112
Init@4=__E__98__ @14
and when I later compile everything and do dumpbin on resulting proxy DLL - I get:
14 60 0000125D Init
112 62 00001262 Init3
Not sure if it's correct, i.e. name is different from initial one.
Btw, when copying back that proxy dll with original dll rename what I get is "The specified procedure could not be found" message. Is it possible somehow to debug from inside proxy dll what procedure address calling process tries to obtain and fails?
|
|
|
|
 |
|
 |
Hi.
Since the .def file is correct, that must be a compiler problem.
Perhaps the compiler don't accept functions containing @ , because this character is probably reserved for function name mangling.
Obviously since the target DLL has a different function than the proxy dll, you cannot expect the proxy dll to work.
Is there an option for the compiler to accept such a character in the function name ?
|
|
|
|
 |
|
 |
link.exe only allows mangled names to be exported if you point it at a mangled name. I guess if it doesn't find an @ in the target name, it assumes the function is a C function and strips off everything after the @.
Ex:
__declspec(naked) void __stdcall decorated3() { }
If you use "mangled@4=decorated3" in your .def, the function will be exported as mangled. If you use "mangled@4=?decorated3@@YGXXZ", it's exported as mangled@4.
Unfortunately, if you want to extend decorated3, you have to either update the .def file with the new mangled name, or have decorated3 jump to the function you extend so the name mangling stays intact.
|
|
|
|
 |
|
 |
I test it,but it shows "can't find ?terminate@@YAXXZ",why?
|
|
|
|
 |
|
 |
Perhaps it is a function with weird name in the dll ; try putting it manually in the .def file.
|
|
|
|
 |
|
 |
But I find no errors during the code from .def file,It just the same as "dumpin",why?Thank you.
|
|
|
|
 |
|
 |
Could you mail me that particular version of this DLL ?
xmic@freemail.gr
and I will test it as soon as I return back home this weekend.
|
|
|
|
 |
|
 |
Rather than "manually" fixup all of the proxied functions with GetProcAddress() calls, you can do this (for each function whose behavior you are not modifying):
#pragma comment(linker, "/EXPORT:WhateverFunction=realDLLnamePrefix.WhateverFunction")
It's more concise to do it this way.
|
|
|
|
 |
|
 |
Interesting, would it work with all compilers ?
|
|
|
|
 |
|
 |
No, since a #pragma statement is compiler-specific, but the same idea can work in a .DEF file.
EXPORTS
SomeFunction=kernel32.SomeFunction
That would export "SomeFunction" from your DLL but when your DLL was loaded the Windows loader would put in the address of SomeFunction() in kernel32.dll, instead.
The only way it won't work is by using __declspec(dllexport) because C++ will change the export
function name if you do that (name decoration, I think?).
|
|
|
|
 |
|
 |
This works in theory, but in practise, VC wouldn't accept such an exports section. Says unresolved external messages.
Did it work for you ?
|
|
|
|
 |
|
 |
Yes, that syntax works for me. I am using Visual Studio (C++) 2005. I built a Win32 project, of type DLL, and created a module definition file (.def). Without actually defining any functions in my DLL, I added a line to the .DEF file, so the whole thing looked like this:
LIBRARY "Export_forwarding"
EXPORTS
Beeper=KERNEL32.Beep
Then I created a test application which did a quick LoadLibary() on this DLL and a GetProcAddress(..., "Beeper"). The GetProcAddress() routine returns the address of Beep() in kernel32.dll. I tested too that it could be called successfully using this address.
|
|
|
|
 |
|
 |
Hello
It is a handy tool and actually I've been meaning to do something like that, but you saved my day!
Regards,
Elias
|
|
|
|
 |
|
 |
I have several exports in teh def file that have an @@ in the name.
When I compile the proxy the linker in VC 6.0 removes the @@ (and the data after the @@) from the dll's exports.
One other writer has had this problem. Anybody have any ideas?
|
|
|
|
 |
|
|
 |
|
 |
I made my XP SP2 proxy and works well as a firewall.
But what about Vista. I tried the same technique but it doesn't seem to work.
Anyone works in it ?
Thanks.
|
|
|
|
 |
|
 |
I used the above code to make a proxy dll for wsock32.dll
the default proxy dll works fine but until i try manipulating parameters
in this case im trying to manipulate the send function.
according to MSDN ( http://msdn2.microsoft.com/en-us/library/ms740149.aspx) :
int send(
SOCKET s,
const char* buf,
int len,
int flags
);
i replaces the default forward:
//Default send
extern "C" __declspec(naked) void __stdcall __E__69__()
{
__asm
{
jmp p[69*4];
}
}
With:
//Manipulable send
extern "C" void __stdcall __E__69__( SOCKET s, const char* buf, int len, int flags )
{
// Processing
MessageBeep( -1 );
// Call original func
typedef void (*__stdcall ps)( SOCKET, const char* , int , int);
ps PX = (ps)p[69*4];
PX( s, buf, len, flags);
return;
}
Compiles with the following warning:
.\wsock32.cpp(752) : warning C4229: anachronism used : modifiers on data are ignored
when using the proxy dll on my application, i get an access violation like this:
------------------------------------------------------------------
This application has encountered a critical error:
Error #132 (0x85100084) Fatal Exception
Exception: 0xC0000005 (ACCESS_VIOLATION) at 001B:00000000
The instruction at "0x00000000 referenced memory at "0x00000000".
The memory could not be "read"
Press OK to terminate the application
------------------------------------------------------------------
am i doing something wrong?
Thanks in advance
|
|
|
|
 |
|
 |
If you don't use MessageBeep(-1), it still crashes ?
Wsock32 is a dirty dll anyway.
|
|
|
|
 |
|
 |
Yes it does unfortunately, it was only there to make sure the code there was actually executed
this is a stack trace
10001A3A WSOCK32.dll __E__69__+26 (0x00002458,0x0012FDF7,0x00000001,0x00000000) (wsock32.cpp,758)
00603AAD app.exe +0 (0x00000000,0x00000000,0x00000000,0x00000000)
line 758 is , from my precious post
PX( s, buf, len, flags);
Also a specific statement from microsoft: ( http://msdn2.microsoft.com/en-us/library/64tkc9y5(VS.80).aspx )
"Because you are calling the DLL function through a pointer and there is no compile-time type checking, make sure that the parameters to the function are correct so that you do not overstep the memory allocated on the stack and cause an access violation. One way to help provide type-safety is to look at the function prototypes of the exported functions and create matching typedefs for the function pointers."
i though that maybe it had something to do that the send functions gets forwarded to w2_32.dll. But changing the recv function instead of send gave the same error.
|
|
|
|
 |
|
 |
Solved it myself by:
putting following type def at top of file:
------------Code-------------------
typedef void (CALLBACK *PTTOSEND)(SOCKET, const char*, int, int);
Instead of the default array var to hold the func pointer i created my own var like this:
------------Code-------------------
ptToSend = (PTTOSEND) GetProcAddress(hL,"send"); //type cast
The function call then looks like this
------------Code-------------------
// customizable send
extern "C" void __stdcall __E__69__( SOCKET s, const char* buf, int len, int flags )
{
//Returning response from real dll
return (*ptToSend)( s, buf, len, flags );
}
|
|
|
|
 |