                                Tracer
                                  or
           Writing tracer without using Windows Debug API 
                                        Copyright (c) 2008 deroko of ARTeam

        Initial version of this code was written at the beginning of 2007. Last
revision, and complete rewrite was done in 2008. This driver, has been used to
produce dumps which came with my tutorial about ASProtect VM analyze in July 2007.
Article, and dumps you can find here : 

http://accessroot.com/arteam/site/download.php?view.206

        This was my ASProtect SKE 2.3 unpacker, and very few people out there got
to see it (source of course). Later this debugger was used to write some other 
unpackers but never was relesed as it was kept private, due to one simple fact. 
VMWare was not able to emulate RF properly which was essential for this tool to
work. Unpacker in which I've used this was also TheMida unpacker. I'm also sure
that some people got source code for this unpacker, but I don't even remember
with whom I've shared it.

Last updates which I've added to this code are dr7 protection, and TLB tracing
so we have at the same time memory tracing, however I didn't include TLB version
here, as it's not compatible with VMWare (or is it with latest vmware!?).

To be honest, I don't even remember when I used last time win32 debug APIs to 
write unpacker, or tracer, as this is much faster, and easier interface to use.

This code works on windows x32 only. Same thing can be done on win x64, either by 
using hardware virtualization, which I suggested long time ago, but it is not good
if you are using VMWare. Other way would be to disable PatchGuard and hook interupt
descriptor table.

To Compile - open Win XP build environment and type bld.exe -w, and 
             eveyrthing wiil be placed in bin folder.
             
Small SDK:

/*************************************************************************
 * IOCTL_INIT_PROCESS - tells tracer which process to use, and what event will
 *                      be used to sync communication between r0/r3
 *                      struct used : INIT_PROCESS
 * IOCTL_STOP_PROCESS - tells tracer to stop tracing. If there is no traced process
 *                      nothing happens
 * IOCTL_SET_REGISTERS- updates registers with data passed in TRACER_DATA,
 *                      state must be s_ready, s_softice to continue tracing
 *                      if regs are not modified, then just state should be changed
 * IOCTL_GET_REIGSTERS- gets registers and state. State can be s_except or s_exit
 *                      where on s_exit there is no more valid process
 * IOCTL_INIT_RDSTC   - not implemented. Was supposed to hook rdtsc so it can be used
 *                      as tick counter and break at the same time
 * IOCTL_STOP_RDTSC   - not implemented. Same as above, but never implemented
 **************************************************************************/
#define IOCTL_INIT_PROCESS    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_STOP_PROCESS    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_INIT_RDTSC      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x820, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_STOP_RDTSC      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x830, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SET_REGISTERS   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x840, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_GET_REGISTERS   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x850, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_GET_VERSION     CTL_CODE(FILE_DEVICE_UNKNOWN, 0x860, METHOD_BUFFERED, FILE_ANY_ACCESS)


IOCTL_INIT_PROCESS uses INIT_PROCESS structure:

typedef struct _INIT_PROCESS{
        HANDLE  dwProcessId;
        HANDLE  hEvent;
}INIT_PROCESS, *PINIT_PROCESS;

You will need to call this to specify which process will be traced, and event through
which you will get notification from driver, so latter you can do WaitForSingleObjct on this
event. However you can always attach to some process, but note that you must signal process
to stop via exceptions (eg. Read/WriteProcessMemory) as you cant set registers yet, as 
there is none to set. 

IOCTL_STOP_PROCESS - dones't take any arguments

IOCTL_GET/SET_REGISTERS expect as output/input TRACER_DATA structre:

typedef struct{
        ULONG   reg_eax;
        ULONG   reg_ecx;
        ULONG   reg_edx;
        ULONG   reg_ebx;
        ULONG   reg_esp;
        ULONG   reg_ebp;
        ULONG   reg_esi;
        ULONG   reg_edi;
        ULONG   reg_eip;
        ULONG   reg_eflags;
        ULONG   reg_dr0;
        ULONG   reg_dr1;
        ULONG   reg_dr2;
        ULONG   reg_dr3;
        ULONG   reg_dr6;
        ULONG   reg_dr7;
        ULONG   handler;                //handler index which caused exception
}EXCEPTION, *PEXCEPTION;

 
typedef struct _TRACER_DATA{
        HANDLE  dwProcessId;
        HANDLE  dwThreadId;
        ULONG   dwStatus;
        EXCEPTION  x86_regs; 
}TRACER_DATA, *PTRACER_DATA;


dwProcessId - process id of traced process (well you already know this through CreateProcess
              or when you attach to already running process though IOCTL_INIT_PROCESS).
dwThreadId  - thread id of thread which caused exception. Note that threads are not paused
              when exception occurs, they are still running.
              
              If for example, thread1 and thread2 try to execute code which has breakpoint,
              only one will be signaled, while other thread will wait it kernel mode until
              internal lock (eg. processing of this thread is not completed)
              
dwStatus    - explains what happened, and what debugger should do:

/*******************************************************
 * define states used by debugger
 * StatusException     - defines that exception occured
 * StatusContinue      - send only by user mode program to tell
 *                       that debugging can continue
 * StatusDefault       - call original handler, sent by user mode
 *                      program to tell that debugging can continue
 * StatusExecuteSoftice    - send only  by user mode program to tell
 *                      tracer to stop, and generates int 3
 * StatusExit          - state is set when traced process exits
 *******************************************************/
typedef enum{
        StatusException,                         
        StatusContinue,                
        StatusDefault,
        StatusExecuteSoftice,
        StatusExit
}STATUS_ENUM;


You may check tracer code to see how it works. I've set code to show you loaded
libraries by some process:

C:\Users\deroko\Desktop>tracer.exe C:\Windows\system32\notepad.exe
[*] LdrInitializeThunk at : 77BFA970
[*] Received int 3 at : 77BFA971
[*] Removing break from LdrInitializeThunk
[*] Setting break at NtMapViewOfSection at : 77C1FB64
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\kernel32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\advapi32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\rpcrt4.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\gdi32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\user32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\msvcrt.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\comdlg32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\shlwapi.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\winsxs\x86_microsoft.windows.co
mmon-controls_6595b64144ccf1df_6.0.6000.16386_none_5d07289e07e1d100\comctl32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\shell32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\winspool.drv
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\ole32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\oleaut32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\imm32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\imm32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\imm32.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\msctf.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\lpk.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\usp10.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\rpcss.dll
[*] Loaded dll : \Device\HarddiskVolume1\Windows\System32\uxtheme.dll
[*] Process exited

C:\Users\deroko\Desktop>



                                        Copyright (c) 2008 deroko of ARTeam




