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

📄 taskswch.cpp

📁 ICEExt for Driver Studio3.2的sourcecode
💻 CPP
字号:
/*++
    This file is mostly derived from mamaich's debugger codename BlindStudio.

    Copyleft  (c) 2002 Sten
    Contact information:
        mail: stenri@mail.ru

    Copyright (c) 2001 mamaich
    Contact information:
    	web: www.reversing.net/mamaich
        mail: mamaich@reversing.net
        ICQ# 70241285

    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:
    taskswch.cpp

Abstract:  Task switch hook. Clears my breakpoint on task switching. 

Revision History:

 Sten        05/06/2002
      The file is fully rewritten for better understanding.
 mamaich     14/06/2001
      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 "search.h"
#include "bpr.h"
#include "ntoskrnl.h"
#include "undoc.h"

void MySwapContextHook_NT();
void MySwapContextHook_W3K();
void MySwapContextEndHook();

static ULONG_PTR SwapContextPtr=0;
static ULONG_PTR SwapContextCnt=0;

static PVOID pSwapContextHook      =0;
static PVOID pSwapContextSavedBytes=0;

// The code "mov byte ptr es:[esi+2Dh], 2" is near the start of 
// SwitchContext function in NTOSKRNL.EXE. It is the only place we see
// these bytes in NT4 & 2K and the first place in XP
UCHAR SwapContextStart_NT[] =
{
    0x26, 0xc6, 0x46, 0x2d, 0x02          // mov byte ptr es:[esi+2Dh], 2
};

// MS changed SwapContext routine implementation in Windows 2003 Server
// So we should use other template to search it
UCHAR SwapContextStart_W3K[] =
{
    0x51,                                 // push    ecx
                               
                                          //loc_407F51:                             
    0x80, 0x7E, 0x5D, 0x00,               // cmp     byte ptr [esi+5Dh], 0
    0x74, 0x04,                           // jz      short loc_407F5B
    0xF3, 0x90,                           // pause
    0xEB                                  // jmp     short loc_407F51
};


////////////////////////////////////////////////////////////////////////////
//
// InitSwapContextHook
//
//   Hooks the SwapContext function
//
//   Note: InitNTosKernel MUST be called before InitSwapContextHook
//
////////////////////////////////////////////////////////////////////////////

NTSTATUS InitSwapContextHook()
{
    SwapContextPtr = (ULONG_PTR)((ULONG_PTR)RabSearch(SwapContextStart_NT, sizeof(SwapContextStart_NT),
                                              (unsigned char *)hNTOSKRNL, NTOS_TEXT_SIZE) + (ULONG)hNTOSKRNL); 

    if ((ULONG_PTR)SwapContextPtr < (ULONG_PTR)hNTOSKRNL)
    {
        // try to locate Windows 2003 Server SwapContext routine
        SwapContextPtr = (ULONG_PTR)((ULONG_PTR)RabSearch(SwapContextStart_W3K, sizeof(SwapContextStart_W3K),
                                               (unsigned char *)hNTOSKRNL, NTOS_TEXT_SIZE) + (ULONG_PTR)hNTOSKRNL); 

        if ((ULONG_PTR)SwapContextPtr < (ULONG_PTR)hNTOSKRNL)
        {
            DbgPrint("InitSwapContext: can't find SwapContext function %08X.\n",SwapContextPtr);
            SwapContextPtr = 0;
            return STATUS_PROCEDURE_NOT_FOUND;
        }

        // install W3K specific SwapContext hook
        pSwapContextHook = (PVOID)&MySwapContextHook_W3K;
        pSwapContextSavedBytes = (PVOID)&SwapContextStart_W3K;
    }
    else
    {
        // install NT+ generic SwapContext hook
        pSwapContextHook = (PVOID)&MySwapContextHook_NT;
        pSwapContextSavedBytes = (PVOID)&SwapContextStart_NT;
    }

    DbgPrint("SwapContextPtr:                               %08X\n", SwapContextPtr);

    SwapContextCnt = SwapContextPtr + 5;

    __asm cli; // Disable task switching
    
    ULONG Addr=(ULONG_PTR)pSwapContextHook - (SwapContextPtr+5);
    *(PUCHAR)SwapContextPtr=(UCHAR)0xe9;
    *(PULONG)(SwapContextPtr+1)=Addr;

    __asm sti; 

    return STATUS_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////
//
// RemoveSwapContextHook
//
//   Uninstall swap context hook
//
////////////////////////////////////////////////////////////////////////////

void RemoveSwapContextHook()
{
    if (SwapContextPtr)
    {
         __asm cli;  // Disable task switching

         memcpy((void*)SwapContextPtr, pSwapContextSavedBytes,5);
       
         __asm sti;
             SwapContextPtr=0;
    }
}

////////////////////////////////////////////////////////////////////////////
//
// HandleContextSwap_NT
//
//   This code is called when windows decides to swap context of 2 threads.
//   I should deactivate breakpoints on range in the old process
//   NT+ version
//  
////////////////////////////////////////////////////////////////////////////

void __stdcall HandleContextSwap_NT(ETHREAD *New, ETHREAD *Old)
{
	UNREFERENCED_PARAMETER(Old);

    bpr_DeactivateAll(); // Deativate all BPRs in the old process

    PULONG Stack=(PULONG)New->Tcb.KernelStack;

    // Stack of SwapContext in NT4-XP looks like:
    // esp+8 -> return address | Stack[2]
    // esp+4 -> EFLAGS         | Stack[1]
    // esp   -> ECX            | Stack[0]

    // I'll insert address of my hook function between EFLAGS and return addreses

    New->Tcb.KernelStack=((char*)New->Tcb.KernelStack)-4;
    memmove(New->Tcb.KernelStack,Stack,8);
    Stack[1]=(ULONG)MySwapContextEndHook;
}

////////////////////////////////////////////////////////////////////////////
//
// HandleContextSwap_W3K
//
//   This code is called when windows decides to swap context of 2 threads.
//   I should deactivate breakpoints on range in the old process
//   Windows 2003 Server version
//
////////////////////////////////////////////////////////////////////////////

void __stdcall HandleContextSwap_W3K(ETHREAD *New, ETHREAD *Old)
{
	UNREFERENCED_PARAMETER(Old);

    bpr_DeactivateAll(); // Deativate all BPRs in the old process

    PULONG Stack=*(PULONG*)((ULONG)New+0x20); //->Tcb.KernelStack;
                                              // ETHREAD structure was changed
                                              // in W3K

    // Stack of SwapContext in W3K looks like:
    // esp+8 -> return address | Stack[2]
    // esp+4 -> ???            | Stack[1]
    // esp   -> ECX            | Stack[0]

    // I'll insert address of my hook function between EFLAGS and return addreses
    *(PULONG*)((ULONG)New+0x20) -= 1;
    memmove(*(PULONG*)((ULONG)New+0x20),Stack,8);
    Stack[1]=(ULONG)MySwapContextEndHook;
}

/////////////////////////////////////////////////////////////////////////////
//
// HandleContextSwapEnd
//
//   This code is called after context is swapped. It reenables all my
//   breakpoints in the new process
//
/////////////////////////////////////////////////////////////////////////////

void __stdcall HandleContextSwapEnd()
{
     bpr_ActivateAll(); // Activate all BPRs in the new process
}

/////////////////////////////////////////////////////////////////////////////
//
// MySwapContextHook_NT
//
//   Hook. Called from NTOSKRNL!SwapContext
//
/////////////////////////////////////////////////////////////////////////////

void __declspec(naked) MySwapContextHook_NT()
{
    __asm
    {
          mov          byte ptr es:[esi+2Dh], 2
          pushfd
          pushad
          push         edi
          push         esi
          call         HandleContextSwap_NT
          popad
          popfd
          jmp          [SwapContextCnt]
    }
}

/////////////////////////////////////////////////////////////////////////////
//
// MySwapContextHook_W3K
//
//   Hook. Called from NTOSKRNL!SwapContext
//
/////////////////////////////////////////////////////////////////////////////

void __declspec(naked) MySwapContextHook_W3K()
{
    __asm
    {
          push         ecx

swap_wait:
          ; this loop stolen directly from W3K ntoskrnl.
          cmp          byte ptr [esi+5Dh], 0 ; _KTHREAD.SwapBusy
          jz           short swap_ok
          pause
          jmp          short swap_wait

swap_ok:
          pushfd
          pushad
          push         edi
          push         esi
          
          call         HandleContextSwap_W3K

          popad
          popfd

          cmp          byte ptr [esi+5Dh], 0 ; _KTHREAD.SwapBusy
          jmp          [SwapContextCnt]
    }
}

/////////////////////////////////////////////////////////////////////////////
//
// MySwapContextEndHook
//
//   Hook. Called on return from NTOSKRNL!SwapContext
//
/////////////////////////////////////////////////////////////////////////////

void __declspec(naked) MySwapContextEndHook()
{
    __asm
    {
          pushfd
          pushad
          call    HandleContextSwapEnd
          popad
          popfd
          retn
    }
}

⌨️ 快捷键说明

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