Luigi Auriemma

aluigi.org (ARCHIVE-ONLY FORUM!)
It is currently 19 Jul 2012 13:31

All times are UTC [ DST ]





Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 14 posts ] 
Author Message
 Post subject: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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.c
Code:
// 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.h
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) {
    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.def
Code:
EXPORTS
  _implode @1
  _explode @2
  _crc32 @3


Top
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
 Post subject: Re: Get the function params in order to use them with dllproxy
PostPosted: 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
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 14 posts ] 

All times are UTC [ DST ]


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

Search for:
cron