 |
|
 |
Any idea about this means ?
http://img228.imageshack.us/img228/7624/again.jpg
When the program loads the proxy DLL this error occures.
modified on Wednesday, July 29, 2009 11:15 AM
|
|
|
|
 |
|
 |
Is this the same machine where you installed Visual Studio?
Send me the Project and revised it.
|
|
|
|
 |
|
 |
Hi, I created this application based on the above to remove the dependencies to other tools (dumpbin). It is a test and can be improved.
Regards.
//email: arielmendoza@hotmail.com
#include "stdafx.h"
#include "stdafx.h"
#include "windows.h"
#include "winnt.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
int main(int argc, char* argv[])
{
char DefFile[255];
char CppFile[255];
if(argc!=3)
{
printf("\nMissing parameters ex:");
printf("\nExtractDllExports ws2_32.dll ws2_32");
return 2;
}
memset(DefFile,0,sizeof(DefFile));
memset(CppFile,0,sizeof(CppFile));
sprintf(DefFile,"%s.def",argv[2]);
sprintf(CppFile,"%s.cpp",argv[2]);
FILE *fpdef;
FILE *fpcpp;
if((fpdef=fopen(DefFile, "w+"))==NULL)
{
printf("\Error in CreateFile %s",DefFile);
return 1;
}
if((fpcpp=fopen(CppFile, "w+"))==NULL)
{
printf("\Error in CreateFile %s",CppFile);
return 1;
}
HMODULE lib = LoadLibraryExA(argv[1], NULL, DONT_RESOLVE_DLL_REFERENCES);
if(lib==NULL)
{
//Error cargando la DLL
printf("\nError in LoadLibraryExA. Dll:%s",argv[1]);
return 1;
}
assert(((PIMAGE_DOS_HEADER)lib)->e_magic == IMAGE_DOS_SIGNATURE);
PIMAGE_NT_HEADERS header =PIMAGE_NT_HEADERS((BYTE *)lib + ((PIMAGE_DOS_HEADER)lib)->e_lfanew);
assert(header->Signature == IMAGE_NT_SIGNATURE);
assert(header->OptionalHeader.NumberOfRvaAndSizes > 0);
PIMAGE_EXPORT_DIRECTORY exports = PIMAGE_EXPORT_DIRECTORY((BYTE *)lib + header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PVOID names = (BYTE *)lib + exports->AddressOfNames;
WORD *Ordinals = (WORD*)((BYTE *)lib + exports->AddressOfNameOrdinals);
//inicializar el .cpp
fputs("\n//**** remember to add the /def parameter to linker ****",fpcpp);
fputs("\n#include <windows.h>",fpcpp);
fputs("\n\nHINSTANCE hLThis = 0;",fpcpp);
fputs("\nHINSTANCE hL = 0;",fpcpp);
char Farproc[255];
memset(Farproc,0,sizeof(Farproc));
sprintf(Farproc,"\nFARPROC p[%d] = {0};",exports->NumberOfNames);
fputs(Farproc,fpcpp);
fputs("\nBOOL WINAPI DllMain(HINSTANCE hInst,DWORD reason,LPVOID)",fpcpp);
fputs("\n{",fpcpp);
fputs("\n if (reason == DLL_PROCESS_ATTACH)",fpcpp);
fputs("\n {",fpcpp);
fputs("\n hLThis = hInst;",fpcpp);
char DllName[255];
memset(DllName,0,sizeof(DllName));
sprintf(DllName,"\n hL = LoadLibrary(\"%s\");",argv[1]);
fputs(DllName,fpcpp);
fputs("\n if (!hL) return false;",fpcpp);
//inicializar el ,def
fputs("EXPORTS",fpdef);
for (int i = 0; i < exports->NumberOfNames; i++)
{
//Escribir el .def
char txtFunction[255];
memset(txtFunction,0,sizeof(txtFunction));
WORD w=(WORD )(BYTE *)lib + ((WORD *)Ordinals)[i]+1;
sprintf(txtFunction,"\n%s=__E__%d__ @%d", (BYTE *)lib + ((DWORD *)names)[i],i,w);
fputs(txtFunction,fpdef);
//Cpp
char txtPointer[255];
memset(txtPointer,0,sizeof(txtPointer));
sprintf(txtPointer,"\n p[%d] = GetProcAddress(hL,\"%s\");",i,(BYTE *)lib + ((DWORD *)names)[i]);
fputs(txtPointer,fpcpp);
}
fputs("\n }",fpcpp);
fputs("\n if (reason == DLL_PROCESS_DETACH)",fpcpp);
fputs("\n {",fpcpp);
fputs("\n FreeLibrary(hL);",fpcpp);
fputs("\n }",fpcpp);
fputs("\n return 1;",fpcpp);
fputs("\n}",fpcpp);
//Comentario de como modificar la funcion
fputs("\n// gethostname",fpcpp);
fputs("\n// Example replace functions ",fpcpp);
fputs("\n//extern \"C\" int __stdcall __E__92__(char *name, int namelen)",fpcpp);
fputs("\n// {",fpcpp);
fputs("\n//call original gethostname",fpcpp);
fputs("\n// typedef int (__stdcall *pS)(char*,int);",fpcpp);
fputs("\n// pS pps = (pS)p[92];",fpcpp);
fputs("\n// int rv = pps(name,namelen);",fpcpp);
fputs("\n// if(rv==0)",fpcpp);
fputs("\n// {",fpcpp);
fputs("\n// memset(name,0,namelen);",fpcpp);
fputs("\n//Manipulate result",fpcpp);
fputs("\n// strcpy(name,\"TestName\");",fpcpp);
fputs("\n// }",fpcpp);
fputs("\n// return rv;",fpcpp);
fputs("\n// }",fpcpp);
fputs("\n//end example;",fpcpp);
//
for (int i = 0; i < exports->NumberOfNames; i++)
{
char Comentario[255];
char Encabezado[255];
char Salto[255];
memset(Comentario,0,sizeof(Comentario));
memset(Encabezado,0,sizeof(Encabezado));
memset(Salto,0,sizeof(Salto));
sprintf(Comentario,"\n\n//%s",(BYTE *)lib + ((DWORD *)names)[i]);
sprintf(Encabezado,"\nextern \"C\" __declspec(naked) void __stdcall __E__%d__()",i);
sprintf(Salto,"\n jmp p[%u*%u];",i,sizeof(void*));
fputs(Comentario,fpcpp);
fputs(Encabezado,fpcpp);
fputs("\n{",fpcpp);
fputs("\n __asm",fpcpp);
fputs("\n {",fpcpp);
fputs(Salto,fpcpp);
fputs("\n }",fpcpp);
fputs("\n}",fpcpp);
}
//system("pause");
fcloseall();
return 0;
}
|
|
|
|
 |
|
 |
There is an error in the last example. It must not be
pS pps = (pS)p[63*4];
but
pS pps = (pS)p[69];
Someone in previous comments got access violation - it is due to this error, not because "(naked)" or something else.
|
|
|
|
 |
|
 |
Hi!
I am new to c++ programming so this question might sound silly.
I am trying to manipulate the parameters and proxy this function:
D3DXMATRIX* WINAPI D3DXMatrixLookAtRH
( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt,
CONST D3DXVECTOR3 *pUp );
And the code from my proxy dll looks like this:
extern "C" D3DXMATRIX* WINAPI __stdcall __E__205__(D3DXMATRIX *pOut,CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, CONST D3DXVECTOR3 *pUp)
{
typedef D3DXMATRIX* (WINAPI __stdcall *pS)(D3DXMATRIX*, CONST D3DXVECTOR3*, CONST D3DXVECTOR3*, CONST D3DXVECTOR3*);
pS pps = (pS)p[205*4];
D3DXMATRIX* rv = pps(pOut,pEye,pAt,pUp);
return rv;
}
I get an unhandled exception. Any idea what am I doing wrong?
|
|
|
|
 |
|
 |
At first glance, I don't see anything wrong. Do ALL functions crash ? If not, then chances are that you calling the function with bad parameters.
1. Is it for a 64-bit dll ? (then you need 205*8!)
2. WINAPI = __stdcall so you do not need both.
3. Check the value of the rv while debugging.
|
|
|
|
 |
|
 |
For the first test I just pass on the parameters on and don't manipulate them. What is interesting if I do this:
(debugging it)
extern "C" D3DXMATRIX* __stdcall __E__205__(D3DXMATRIX *pOut,CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, CONST D3DXVECTOR3 *pUp)
{
std::ofstream outdata;
outdata.open("C:\\out.txt");
outdata << "Eye:" << pEye->x << " " << pEye->y << " " << pEye->z << std::endl;
outdata.close();
return NULL;
}
The function calls seem to succeed. Because the parameters do have the right values. So I am shore the function is called.
Maybe it has something to do with the first function parameter being the [in, out] parameter? The function out parameter and the returning type are the same. (according to documentation: http://msdn.microsoft.com/en-us/library/bb205343(VS.85).aspx[^])
if I put the rest of the function in I get an unhandled exception at this line of code:
D3DXMATRIX* rv = pps(pOut,pEye,pAt,pUp);
|
|
|
|
 |
|
 |
When i try to use "proxy2.exe dumpbin /exports wsock32.dll > exports.txt" i get the following written into the exports.txt :
Wrappit. Copyright (C) Chourdakis Michael
Usage: WRAPPIT
==================================================================
I tried diffrent dlls but it didnt work either...
Thanks for answers
Thelod
|
|
|
|
 |
|
 |
Hi there.
Be patient for a few days and I will put wrappit2.cpp which has many bugs fixed.
Michael.
|
|
|
|
 |
|
 |
I 've created a second version which works without inline assembly, by using forwards - and it works with PPC and x64. If anyone interested, mail me , I should update the CP article soon.
|
|
|
|
 |
|
 |
Hey, it's a very handy tool, excellent work.
Can you email me your new version?
Thank you very much.
visit me at
http://usuarios.lycos.es/hernandp
|
|
|
|
 |
|
 |
Thanks for sharing your code with us. Can you send me version 2 please.
I can't make work v1 correctly with borland compiled dll. The original dll uses DLLEntyPoint, which seems to cause the calling application to crash when using the proxy dll.
Another issue in the original code is that the generated name of all functions was always the same because i was not incremented while parsing .
|
|
|
|
 |
|
|
 |
|
 |
Thank you for the quick reply Michael.
|
|
|
|
 |
|
 |
A PM sent to your account. Have some problems with using wrappit 2.
|
|
|
|
 |
|
 |
WinCE (ARMV4) doesn't support inline assembly. Is there an alternative code to make the stub cpp file compile with WinCE? I don't know most of the parameters for the DLL so i was hoping there's another method to do the jmp.
Thanks
-- modified at 23:23 Monday 10th September, 2007
|
|
|
|
 |
|
 |
There is a way to create a 'forward entry' in a dll, but i am not sure how.
For example, if you see wsock32.dll , many items are automatically forwarded to ws2_32.dll.
In case you find the relative linker/def file option, let me know
|
|
|
|
 |
|
 |
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.
|
|
|
|
 |