⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tracer.cpp

📁 ICEExt for Driver Studio3.2的sourcecode
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*++
    Copyright  (c) 2002 Sten
    Contact information:
        mail: stenri@mail.ru

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

 
Module Name: 
    tracer.cpp

Abstract: Very simple tracer engine. It's only purpose is trace the instruction that
    caused break point on range exception so that break point can be restored after 
    instruction execution.
Revision History:

 Godness     01/09/2005
      Adapted for eXTreme tRaCer engine

 Sten        11/12/2002
      Initial release

--*/

extern "C"{
#pragma warning ( push, 3 )
#include <ntddk.h>
#pragma warning ( pop )
}

#pragma warning ( disable: 4514 ) // unreferenced inline function has been removed

#include "defs.h"
#include "ntoskrnl.h"
#include "softice.h"
#include "keyboard.h"
#include "undoc.h"
#include "bpr.h"
#include "tracer.h"

///////////////////////////////////////////////////////////////////////
//                    External definitions
///////////////////////////////////////////////////////////////////////
extern void ExecutePCommand(void);
extern void ExecutePRETCommand(void);

extern ULONG NumberOfTracedCommand;
extern ULONG CountOfCommand;
extern ULONG TracerCallBack;
extern ULONG EipWhenPRET;

extern ULONG ReturnToMakePageIn;
extern ULONG MakePageIn;
extern ULONG SavedCR0;
extern ULONG CR3ForOurProcess;
extern ULONG PreLastEIPValue;
extern ULONG CurrentRing;

void* CheckAddressAndMakePageIn(void *address);
void* GetUserHandler(void);

///////////////////////////////////////////////////////////////////////
//                           Globals
///////////////////////////////////////////////////////////////////////
void *OldInterruptStack;
char NewInterruptStack[0x1000];

int InTraceMode         = 0;
int HideTFflag          = 0;
int EipWait             = 0;

int SystemInt1          = 0;
int DRDebugException    = 0;
int DRSavedHandler      = 0;
char DRSavedByte        = 0;

void* UserHandler       = 0;
void* UserAddress       = 0;
int EmulatePOPFD        = 0;

char Int0Installed = 1;
void *OldInt0      = 0;
void *OldInt1      = 0; // Old int1 handler
void *OldInt6      = 0;
void *OldIntD      = 0;
void *OldInt10     = 0;

char szBad[]          = "Traced through given number of instructions - no trace condition has been met...\n";
char szGood[]         = "One of the trace conditions is met! %d commands has been traced...\n";
char szFPUInst[]      = "FPU exception occured at address %08X\n";
char szInt3Inst[]     = "INT3 instruction has been met at address %08X\n";
char szException[]    = "Exception instruction has been met at address %08X\n";
char szInvalidInst[]  = "Invalid instruction has been met at address %08X\n";
char szTraceStoped[]  = "Tracing has been stopped! %d commands has been traced...\n";
char szZeroDivision[] = "Division on ZERO occured at address %08X\n";

int __cdecl CodeAnalyzer (CLIENT_STATE *pClientState)
{
#define CHANGE_ESP3_VALUE(UserRegister)                 \
    pClientState->esp3 = UserRegister;                  \
    pClientState->eip += 2;                             \
    return 1;

    if (!CheckAddressAndMakePageIn((void *)(pClientState->eip + 0))) return 0;
    if (!CheckAddressAndMakePageIn((void *)(pClientState->eip + 1))) return 0;

    if (*(PUCHAR)(pClientState->eip + 0) == 0x8B)
    {
        switch (*(PUCHAR)(pClientState->eip + 1))
        {
        case 0xE0: CHANGE_ESP3_VALUE(pClientState->eax);  // emulate mov esp, eax
        case 0xE1: CHANGE_ESP3_VALUE(pClientState->ecx);  //  -//-   mov esp, ecx
        case 0xE2: CHANGE_ESP3_VALUE(pClientState->edx);  // ...
        case 0xE3: CHANGE_ESP3_VALUE(pClientState->ebx);
        case 0xE4: CHANGE_ESP3_VALUE(pClientState->esp3); 
        case 0xE5: CHANGE_ESP3_VALUE(pClientState->ebp); 
        case 0xE6: CHANGE_ESP3_VALUE(pClientState->esi); 
        case 0xE7: CHANGE_ESP3_VALUE(pClientState->edi); 
        }
    }

    if (*(PUCHAR)(pClientState->eip + 0) == 0x9C)   // if pushfd command was met
    {                                               // need to remove TF flag from stack
        EipWait = pClientState->eip + 1;
        HideTFflag = 1;
        return 0;
    }

    if (*(PUCHAR)(pClientState->eip + 0) == 0x9D)   // if popfd command was met
    {
        if (!CheckAddressAndMakePageIn((void *)(pClientState->esp3))) return 0;

        if (*(PULONG)pClientState->esp3 & 0x100)
        {
            if ((UserHandler = GetUserHandler()) == 0) return 0;
            UserAddress = (void *)pClientState->eip;

            DWORD cr0 = EnableWrite();
            *(PUCHAR)pClientState->eip = 0xCC;
            SetCR0(cr0);

            EmulatePOPFD = 1;
            return 0;
        }
    }

    return 0;
}

///////////////////////////////////////////////////////////////////////
//
//  Int 00 handler 
//
///////////////////////////////////////////////////////////////////////

