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

📄 cmd_trace.cpp

📁 ICEExt for Driver Studio3.2的sourcecode
💻 CPP
字号:

/*++
    Copyright (c) 2005 Godness
    Contact information:
        mail: godness@omen.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:
      cmd_trace.cpp
    
    Abstract: Implements !TRACE, !TRCINIT, !TRCCODE extension commands.
      See tracetut.txt for more detail

    =============== e X T r e m e = t R a C e r = E n g i n e =================

    Revision History of eXTreme tRaCer Engine:

    Godness        01/08/2005
       project was started ...finally!
    
    Godness        20/08/2005
       version 0.01
       now it can trace simple condition such as "eax == 1"

    Godness        29/08/2005
       + added logic condition "||" and "&&"
       + added support brackets (eax == 1 || ebx == 2) && (...)
       + added support register at right part of condition "eax == ax"

    Godness        13/09/2005
       version 0.02 beta
       + added support "Step over" and "Execute till return" commands
       - fixed bugs
    
    Godness        01/10/2005
       Initial release

    Godness        04/03/2006
       + added powerful posibility work with pointers such as *eax == 'string'
       - fixed many bugs

    ===========================================================================
--*/

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

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

#include <windef.h>
#include <ntverp.h>
#include <stdio.h>
#include "keyboard.h"
#include "wdbgexts.h"
#include "softice.h"
#include "defs.h"
#include "tracer.h"

extern void help_TRACE(void);
extern void help_TRCINIT(void);
extern bool Compile(char *buffer);
extern char compiled_code[0x800];

extern int __cdecl CodeAnalyzer (CLIENT_STATE *pClientState);

extern char szGood[];
extern char szBad[];

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

ULONG NumberOfTracedCommand     = 0;
ULONG CountOfCommand            = 0;
ULONG TracerCallBack            = 0;
ULONG EipWhenPRET               = 0xFFFFFFFF;

ULONG ReturnToMakePageIn        = 0;
ULONG MakePageIn                = 0;
ULONG SavedCR0                  = 0;
ULONG CR3ForOurProcess          = 0;
ULONG PreLastEIPValue           = 0;
ULONG CurrentRing               = 0;

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void ExecutePCommand(void);
void ExecutePRETCommand(void);
bool NeedToExecutePCommand(void);
bool si_atoi(PCSTR string, ULONG& value);
void FillClientStateStruct(CLIENT_STATE &client);

////////////////////////////////////////////////////////////////////////////
//
// TRACE
//
//  Trace commands with condition
// 
////////////////////////////////////////////////////////////////////////////

DECLARE_API(trace)
{
    UNREFERENCED_PARAMETER(dwProcessor);
    UNREFERENCED_PARAMETER(dwCurrentPc);
    UNREFERENCED_PARAMETER(hCurrentThread);
    UNREFERENCED_PARAMETER(hCurrentProcess);

    CLIENT_STATE client;
    
    if (*args == '*')
    {
        if (NumberOfTracedCommand > CountOfCommand)
        {
            __asm
            {
                mov     eax, ClientRegs
                push    [eax + 0x24]         //push eflags
                push    [eax + 0x28]         //push cs
                push    [eax + 0x20]         //push eip
                push    [eax + 0x00]         //push eax
                push    [eax + 0x08]         //push ecx
                push    [eax + 0x0C]         //push edx
                push    [eax + 0x04]         //push ebx
                push    [eax + 0x1C]         //push esp
                push    [eax + 0x18]         //push ebp
                push    [eax + 0x10]         //push esi
                push    [eax + 0x14]         //push edi
                call    offset compiled_code
                add     esp, 0x2C
                mov     args, eax
            }

            if (!args)
            {
                DbgPrint(szGood, CountOfCommand);
            }
            else if (++CountOfCommand == NumberOfTracedCommand)
            {
                DbgPrint(szBad);
            }
            else if (EipWhenPRET == -1 || !NeedToExecutePCommand())
            {
                FillClientStateStruct(client);
                if (CodeAnalyzer(&client))      //in case when we start from instruction than need to be amulate
                    ++CountOfCommand;

                ClientRegs->EIP = client.eip;   //restore in softice client's registers
                if (ClientRegs->CS & 1)
                    ClientRegs->ESP = client.esp3;
                //else ??? need to be corrent in CodeAnalizer for ring0
                //    ClientRegs->ESP = client.esp0;

                if (CountOfCommand < NumberOfTracedCommand)
                {
                    TracerCallBack = (ULONG)compiled_code;
                    si_Exec("T");
                }

                return;
            }
            else
            {
                ExecutePCommand();
                return;
            }
            
            CountOfCommand = 0;
            NumberOfTracedCommand = 0;
            EipWhenPRET = (ULONG)(-1);
        }

        return;
    }

    CountOfCommand  = 0;
    EipWhenPRET     = (ULONG)(-1);

    if (si_atoi(args, NumberOfTracedCommand))
    {
        while (*args != 0 && *args != ' ') ++args;
        while (*args == ' ') ++args;
    }

    if (*args == 0 || si_atoi(args, EipWhenPRET))
    {
        if (NumberOfTracedCommand)
        {
            //void *OldInt = GetInterruptHandler(0x6);
            //if (&Int06Handler != OldInt)
            //{
            //    OldInt6 = OldInt;
            //    SetInterruptHandler(0x6, &Int06Handler);
            //}
            //
            //OldInt = GetInterruptHandler(0xD);
            //if (&Int0DHandler != OldInt)
            //{
            //    OldIntD = OldInt;
            //    SetInterruptHandler(0xD, &Int0DHandler);
            //}
            //
            //OldInt = GetInterruptHandler(0x10);
            //if (&Int10Handler != OldInt)
            //{
            //    OldInt10 = OldInt;
            //    SetInterruptHandler(0x10, &Int10Handler);
            //}

            if (EipWhenPRET == -1 || !NeedToExecutePCommand())
            {
                PreLastEIPValue = ClientRegs->EIP;
                CurrentRing = ClientRegs->CS & 3;

                __asm
                {
                    mov     eax, CR3
                    mov     CR3ForOurProcess, eax
                }

                FillClientStateStruct(client);
                if (CodeAnalyzer(&client))      //in case when we start from instruction than need to be amulate
                    ++CountOfCommand;

                ClientRegs->EIP = client.eip;   //restore in softice client's registers
                if (ClientRegs->CS & 1)
                    ClientRegs->ESP = client.esp3;
                //else ??? need to be corrent in CodeAnalizer for ring0
                //    ClientRegs->ESP = client.esp0;

                if (CountOfCommand < NumberOfTracedCommand)
                {
                    TracerCallBack = (ULONG)compiled_code;
                    si_Exec("T");
                }
            }
            else
                ExecutePCommand();
        }
        
        return;
    }

    help_TRACE();
    return;
}

