📄 softice.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:
softice.cpp
Abstract: Interface to functions inside SoftICE body.
Revision History:
Sten 05/06/2002
Initial release
--*/
/////////////////////////////////////////////////////////////////////////////
// SoftICE interface library. //
/////////////////////////////////////////////////////////////////////////////
extern "C"{
#pragma warning ( push, 3 )
#include <ntddk.h>
#pragma warning ( pop )
}
#pragma warning ( disable: 4514 ) // unreferenced inline function has been removed
#pragma warning ( disable: 4127 ) // conditional expression is constant
#include "defs.h"
#include "img.h"
#include "search.h"
#include "keyboard.h"
#include <stdio.h>
#include <stdlib.h>
#define __SOFTICE_C__
#include "softice.h"
#undef __SOFTICE_C__
ULONG si_InitCompleted = FALSE;
static ULONG ulBangFuncsArrayEntrySize = 48; // sizeof one Bang KDE function array entry
/////////////////////////////////////////////////////////////////////////////
// Return pointer to first digit in string
/////////////////////////////////////////////////////////////////////////////
inline PCHAR si_GetFirstDigit(PCHAR str)
{
if (!str) return NULL;
while (*str++) if (isdigit((UCHAR)*str)) return str;
return NULL;
}
/////////////////////////////////////////////////////////////////////////////
// SoftICE has a bug in __chkstk implementation that leads to BSOD if KDE
// calls this function. Fix bug, so that my MP3 decoder can work correctly
/////////////////////////////////////////////////////////////////////////////
extern "C" __cdecl _chkstk();
VOID si_FixChkStkBug()
{
PUCHAR pChkStkAddr = (PUCHAR)**(PULONG*)(((PCHAR)_chkstk)+2);
if (RtlCompareMemory(pChkStkAddr, PAT__chkstk, sizeof(PAT__chkstk)-sizeof(char)) == 0)
{
DbgPrint("Fixing SoftICE _chkstk bug (%08X)...\n", pChkStkAddr);
*(pChkStkAddr + OFS__chkstk + 0) = 0x89; // mov esp, edx
*(pChkStkAddr + OFS__chkstk + 1) = 0xD4;
}
}
extern"C" __cdecl HeapReAlloc();
// ^^ I need only its addr within SoftIce:
// In VC6 this is compiled to: jmp [NtIce!HeapRealloc]
// Or I may use address of dprintf...
// Using of HeapReAlloc is better, because I need at least one import from
// NtIce.sys
/////////////////////////////////////////////////////////////////////////////
//
// Init
// Locates SoftICE start address in memory, searches for some useful parts
// inside its body
//
/////////////////////////////////////////////////////////////////////////////
ULONG si_Init()
{
if(si_InitCompleted) return FALSE; // not to be inited twice
si_FixChkStkBug(); // fix _chkstk bug
// Find NTIce start in memory
si_IceBase = UtGetModuleBaseByAddr(**(DWORD**)(((char*)HeapReAlloc)+2));
if ((ULONG)si_IceBase == 0)
{
DbgPrint("ERROR: Can't find SoftICE MZ header in memory.\n");
return FALSE;
}
DbgPrint("SoftICE MZ-header found at %08X\n", si_IceBase);
IMAGE_DOS_HEADER *MZ=(IMAGE_DOS_HEADER*)si_IceBase;
#include <pshpack1.h>
const struct HDR
{
DWORD signature;
IMAGE_FILE_HEADER hdr;
IMAGE_OPTIONAL_HEADER opt_head;
IMAGE_SECTION_HEADER section_header[2];
} *PE;
#include <poppack.h>
PE=(HDR*)(MZ->e_lfanew+si_IceBase);
si_CodeBase = (PUCHAR)si_IceBase + PE->opt_head.BaseOfCode;
si_CodeSize = PE->opt_head.SizeOfCode;
si_DataBase = (PUCHAR)si_IceBase + PE->opt_head.BaseOfData;
si_DataSize = PE->opt_head.SizeOfInitializedData;
DbgPrint("si_CodeBase found at %08X\n", (ULONG_PTR)si_CodeBase);
DbgPrint("si_DataBase found at %08X\n", (ULONG_PTR)si_DataBase);
//-------------------------------------------------------------------------
// Extract version info from SoftICE banner
//-------------------------------------------------------------------------
unsigned char BANNER[]="SoftICE (R) - DriverStudio (tm) ";
char *si_Banner= (char *)(RabSearch(BANNER, sizeof(BANNER)-sizeof(char), si_DataBase, si_DataSize)
+ si_DataBase);
if ((ULONG_PTR)si_Banner < (ULONG_PTR)si_DataBase)
{
DbgPrint("ERROR: Can't find SoftICE banner in memory.\n");
}
ULONG si_Ver1 = 0;
ULONG si_Ver2 = 0;
ULONG si_Ver3 = 0;
DbgPrint("si_Banner: %08X\n", si_Banner);
si_Banner = si_GetFirstDigit(si_Banner);
if (si_Banner)
{
si_Ver1 = (ULONG)(PUCHAR)*si_Banner - '0';
si_Banner += 2; // skip 'X.'
si_Ver2 = (ULONG)(PUCHAR)*si_Banner - '0';
si_Banner += 2; // skip 'X.'
si_Ver3 = (ULONG)(PUCHAR)*si_Banner - '0';
si_Banner += 9; // skip 'X (Build '
si_IceBuild = atoi(si_Banner);
}
si_IceVersion = si_Ver1 * 100 + si_Ver2 * 10 + si_Ver3;
DbgPrint("Binding to SoftICE %u.%u.%u (Build %u)\n",
si_Ver1,
si_Ver2,
si_Ver3,
si_IceBuild);
if (si_IceVersion >= 432)
ulBangFuncsArrayEntrySize = 268;
DbgPrint("ulBangFuncsArrayEntrySize: %u\n", ulBangFuncsArrayEntrySize);
//**********************************************
#define SI_REPORT_NOT_FOUND(PAT_Name) DbgPrint("ERROR: Can't find " #PAT_Name " template in memory.\n");
#define SI_FIND_CODE_PATTERN(si_PatName, PAT_Name, TYPE_Pat, OFS_Pat) \
do \
{ \
si_PatName = TYPE_Pat (RabSearch(PAT_Name, sizeof(PAT_Name), \
si_CodeBase, si_CodeSize) + si_CodeBase - OFS_Pat); \
\
if ((ULONG_PTR)si_PatName < (ULONG_PTR)si_CodeBase) \
{ \
SI_REPORT_NOT_FOUND(PAT_Name); \
return FALSE; \
} \
\
DbgPrint("%-45s %08X\n", #PAT_Name " found at:", (ULONG_PTR)si_PatName); \
} while (0)
#define IF_SI_CODE_PATTERN_FOUND(si_PatName, PAT_Name, TYPE_Pat, OFS_Pat) \
if ( \
((ULONG_PTR)(si_PatName = TYPE_Pat (RabSearch(PAT_Name, sizeof(PAT_Name), \
si_CodeBase, si_CodeSize) + si_CodeBase - OFS_Pat)) >= (ULONG_PTR)si_CodeBase) \
&& \
DbgPrint("%-45s %08X\n", #PAT_Name " found at:", (ULONG_PTR)si_PatName) \
)
#define SI_EXTRACT_CALL_OPERAND(Addr, si_Name, TYPE_Name) \
do \
{ \
ULONG_PTR dwRelOfs = *(PULONG)(Addr); \
si_Name = TYPE_Name((ULONG_PTR)Addr + 4 + (ULONG_PTR)dwRelOfs); \
DbgPrint("%-45s %08X\n", #si_Name" resolved at:", (ULONG_PTR)si_Name); \
}while (0)
//**********************************************
ULONG_PTR tmp;
SI_FIND_CODE_PATTERN(si_GetChar, PAT_GetChar, TYPE_GetChar, OFS_GetChar);
SI_FIND_CODE_PATTERN(si_KbHit, PAT_KbHit, TYPE_KbHit, OFS_KbHit);
SI_FIND_CODE_PATTERN(si_CallVideoDriver_1, PAT_CallVideoDriver_1, TYPE_CallVideoDriver_1, 0);
SI_EXTRACT_CALL_OPERAND((ULONG_PTR)si_CallVideoDriver_1+OFS_UpdateScreen, si_UpdateScreen, TYPE_UpdateScreen);
SI_FIND_CODE_PATTERN(si_MoveCursor, PAT_MoveCursor, TYPE_MoveCursor, OFS_MoveCursor);
SI_FIND_CODE_PATTERN(tmp, PAT_Expression2Integer, ULONG_PTR, 0);
SI_EXTRACT_CALL_OPERAND(tmp+OFS_Expression2Integer, si_Expression2Integer, TYPE_Expression2Integer);
SI_FIND_CODE_PATTERN(tmp, PAT_ProcessIF, ULONG_PTR, 0);
SI_EXTRACT_CALL_OPERAND(tmp+OFS_ProcessIF, si_ProcessIF, TYPE_ProcessIF);
IF_SI_CODE_PATTERN_FOUND(tmp, PAT_ClearCompiledIF_DS32, ULONG_PTR, 0)
{
SI_EXTRACT_CALL_OPERAND(tmp+OFS_ClearCompiledIF_DS32, si_ClearCompiledIF, TYPE_ClearCompiledIF);
}
else
IF_SI_CODE_PATTERN_FOUND(tmp, PAT_ClearCompiledIF, ULONG_PTR, 0)
{
SI_EXTRACT_CALL_OPERAND(tmp+OFS_ClearCompiledIF, si_ClearCompiledIF, TYPE_ClearCompiledIF);
}
else
{
SI_REPORT_NOT_FOUND(PAT_ClearCompiledIF);
return FALSE;
}
IF_SI_CODE_PATTERN_FOUND(tmp, PAT_CheckCondition_DS32, ULONG_PTR, 0)
{
SI_EXTRACT_CALL_OPERAND(tmp+OFS_CheckCondition, si_CheckCondition, TYPE_CheckCondition);
}
else
IF_SI_CODE_PATTERN_FOUND(tmp, PAT_CheckCondition, ULONG_PTR, 0)
{
SI_EXTRACT_CALL_OPERAND(tmp+OFS_CheckCondition, si_CheckCondition, TYPE_CheckCondition);
}
else
{
SI_REPORT_NOT_FOUND(PAT_CheckCondition);
return FALSE;
}
SI_FIND_CODE_PATTERN(tmp, PAT_QueueMacro, ULONG_PTR, 0);
si_QueueMacroExec = *(PULONG*)(tmp + OFS_QueueMacroExec);
si_fMacroQueued = *(PULONG*)(tmp + OFS_fMacroQueued);
DbgPrint("si_QueueMacroExec found at: %08X\n", si_QueueMacroExec);
DbgPrint("si_fMacroQueued found at: %08X\n", si_fMacroQueued);
SI_FIND_CODE_PATTERN(si_Patch_DE_JZ, PAT_PatchDE, PUCHAR, 0);
if (si_Patch_DE_JZ) si_Patch_DE_JZ += OFS_PatchDE_JZ;
//-------------------------------------------------------------------------
// ExecuteMacro
//-------------------------------------------------------------------------
IF_SI_CODE_PATTERN_FOUND(si_ExecuteMacro, PAT_ExecuteMacro, TYPE_ExecuteMacro, OFS_ExecuteMacro)
{
// ok, pattern found
}
else
IF_SI_CODE_PATTERN_FOUND(si_ExecuteMacro, PAT_ExecuteMacro_DS30, TYPE_ExecuteMacro, OFS_ExecuteMacro)
{
// ok, pattern found
}
else
{
SI_REPORT_NOT_FOUND(PAT_ExecuteMacro);
return FALSE;
}
//-------------------------------------------------------------------------
// NTIce
//-------------------------------------------------------------------------
SI_FIND_CODE_PATTERN(si_NTIce, PAT_NTIce, TYPE_NTIce, OFS_NTIce);
SI_EXTRACT_CALL_OPERAND((ULONG_PTR)si_NTIce+OFS_NTIceMain, si_NTIceMain, (void(__stdcall*)(ULONG_PTR)));
SI_FIND_CODE_PATTERN(si_PrintChar, PAT_PrintChar, TYPE_PrintChar, OFS_PrintChar);
si_ExecuteMoreCommands = *(BYTE**)((ULONG_PTR)si_PrintChar+OFS_ExecuteMoreCommands);
DbgPrint("fExecuteMoreCommands found at %08X\n", (ULONG_PTR)si_ExecuteMoreCommands);
SI_FIND_CODE_PATTERN(si_DelayMilliSec, PAT_DelayMilliSec, TYPE_DelayMilliSec, OFS_DelayMilliSec);
SI_FIND_CODE_PATTERN(si_ReadFromKbdBuffer_char, PAT_ReadFromKbdBuffer_char, TYPE_ReadFromKbdBuffer_char, OFS_ReadFromKbdBuffer_char);
SI_FIND_CODE_PATTERN(si_WriteToKbdBuffer_char, PAT_WriteToKbdBuffer_char, TYPE_WriteToKbdBuffer_char, OFS_WriteToKbdBuffer_char);
SI_FIND_CODE_PATTERN(si_EmptyKbdBuffer, PAT_EmptyKbdBuffer, TYPE_EmptyKbdBuffer, OFS_EmptyKbdBuffer);
SI_FIND_CODE_PATTERN(si_ActivateBPs, PAT_ActivateBPs, TYPE_ActivateBPs, OFS_ActivateBPs);
SI_FIND_CODE_PATTERN(si_DeactivateBPs, PAT_DeactivateBPs, TYPE_DeactivateBPs, OFS_DeactivateBPs);
SI_FIND_CODE_PATTERN(si_ShowBreakReason, PAT_ShowBreakReason, TYPE_ShowBreakReason, OFS_ShowBreakReason);
si_BreakReason = *(PULONG*)((ULONG_PTR)si_ShowBreakReason+OFS_BreakReason);
DbgPrint("BreakReason found at %08X\n", (ULONG_PTR)si_BreakReason);
SI_FIND_CODE_PATTERN(si_CallVideoDriver_1x, PAT_CallVideoDriver_1x, TYPE_CallVideoDriver_1x, OFS_CallVideoDriver_1x);
SI_EXTRACT_CALL_OPERAND((ULONG_PTR)si_CallVideoDriver_1x+OFS_CallVideoDriver, si_CallVideoDriver, TYPE_CallVideoDriver);
SI_FIND_CODE_PATTERN(si_SaveClientRegisters, PAT_SaveClientRegisters, TYPE_SaveClientRegisters, OFS_SaveClientRegisters);
SI_FIND_CODE_PATTERN(si_SayESI, PAT_SayESI, TYPE_SayESI, OFS_SayESI);
si_NormCharColor = *(BYTE **)((ULONG_PTR)si_SayESI+OFS_NormCharColor);
DbgPrint("bNormCharColor found at %08X\n", (ULONG_PTR)si_NormCharColor);
SI_FIND_CODE_PATTERN(si_SayESIpause, PAT_SayESIpause, TYPE_SayESIpause, OFS_SayESIpause);
SI_FIND_CODE_PATTERN(si_GetCurrentIRQLLevel, PAT_GetCurrentIRQLLevel, TYPE_GetCurrentIRQLLevel, OFS_GetCurrentIRQLLevel);
SI_FIND_CODE_PATTERN(tmp, PAT_TraceFlag, ULONG_PTR, 0);
si_TraceFlag = *(BYTE**)(tmp+OFS_TraceFlag);
DbgPrint("dwTraceFlag found at %08X\n", (ULONG_PTR)si_TraceFlag);
SI_FIND_CODE_PATTERN(tmp, PAT_ClientRegs, ULONG_PTR, 0);
ClientRegs = *(SiRegs**)(tmp+OFS_ClientRegs);
SI_FIND_CODE_PATTERN(tmp, PAT_VmemPtr, ULONG_PTR, 0);
si_Screen = *(PULONG*)(tmp+OFS_VmemPtr);
DbgPrint("Screen ptr at %08X\n", (ULONG_PTR)(si_Screen));
DbgPrint("Screen found at %08X\n", (ULONG_PTR)(*si_Screen));
SI_FIND_CODE_PATTERN(tmp, PAT_Width, ULONG_PTR, 0);
si_Width = *(unsigned char**)(tmp+OFS_Width);
DbgPrint("Screen width: %d\n", *si_Width);
SI_FIND_CODE_PATTERN(tmp, PAT_Height, ULONG_PTR, 0);
si_Height = *(unsigned char**)(tmp+OFS_Height);
DbgPrint("Screen height: %d\n", *si_Height);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -