Debugging functions that application calls .

My project is to build a debugger that will keep a log of all functions that the debugged application will call , along with the parameters passed . Of course , this includes calling functions from a DLL .

I already know how to make a sample debugger and do the loop with WaitForDebugEvent etc . The problem is , that I don't know either how to set a breakpoint , or how to be notified when the application calls a DLL function .

In DOS , there was a flag that if set , the interrupt 1 was called after each command . Should I do the same for windows and recognize any CALL assembly instruction , check the stack and find out what were the parameters ?

I don't know anything about these however . Please help =)
LVL 6
WxWAsked:
Who is Participating?
 
nietodConnect With a Mentor Commented:
>> What if i patch existing DLL so it calls my
>> library before continuing ?
That's harder to do.  You're patch will "take space"  so it will overwrite the early portions of the procedure.  You will have to restore those portions when the procedure is ultimately run, then repatch.  This is extremely difficulate to do in a single threading situation.  It would be impossible to do in a multi-threading situation.
0
 
nietodCommented:
If you do that, you will find the computer runs increadibly slow.  If you  interrupt handler is very well written (is very fast) you might be able to get the computer to run at about 1/50th of the regular speed, but that is probably the best you can hope for.

A more realistic solution is to patch every DLL procedure link.  When a DLL is linked to a module, there are links inside the module that coorespond to each procedure from the DLL that the module uses.  These links are basically jump instructions to the DLL's procedures.  You could patch these so that they jump to an instruction in your debugger, then you can make your log entry and jump to the correct location in the DLL.

That will be reasnably fast and safe.

Note that if a call is made with using a pointer obtaines with GetProcAddress() it will not be noted this way, but the cll to GetProcAdddress will be, so you could actualy make this work too (by making GetProcAddress return a pointer to some location in your debugger....)
0
 
WxWAuthor Commented:
How should I modify the dll ( at run time ! ) so it jumps to my debugger ? And , the debugger code should be mapped to the address space of the running program , otherwise how it can be called ?

I think that an easier approach is to create a DLL that has the same exported functions like the original , and swap the file names . My dll will log each call , then pass the call to the original dll . Is that safe ?
0
Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

 
nietodCommented:
>> How should I modify the dll?
You don't, you modify the EXE's links to the DLL, once the EXE and DLL is mapped into memory.  

>> the debugger code should be mapped to
>> the address space of the running program
Yes.  

>> I think that an easier approach is to create a DLL
>> that has the same exported functions like the original
You can only do tht if you know the DLL and its exports ahead of time.  A generalized debugger can't.  Can you in this case?
0
 
WxWAuthor Commented:
1.In that case I must search the EXE for the links to the DLL code and change them using WriteProcessMemory()? I don't know where or how to search for these links . I guess this kind of search is documented in the Portable Executable specification ?

2.Actually , that I want is to see how a program calls a DLL function . I know the dll ( MMSYSTEM.DLL , MSACM.DLL ) . They are 16 bit code . If I write a 16-bit dll that does the call and logs the call to the original dll , I think it will work .

3.I don't think that there is a quick way to write the new dll right ? I must see all functions that are exported , then read all documentation on the parameters passed , and finally use them correctly ( otherwise BOOM stack error ! )


0
 
WxWAuthor Commented:
I have another idea : What if i patch existing DLL so it calls my library before continuing ? It will be like a virus .

How can I get where excactly at the DLL the function entry point is laid ? I guess I have to read the NE header .

0
 
nietodCommented:
>> this kind of search is documented in
>> the Portable Executable
>> specification
Yes, more or less.  The OS has to make these patches when it loads the DLL.  i.e. these links exist in the EXE, but don't have the correct address, when the DLL is loaded, the OS adjusts the links so they have the correct address.  So you would have to do the same thing.

>> I know the dll ( MMSYSTEM.DLL , MSACM.DLL )
The replacing them with your own "interface" DLLs is a good solution.  A lot easier.

>> I must see all functions that are exported
Use the dumpbin.exe utility for this.

>> then read all documentation on the parameters
>> passed , and finally use them correctly
yes and no.   that would be one way.  Another approach would be to use interface functions that don't change the stack (and certain registers).  You can do this with assembly and/or "naked" functions.  So your interface function would be called with the parameters on the stack required for the ultimate procedure.  If you don't alter those parameters and if you don't put anything on the stack, you can simply jump (not call, calling alters the stack) to the final procedure.  When that procedure ends, control returns to the EXE, not to your interface procedure (because you jumped from it, you didn't call from it.)
The problem with this approach is that there isn't much you can do in this interface procedure because you can't affect the stack.  However, that isn't much of a limitation in assembly, its a bigger limiation in a high level language.  (Actually you can use the stack, but there are lots of restrictions.)
0
 
WxWAuthor Commented:
I know how to access the stack and I can make an assembly DLL that does that . Its really very useful to me that idea , because i will get rid of reading all documentation of each function , and debug only what i want .
Thanks nietod .
0
 
WxWAuthor Commented:
I guess *hmmm* i have read access to the stack segment -)
0
 
nietodCommented:
I don't understand.  

Your code will be in the same process, so it will use the same stack.  (read and write to it.)  The interface code can use the stack, but it must pop everything off that it puts on before it jumps to the other procedure.  You also must make sure to preserve all registers that are supposed to be preserved by the calling convention.  I beleive that is ESI and EDI in stdcall, but you must just use PUSHA and POPA to preserved them all.
0
 
WxWAuthor Commented:
For ur information , the following code worked , as an emulation of an existing TEST.DLL exporting a function int _stdcall test(char*) :

EMU.CPP
---------------------------

// This code is linked with EMUA.OBJ
#include <windows.h>
#include <stdio.h>


HINSTANCE hLib;

extern "C" FARPROC _stdcall _export Get_Address(char*s)
   {
   FARPROC fp = GetProcAddress(hLib,s);
   return fp;
   }

extern "C" int _stdcall _export test(char*);

BOOL WINAPI DllEntryPoint(HINSTANCE,DWORD fd,LPVOID)
   {
   switch(fd)
      {
      case DLL_PROCESS_ATTACH:

         hLib = LoadLibrary("EMU.DLL");
         return true;

      case DLL_PROCESS_DETACH:

         FreeLibrary(hLib);
         return true;
      }
   return true;
   }


EMUA.ASM
-----------

..386
..MODEL FLAT STDCALL

..data
s_test db "test",0
s_cap db "Caption",0
s_msg db "msg",0

addr dd ?


..code

L EQU <LARGE>

PUBLIC test
EXTRN Get_Address:PROC
EXTRN MessageBoxA:PROC

test PROC
pushad
push offset s_test
call Get_Address
mov addr,eax

PUSH L 0
PUSH offset s_msg
PUSH offset s_cap
PUSH L 0
CALL MessageBoxA

popad
jmp [addr]
Endp

Ends

End

--------

Thanks again -)


0
 
WxWAuthor Commented:
correction :

{
      case DLL_PROCESS_ATTACH:

         hLib = LoadLibrary("EMU.DLL");
         return true;

should be LoadLibrary("TEST.DLL");
0
All Courses

From novice to tech pro — start learning today.