////////////////////////////////////////////////////////////////////////////
//
// TRCINIT
//
//  Compile the tracer condition code
// 
////////////////////////////////////////////////////////////////////////////

DECLARE_API(trcinit)
{
    UNREFERENCED_PARAMETER(dwProcessor);
    UNREFERENCED_PARAMETER(dwCurrentPc);
    UNREFERENCED_PARAMETER(hCurrentThread);
    UNREFERENCED_PARAMETER(hCurrentProcess);

    short saved_fs;

    __asm
    {
        mov     ax, fs
        mov     saved_fs, ax
        mov     eax, 30h
        mov     fs, ax
    }

    if (Compile((char *)args))
    {
        DbgPrint("\n ------------ e X T r e m e - t R a C e r ------------\n");
        DbgPrint("\n                       IS READY!\n");
        DbgPrint("\n Enter the \"!trace\" command to see the blue screen ;-)\n");
        DbgPrint(" -----------------------------------------------------\n\n");
    }
    else
    {
        DbgPrint("\n Error in tracer condition!\n\n");
        help_TRCINIT();
    }

    __asm
    {
        mov     ax, saved_fs
        mov     fs, ax
    }

    return;
}

////////////////////////////////////////////////////////////////////////////
//
// TRCCODE  ...abstract
//
//  Show the code that was compiled by TRCINIT function
// 
////////////////////////////////////////////////////////////////////////////

DECLARE_API(trccode)
{
    UNREFERENCED_PARAMETER(dwProcessor);
    UNREFERENCED_PARAMETER(dwCurrentPc);
    UNREFERENCED_PARAMETER(hCurrentThread);
    UNREFERENCED_PARAMETER(hCurrentProcess);
    UNREFERENCED_PARAMETER(args);

    si_PutToKbdBufferChar('u');
    si_PutToKbdBufferChar(' ');

    for (int i = 7; i >= 0; i--)
    {
        char ch = (char)((int)compiled_code >> 4*i) & 0x0F;
        if (ch < 0xA) 
            ch += 0x30;
        else
            ch += 0x37;
        
        si_PutToKbdBufferChar(ch);
    }

    si_PutToKbdBufferChar(KBD_ENTER);
    return;
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

bool __declspec(naked) NeedToExecutePCommand(void)
{
    __asm 
    {
        mov     eax, ClientRegs
        mov     eax, [eax + 20h]

        cmp     byte ptr [eax], 0xE8
        je      direct_call

        cmp     word ptr [eax], 0x15FF
        jne     false_exit

        mov     eax, [eax + 2]
        mov     eax, [eax]
        jmp     compare_eip

direct_call:
        add     eax, [eax + 1]
        add     eax, 5

compare_eip:
        cmp     eax, EipWhenPRET
        jae     true_exit

false_exit:        
        xor     eax, eax
        ret

true_exit:
        mov     al, 1
        ret
    }
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void ExecutePCommand(void)
{
    si_Exec("P");
    si_Exec("!TRACE *");
    return;
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void ExecutePRETCommand(void)
{
    si_Exec("P RET");
    si_Exec("!TRACE *");
    return;
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

bool si_atoi(PCSTR string, ULONG& value)
{
    __asm
    {
        mov     esi, string
        call    si_Expression2Integer
        jb      syntax_error
        mov     ebx, value
        mov     [ebx], eax
        mov     eax, 1
        jmp     exit
syntax_error:
        mov     eax, 0
exit:
    }
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void FillClientStateStruct(CLIENT_STATE &client)
{
    client.cs = ClientRegs->CS;
    client.ds = ClientRegs->DS;
    client.fs = ClientRegs->FS;
    client.ss = ClientRegs->SS;
    client.es = ClientRegs->ES;

    client.eax = ClientRegs->EAX;
    client.ebp = ClientRegs->EBP;
    client.ebx = ClientRegs->EBX;
    client.ecx = ClientRegs->ECX;
    client.edx = ClientRegs->EDX;
    client.edi = ClientRegs->EDI;
    client.esi = ClientRegs->ESI;
    
    client.eip = ClientRegs->EIP;
    client.esp0 = ClientRegs->ESP; // ??? need to be correct
    client.esp3 = ClientRegs->ESP; // ???
    client.eflags = ClientRegs->EFLAGS;

    return;
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

⌨️ 快捷键说明

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