📄 cmd_suspend.cpp
字号:
/*++
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:
cmd_suspend.cpp
Abstract: Implements !SUSPEND, !RESUME extension commands.
Revision History:
Sten 05/06/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 <windef.h>
#include <ntverp.h>
#include <stdio.h>
#include "wdbgexts.h"
#include "defs.h"
#include "softice.h"
#include "ntoskrnl.h"
/////////////////////////////////////////////////////////////////////////
//
// Static definitions
//
/////////////////////////////////////////////////////////////////////////
static UNICODE_STRING SuspendEventName;
static PKEVENT objSuspendEvent = NULL;
static HANDLE hSuspendEvent = NULL;
// A place to save client registers
static SiRegs SavedClientRegs;
/////////////////////////////////////////////////////////////////////////
//
// Suspend stub code
// Executes at the client context
//
/////////////////////////////////////////////////////////////////////////
#define SIZE_OF_STUB 100 // must be more or equal to the real stub code size
#define OFS_INT3 12 // offset of the INT3 instruction within the stub code
// NOTE: Don't forget to change it if stub changes!
static void __declspec(naked) SUSPEND_STUB(void)
{
__asm
{
push eax ; EAX = hSuspendEvent
push ecx ; ECX = NtClose
push 0 ; Timeout = NULL
push 0 ; Alertable = FALSE
push eax ; hSuspendEvent
call ebx ; = call NtWaitForSingleObject
pop ecx
; EAX is already on the stack
call ecx ; = call NtClose
int 3 ; here SoftICE will popup and
; restore client registers from
; *si_PageinTempRegz
; *si_oPageinINT3 MUST point to
; this INT3 instruction
}
}
////////////////////////////////////////////////////////////////////////////
//
// SUSPEND
//
// Suspend current thread
//
////////////////////////////////////////////////////////////////////////////
DECLARE_API(suspend)
{
UNREFERENCED_PARAMETER(dwProcessor);
UNREFERENCED_PARAMETER(dwCurrentPc);
UNREFERENCED_PARAMETER(hCurrentThread);
UNREFERENCED_PARAMETER(hCurrentProcess);
if(args[0]=='!') args += 10; // "! suspend "
if (hSuspendEvent)
{
DbgPrint("ERROR: Only one suspended thread is currently supported.\n");
return;
}
if (*si_CodeFlags != 3)
{
DbgPrint("This command is only supported in 32-bit mode.\n");
return;
}
if (*si_CurrentContext != *si_PopupContext)
{
DbgPrint("You must be in the popup context to execute this command.\n");
return;
}
if ((ClientRegs->EFLAGS & 0x00000200) == 0)
{
DbgPrint("Interrupts must be enabled to execute this command.\n");
return;
}
if (si_GetCurrentIRQLLevel() > PASSIVE_LEVEL)
{
DbgPrint("IRQL must be PASSIVE_LEVEL to execute this command.\n");
return;
}
if ((ClientRegs->CS & 3) != 0)
{ // client is ring 3 code
//-----------------------------------------//
// Create my Notification event //
//-----------------------------------------//
RtlInitUnicodeString(&SuspendEventName,
L"\\BaseNamedObjects\\SUSPENDEVENT");
objSuspendEvent = IoCreateNotificationEvent(
&SuspendEventName, &hSuspendEvent);
if (objSuspendEvent == NULL)
{
DbgPrint("\nError. IoCreateNotificationEvent failed.\n");
return;
}
KeClearEvent(objSuspendEvent);
//-----------------------------------------//
// Save client regs //
//-----------------------------------------//
RtlMoveMemory(&SavedClientRegs, ClientRegs, sizeof(SiRegs));
//-----------------------------------------//
// PUSH SUSPEND_STUB //
//-----------------------------------------//
InitSEH();
__try
{
ClientRegs->ESP -= SIZE_OF_STUB;
RtlMoveMemory((void*)ClientRegs->ESP, &SUSPEND_STUB, SIZE_OF_STUB);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
ClientRegs->ESP += SIZE_OF_STUB;
DbgPrint("Client stack is not accessible.\n");
CleanupSEH();
return;
}
CleanupSEH();
//-----------------------------------------//
// Setup parameters to stub code //
// and set clients EIP to point to my stub //
//-----------------------------------------//
ClientRegs->EAX=(DWORD)hSuspendEvent;
ClientRegs->EBX=(DWORD)NtWaitForSingleObject;
ClientRegs->ECX=(DWORD)NTDLL_NtClose;
ClientRegs->EIP=ClientRegs->ESP;
}
else
{
DbgPrint("Error. This command doesn't work on system threads.\n");
return;
}
*si_ExecuteMoreCommands = 0; // Exit from SoftICE after return
return;
}
////////////////////////////////////////////////////////////////////////////
//
// RESUME
//
// Resume current thread execution
//
////////////////////////////////////////////////////////////////////////////
DECLARE_API(resume)
{
UNREFERENCED_PARAMETER(dwProcessor);
UNREFERENCED_PARAMETER(dwCurrentPc);
UNREFERENCED_PARAMETER(hCurrentThread);
UNREFERENCED_PARAMETER(hCurrentProcess);
UNREFERENCED_PARAMETER(args);
if (si_GetCurrentIRQLLevel() > DISPATCH_LEVEL)
{
DbgPrint("IRQL must be <= DISPATCH_LEVEL to execute this command.\n");
return;
}
if (hSuspendEvent)
{
hSuspendEvent = 0;
// copy saved client registers to si_PageinTempRegz
RtlMoveMemory(si_PageinTempRegz, &SavedClientRegs, sizeof(SiRegs));
// setup pageinINT3 offset so that SoftICE will popup
// when INT3 at this offset is executed
*si_oPageinINT3 = SavedClientRegs.ESP-SIZE_OF_STUB+OFS_INT3;
*si_Pagein_InProgress = 1; // tell SoftICE that pagein command is in
// progress :)
// signal to our ring3 stub to resume execution
KeSetEvent(objSuspendEvent, IO_NO_INCREMENT, FALSE);
*si_ExecuteMoreCommands = 0; // exit from SoftICE after return
}
else
{
DbgPrint("Nothing to resume.\n");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -