|
Luigi Auriemmaaluigi.org (ARCHIVE-ONLY FORUM!) |
|
It is currently 19 Jul 2012 13:31
|
View unanswered posts | View active topics
|
Page 1 of 1
|
[ 14 posts ] |
|
Author |
Message |
NeoAsterix
|
Post subject: Get the function params in order to use them with dllproxy Posted: 10 Feb 2009 16:28 |
|
Joined: 10 Feb 2009 16:03 Posts: 9
|
Hello Luigi and forum, I gave a check to your tool, dllproxy and I appreciated it a lot. I'm trying to spy a dll call and the ApiSpy concept (the same used on your tool) seems work fine. I was able to attach my code to a dll and wrap the dll calls but, I was not able to handle the dll call because I don't known the exact number of parameters nor types. To be honest I'm pretty unfamiliar with C++ and Asm, but I develop since many years in many languages so I was able to get it working and to analyze it. The DLL has just 3 functions: _crc _explode, _implode, and afaik _explode is the only one that I need to spy. So I let the PROXY_FUNCTION handles the _crc and the _implode functions (inused by the exe) and I tried to make address the _explode function via a new function named CALLIT (I got it from your proxocket code). After some debug (I got often a re-definition of the call), I was able to compile it. The problem is that my spier DLL get attached but it doesn't call my spier functions, I guess because of a different number of parameters. There is the code of the initialization and of my own function: Code: // SAME CODE OF DLLPROXY
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
MessageBox(0, "Called!", "DllProxy", MB_OK | MB_ICONINFORMATION); // THIS WORK!! switch(fdwReason) { case DLL_PROCESS_ATTACH: { DisableThreadLibraryCalls(hinstDLL); InitInstance(); break; } case DLL_PROCESS_DETACH: { ExitInstance(); break; } default: break; } return(TRUE); }
The above code works and the MessageBox is opened each time the _explode function is called. Code: #include <stdlib.h> #include <windows.h> #include <stdio.h>
FILE *fddbg = NULL;
#define CALLING_CONVENTION WINAPI // default for Windows DLLs #define CALLIT(X) static X##_(*_##X) = NULL; \ X##_(X)
#define _explode_(X) int CALLING_CONVENTION (X)(char *boh) CALLIT(_explode) { MessageBox(0, "NEVER ARRIVED HERE :(", "DllProxy", MB_OK | MB_ICONERROR); // NEVER ARRIVED HERE int ret; ret = __explode(boh); fddbg = fopen("calling.txt", "wb"); if(!fddbg) { MessageBox(0, "the calling.txt file can't be created", "DllProxy", MB_OK | MB_ICONERROR); exit(1); } if(fddbg) fprintf(fddbg, "explode %s\n", boh); fclose(fddbg); return(ret); }
Here is where I try to get the call but I never got this piece of code called, I guess because I don't know the parameters of the real function _explode. I just tried with some known types like strings, integers etc. ('boh' is just a try). In C# I can call a function like this: int _explode(params object myparamaters) but I don't know if there is a similar work around in C++ Maybe I should try to disassemble the EXE and check when it calls the _explode function (in the IMPBORL.DLL) but like I said before I'm unfamiliar with ASM so I was just able to get the breakpoint to the call but no clue how to grab their parameters... Any help is appreciated :)
|
|
Top |
|
|
|
|
|
|
|
aluigi
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 10 Feb 2009 18:41 |
|
Joined: 13 Aug 2007 21:44 Posts: 4068 Location: http://aluigi.org
|
the execution of the MessageBox in DllMain means that the proxy dll has been correctly loaded by the program, and this is good. the fact that your _explode is not called can be caused by various factors: - you have not added the file.DEF to your compiler and so your dll doesn't export the function correctly or with the correct names - you have not removed PROXY_FUNCTIONX(_explode) and __explode = (void *)GetProcAddress(hm, "_explode"); from your code for the rest in this moment the correctness of the number of parameters in the function and its CALLING_CONVENTION (it could be probably __cdecl and not WINAPI) is a secondary problem because in any case when your function is called the messagebox must appear. I suggest also to compare the exported functions of the original dll and your proxy one for being 100% sure that they are the same, you can do this with a disassembler or simply with this other tool derived from proxydllskel: http://aluigi.org/mytoolz/dllexplist.zip
|
|
Top |
|
|
NeoAsterix
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 10 Feb 2009 19:14 |
|
Joined: 10 Feb 2009 16:03 Posts: 9
|
aluigi wrote: the execution of the MessageBox in DllMain means that the proxy dll has been correctly loaded by the program, and this is good.
Indeed, I thought so... The dll attachment works aluigi wrote: the fact that your _explode is not called can be caused by various factors: - you have not added the file.DEF to your compiler and so your dll doesn't export the function correctly or with the correct names - you have not removed PROXY_FUNCTIONX(_explode) and __explode = (void *)GetProcAddress(hm, "_explode"); from your code
I added the .DEF and compiled it with -shared I removed the PROXY_FUNCTIONX for the _explode function. Here my full code: IMPBORL.cCode: // code generated by "DLL proxy skeleton generator 0.1.1a", Luigi Auriemma http://aluigi.org
#define DLL_NAME "IMPBORL.DLL" // the name of the original DLL
// if DLL_PATH is not defined the proxy DLL will automatically retrieve the Windows system32 // folder of the system and will load the DLL in that location #define DLL_PATH "orig" // if uncommented will be loaded the DLL from this location //#define DLL_PATH "c:\\windows\\system32"
// if you want to proxify a system DLL remember to disable the header file which already exports those functions // for example, if you want to proxify wsock32.dll or ws2_32.dll you must uncomment the following lines: // #define _WINSOCK_H // #define _WINSOCK2_H // you can find the needed "#define"s in the include header files showed by your compiler when it reports the // "redeclaration" or "previous declaration" errors
// example of a simple recv() hooking: // #define RECV_FUNCTION(FUNCTION_NAME) int CALLING_CONVENTION (FUNCTION_NAME)(int socket, char *buffer, int length, int flags) // static RECV_FUNCTION(*_recv) = NULL; // RECV_FUNCTION(recv) { // length = _recv(socket, buffer, length, flags); // return(length); // }
// example of compiling: gcc -o ws2_32.dll ws2_32.c -shared ws2_32.def //#define POP_EBP // uncomment if you use -fomit-frame-pointer #define POP_EBP __asm__("pop %ebp"); // comment if you use -fomit-frame-pointer // you MUST modify the above POP_EBP if you use -fomit-frame-pointer with your compiler!
//#define WINDLLSHIT // try uncommenting here if you have problems with compiling but don't expect miracles #ifndef WINDLLSHIT #include <stdlib.h> #include <windows.h> #include <stdio.h> #include "IMPBORL.h" #else #define DECLARE_HANDLE(n) typedef struct n##__{int i;}*n DECLARE_HANDLE(HINSTANCE); typedef HINSTANCE HMODULE; DECLARE_HANDLE(HWND); #define LPVOID void * #define DWORD unsigned int #define UINT unsigned int #define LPCSTR char * #define LPCTSTR char * #define LPSTR char * #define BOOL int #define TRUE 1 #define FALSE 0 #define MAX_PATH 1024 #define NULL 0 #define WINAPI __stdcall #define DLL_PROCESS_DETACH 0 #define DLL_PROCESS_ATTACH 1 #define DLL_THREAD_ATTACH 2 #define DLL_THREAD_DETACH 3 typedef int (WINAPI *FARPROC)(); BOOL WINAPI FreeLibrary(HMODULE); HINSTANCE WINAPI LoadLibraryA(LPSTR); UINT WINAPI GetSystemDirectoryA(LPSTR,UINT); FARPROC WINAPI GetProcAddress(HINSTANCE,LPCSTR); BOOL WINAPI DisableThreadLibraryCalls(HMODULE); #define GetSystemDirectory GetSystemDirectoryA #define LoadLibrary LoadLibraryA #endif
//FILE *fddbg = NULL; HMODULE hm = NULL;
#define CALLING_CONVENTION WINAPI // default for Windows DLLs #define PROXY_FUNCTION(FUNCTION_NAME) /* for the proxified functions not modified */ \ void CALLING_CONVENTION (FUNCTION_NAME)(void) #define PROXY_FUNCTIONX(FUNCTION_NAME) \ static PROXY_FUNCTION(*_##FUNCTION_NAME) = NULL; \ PROXY_FUNCTION(FUNCTION_NAME) { \ POP_EBP __asm__("jmp *__"#FUNCTION_NAME); \ }
PROXY_FUNCTIONX(_implode) //PROXY_FUNCTIONX(_explode) PROXY_FUNCTIONX(_crc32) BOOL InitInstance(void) { char winpath[MAX_PATH];
if(hm) return(TRUE); #ifdef DLL_PATH strcpy(winpath, DLL_PATH); #else GetSystemDirectory(winpath, sizeof(winpath)); #endif strcat(winpath, "\\" DLL_NAME);
hm = LoadLibrary(winpath); if(!hm) return(FALSE);
__implode = (void *)GetProcAddress(hm, "_implode"); //__explode = (void *)GetProcAddress(hm, "_explode"); __crc32 = (void *)GetProcAddress(hm, "_crc32"); return(TRUE); }
void ExitInstance(void) { if(hm) { FreeLibrary(hm); hm = NULL; } }
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { MessageBox(0, "Called!", "DllProxy", MB_OK | MB_ICONINFORMATION); switch(fdwReason) { case DLL_PROCESS_ATTACH: { DisableThreadLibraryCalls(hinstDLL); InitInstance(); break; } case DLL_PROCESS_DETACH: { ExitInstance(); break; } default: break; } return(TRUE); }
IMPBORL.hCode: #include <stdlib.h> #include <windows.h> #include <stdio.h>
FILE *fddbg = NULL;
#define CALLING_CONVENTION WINAPI // default for Windows DLLs #define CALLIT(X) static X##_(*_##X) = NULL; \ X##_(X)
#define _explode_(X) int CALLING_CONVENTION (X)(char *boh) CALLIT(_explode) { int ret; //init_proxocket(); MessageBox(0, "the calling.txt file can't be created", "DllProxy", MB_OK | MB_ICONERROR); ret = __explode(boh); fddbg = fopen("calling.txt", "wb"); if(!fddbg) { MessageBox(0, "the calling.txt file can't be created", "DllProxy", MB_OK | MB_ICONERROR); exit(1); } if(fddbg) fprintf(fddbg, "explode %s\n", boh); fclose(fddbg); return(ret); }
IMPBORL.defCode: EXPORTS _implode @1 _explode @2 _crc32 @3
|
|
Top |
|
|
NeoAsterix
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 10 Feb 2009 19:36 |
|
Joined: 10 Feb 2009 16:03 Posts: 9
|
Wait, an important update, when I posted my code I cleaned some dirty rows and I noticed that now the CALLIT(_explode) arrives, you were right! That's great, now I can get the moment when the explode function is called, but I still don't know how to read its parameters and how to re-call the original _explode with the real parameters. Quote: #define _explode_(X) int CALLING_CONVENTION (X)(char *boh) CALLIT(_explode) { int ret; MessageBox(0, "Arrived ok", "DllProxy", MB_OK | MB_ICONERROR); ret = __explode(boh); fddbg = fopen("calling.txt", "wb"); if(!fddbg) { MessageBox(0, "the calling.txt file can't be created", "DllProxy", MB_OK | MB_ICONERROR); exit(1); } if(fddbg) fprintf(fddbg, "explode %s\n", boh); fclose(fddbg); return(ret); }
The *boh parameter is not accepted by the original _explode that indeed crashes :(
|
|
Top |
|
|
aluigi
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 10 Feb 2009 23:31 |
|
Joined: 13 Aug 2007 21:44 Posts: 4068 Location: http://aluigi.org
|
this can be a good job for the debugger like ollydbg or for IDA Pro (or also REC http://www.backerstreet.com/rec/rec.htm) which show the full list of arguments passed to the function. in ollydbg it's enough that you use "bp _explode" or "bp impborl._explode" if the dll is linked in the executable and olly will break when the function is called. anyway exist various options for this job but I think that those one are the easier (most depends by how much confortable you are with these programs or with assembly).
|
|
Top |
|
|
NeoAsterix
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 11 Feb 2009 10:05 |
|
Joined: 10 Feb 2009 16:03 Posts: 9
|
To be honest I never wrote a row of assembler in my life, I had a good experience in C indeed now I'm able to use (rip) your C++ because of my C but I'm very unfamiliar with ASM. I'm trying to use Olly and I was able to set the breakpoint in the proper address, but I have no clue how to get the parameters, I just see the register values. Anyway, even if I'm lost it seems funny! I like to learn new things so I'm trying to understand some asm, I guess that in a couple of years I'll be able to disassemble it correctly :)
|
|
Top |
|
|
NeoAsterix
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 11 Feb 2009 10:19 |
|
Joined: 10 Feb 2009 16:03 Posts: 9
|
I understood that _explode gets 4 arguments, atm I don't know the type.
|
|
Top |
|
|
aluigi
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 11 Feb 2009 12:32 |
|
Joined: 13 Aug 2007 21:44 Posts: 4068 Location: http://aluigi.org
|
ok, so the breakpoint in olly works, this is the first good thing. now you must only understand what the arguments mean.
when olly breaks take a look at the stack window (right-down) and you will see a sequence of offsets and numbers. the first number must be ignored (return address) and you must take care only of the other 4 (if you are sure that are only 4 the arguments taken by _explode).
now do a right click on the first of the 4 and select "Follow in Dump", if it's a pointer to something (like a buffer or an integer like &number) the dump window (left-down) will move to the new location and you can read all the content of that memory (maybe a string like a filename or a data buffer), guessing what they are. if "Follow in Dump" is not available means that it's a number and not a pointer, often it can be the size of a buffer or a boolean value or something else numerical.
do the same for the other 3 arguments and you will guess them.
then press CTRL-F9 which will reach the end of the function and this will allow you to understand if some of the 4 arguments are used also as "output", so when olly breaks at _explode, if you have a buffer as argument 3 select "Follow in Dump", press CTRL-F9 and then check if the content of that memory is changed (and do the same also for the other arguments if needed)
oh I was forgotting, check the value of EAX when you return from the function, it's the return value of the function
|
|
Top |
|
|
NeoAsterix
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 13 Feb 2009 10:18 |
|
Joined: 10 Feb 2009 16:03 Posts: 9
|
Just an update, I didn't forget this topic and I didn't give up (yet)
I'm still losing my eyes on this funny experience, even if I'm going to be crazy...
After a couple of days, it seems that I got some news, the first two parameters seems to be a Callback, I'm pretty sure, even if I thought that C++ doesn't support callbacks :/
Now I'm trying to get the parameters of those callbacks, but the thing is going to be pretty hard for me, anyway if I would give up, I'll come here to say at least thank you to you because you were very helpful to me...
|
|
Top |
|
|
aluigi
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 13 Feb 2009 18:09 |
|
Joined: 13 Aug 2007 21:44 Posts: 4068 Location: http://aluigi.org
|
callbacks? boring :) not impossible but just a bit hard if you are not enough "comfortable" with the debugger, because you need to do the same tests you did with _explode with all the callbacks, when olly breaks in _explode set an execution breakpoint for the offset pointed by the first argument, or any other argument that you guess is a callback.
anyway this "impborl.dll" file doesn't seem so "genuine/safe" if you search it on google or other search engines
|
|
Top |
|
|
NeoAsterix
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 14 Feb 2009 11:49 |
|
Joined: 10 Feb 2009 16:03 Posts: 9
|
impborl was the old pkware dll that decompress/decrypt data. It came from the delphi sdk. Ok, I collected some info, this should be the explode definition: Code: unsigned int explode( unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), void (*write_buf)(char *buf, unsigned int *size, void *param), char *work_buf, void *param); I tested the callbacks in Olly and it works, the number of arguments match. Now I'm trying to modify the dllproxy to handle them and until now, no luck :( Another thing I just discovered is that the Calling_Convention is _cdecl
Last edited by NeoAsterix on 14 Feb 2009 17:14, edited 2 times in total.
|
|
Top |
|
|
NeoAsterix
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 14 Feb 2009 12:04 |
|
Joined: 10 Feb 2009 16:03 Posts: 9
|
My idea id to add two new functions to my code, say myCallback1 and myCallback2 with the same parameters, when the _explode function is called, I should replace the original callback addresses with my own myCallback1 and myCallback2 so I would force _explode to call back them instead of the original pointers and when they are called back from _explode I should re-call the original ones... something like that: Code: unsigned int myCallBack1(char *buffer, unsigned int *size, void *param){ //call the original callback stored in PointerToCB1 } void myCallBack2(char *buffer, unsigned int *size, void *param){ //call the original callback stored in PointerToCB2 }
#define _explode_(X) unsigned int CALLING_CONVENTION (X)(unsigned int *read_buf, void *write_buf, char *work_buf, void *param) CALLIT(_explode) { // store the read_buf pointer to PointerToCB1 // store the write_buf pointer to PointerToCB2 unsigned int back; back = __explode(*myCallBack1, *myCallBack2, work_buf,param); return(back); }
but I need to learn more about pointers and C++ :)
|
|
Top |
|
|
NeoAsterix
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 15 Feb 2009 14:45 |
|
Joined: 10 Feb 2009 16:03 Posts: 9
|
Yay! I got it... and I'm pretty glad to.
I finally refreshed my knowledge about C and now my proxy works as expected. I redirected also the functions read and write buffer so the whole code is now proxied and it logs almost all the steps...
The only part that I'm missing, is the void *param decoding, I don't know how to print/browse it because I don't know which sort of type it is :( I understood that it can be anything and so maybe I should point to its start address and move forward to decode the whole content but I still need to learn more.
|
|
Top |
|
|
aluigi
|
Post subject: Re: Get the function params in order to use them with dllproxy Posted: 15 Feb 2009 14:56 |
|
Joined: 13 Aug 2007 21:44 Posts: 4068 Location: http://aluigi.org
|
uhmmm maybe it's a "int *number" which receives the size of something or a special number when the function returns (you can easily monitor it with CTRL-F9).
|
|
Top |
|
|
|
Page 1 of 1
|
[ 14 posts ] |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|