void __declspec(naked) Int00Handler(void)
{
    __asm
    {
        cmp     cs:[TracerCallBack], 0
        je      next_handler
        pushad
        push    fs
        push    ds
        push    es

        mov     eax, 30h
        mov     fs, ax
        mov     eax, 23h
        mov     ds, ax
        mov     es, ax

        push    dword ptr [esp + 0x2C]
        push    offset szZeroDivision
        call    DbgPrint
        add     esp, 8

        pop     es
        pop     ds
        pop     fs
        popad

    next_handler:
        jmp     cs:[OldInt0]
    }
}

///////////////////////////////////////////////////////////////////////
//
//  Int 01 handler 
//
///////////////////////////////////////////////////////////////////////

void __declspec(naked) Int01Handler(void)
{
    __asm
    {
        cmp     cs:[MakePageIn], 0
        je      not_make_pagein

        jmp     cs:[ReturnToMakePageIn]   //return to CheckAndMakePageIn function

not_make_pagein:
           
        cmp     cs:[TracerCallBack], 0
        je      do_not_trace

        push    ds
        push    eax
        mov     eax, 23h
        mov     ds, ax

        mov     eax, esp
        add     eax, 8
        mov     OldInterruptStack, eax   // save original stack pointer
        pop     eax

        mov     esp, offset NewInterruptStack + 0x1000 - 0x10

        pushad
        push    fs
        mov     esi, OldInterruptStack
        push    dword ptr [esi - 4]             // save original ds value 
        push    es

        mov     eax, 30h
        mov     fs, ax
        mov     eax, 23h
        mov     es, ax

        mov     al, byte ptr [esi + 4]
        and     al, 3
        cmp     al, byte ptr [CurrentRing]
        je      ring_value_not_change

        pop     es                              // if ring value was suddenly changed
        pop     ds                              // the some other int1 interrupt occured
        pop     fs                              // so we need to pass this way for today...
        popad
        mov     esp, OldInterruptStack
        iretd

ring_value_not_change:

        cld
        mov     ecx, 5
        test    al, 3                           // check in CS value last two bits
        jnz     copy_stack                      // copy interrupt stack to new arrea
        mov     ecx, 3                          // it's need for MakePageIn function
copy_stack:
        mov     edi, offset NewInterruptStack + 0x1000 - 0x10
        repnz   movsd

        cmp     HideTFflag, 0                   // remove TF flag when pushfd command was met
        jz      emulate_popfd

        mov     HideTFflag, 0
        mov     eax, OldInterruptStack          // get original interrupt stack pointer
        mov     edx, dword ptr [eax]
        cmp     edx, EipWait                    // check current eip value
        jne     emulate_popfd
        mov     eax, dword ptr [eax + 0xC]      // get esp ring 3 pointer

        push    eax
        call    CheckAddressAndMakePageIn
        or      eax, eax
        jz      emulate_popfd

        and     dword ptr [eax], not 100h

emulate_popfd:
        cmp     EmulatePOPFD, 0                 // need to correct exception params in stack
        jz      tracer_call_back                // for emulate popfd instruction

        mov     EmulatePOPFD, 0

        mov     eax, dword ptr [esp + 0x2C]     // if user eip value == user's exception handler
        cmp     eax, UserHandler
        jnz     tracer_call_back

        mov     eax, dword ptr [esp + 0x38]
        push    eax
        call    CheckAddressAndMakePageIn
        or      eax, eax
        jz      tracer_call_back

        mov     eax, dword ptr [eax + 4]        // get pointer to ExceptionCode in _EXCEPTION_RECORD *ExceptionRecord
        push    eax
        call    CheckAddressAndMakePageIn
        or      eax, eax
        jz      tracer_call_back

        mov     dword ptr [eax], 0x80000004     // STATUS_SINGLE_STEP exception

        call    EnableWrite
        mov     ebx, eax

        mov     eax, UserAddress
        mov     byte ptr [eax], 0x9D            // patch user code back

        push    ebx
        call    SetCR0

tracer_call_back:
        call    TracerCallBack
        or      eax, eax
        jnz     good_message

        mov     eax, CountOfCommand
        inc     eax
        mov     CountOfCommand, eax
        cmp     eax, NumberOfTracedCommand
        jae     bad_message

        mov     eax, DR6                        // check if DR registers was
        test    al, 0Fh                         // cause of interrupt 
        jz      not_debug_breakpoint

        cmp     CurrentRing, 3                  // ring0 context not support yet...
        jne     not_debug_breakpoint

        call    GetUserHandler                  // in this way we must transfer
        or      eax, eax                        // control to system handler
        jz      dr_exception_bad

        push    eax
        call    CheckAddressAndMakePageIn
        or      eax, eax
        jz      dr_exception_bad

        push    eax
        call    EnableWrite
        mov     ebx, eax
        pop     eax

        mov     dl, byte ptr [eax]
        mov     DRSavedHandler, eax
        mov     DRSavedByte, dl
        mov     byte ptr [eax], 0xCC

        push    ebx
        call    SetCR0

        mov     eax, si_OldIntTable
        mov     eax, [eax + 4]
        mov     SystemInt1, eax

        mov     DRDebugException, 1

dr_exception_bad:
        pop     es
        pop     ds
        pop     fs
        popad
        mov     esp, OldInterruptStack
        or      dword ptr [esp + 8], 100h
        jmp     cs:[SystemInt1]                 // transfer control to system handler

not_debug_breakpoint:

        push    esp
        call    CodeAnalyzer
        add     esp, 4

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -