📄 protect.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:
protect.cpp
Abstract: Protect SoftICE from detection:
- int 1 single step
- int 1 EIP+2
- int 3 backdoor interface
- MeltICE, MeltSiwVID, MeltSiwSYM
Revision History:
Sten 21/09/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 "search.h"
#include "ntoskrnl.h"
#include "softice.h"
#include "undoc.h"
///////////////////////////////////////////////////////////////////////
// Globals
///////////////////////////////////////////////////////////////////////
ULONG protect_MeltICE = 0;
ULONG protect_NtQuerySystemInformation = 0;
ULONG protect_INT3 = 0;
ULONG protect_CR4_DE = 0;
ULONG protect_UEF_Flag = 0; // Warning: DO NOT change!
///////////////////////////////////////////////////////////////////////
// Typedefs
///////////////////////////////////////////////////////////////////////
typedef NTSTATUS (*NTCREATEFILE)(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocationSize OPTIONAL,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer OPTIONAL,
ULONG EaLength
);
typedef NTSTATUS (*NTSETCONTEXTTHREAD)(
IN HANDLE ThreadHandle,
IN PCONTEXT Context
);
typedef NTSTATUS (*NTGETCONTEXTTHREAD)(
IN HANDLE ThreadHandle,
OUT PCONTEXT Context
);
typedef NTSTATUS (*NTQUERYSYSTEMINFORMATION)(
IN SYSTEMINFOCLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
typedef NTSTATUS (*NTCONTINUE)(
IN PCONTEXT Context,
IN ULONG InAlert
);
#define INVALID_SERVICE_NUM ((ULONG)(-1))
// NTCREATEFILE
static ULONG NtCreateFileServiceNum = INVALID_SERVICE_NUM;
static NTCREATEFILE OldNtCreateFile = 0;
// NTQUERYSYSTEMINFORMATION
static ULONG NtQuerySystemInfoServiceNum = INVALID_SERVICE_NUM;
static NTQUERYSYSTEMINFORMATION OldNtQuerySystemInformation = 0;
// NWQUERYDIRECTORYOBJECT
static ULONG NtQueryDirObjectServiceNum = INVALID_SERVICE_NUM;
static NTQUERYDIRECTORYOBJECT OldNtQueryDirectoryObject = 0;
// NTCONTINUE
static ULONG NtContinueServiceNum = INVALID_SERVICE_NUM;
static NTCONTINUE OldNtContinue = 0;
// Old int3 handler
static void *OsInt3 = 0;
static void *OldInt3 = 0;
static char szMethodMeltICE[] = "PROTECT: MeltICE\n";
// no carier return needed below (si_SayESI used to print these strings)
static char szMethodINT3[] = "PROTECT: Backdoor interface";
static char szMethodBCHK[] = "PROTECT: BoundChecker interface";
// some symbols we are resolving
static CCHAR aKernel32UnhandledExceptionFilter[] = "kernel32!UnhandledExceptionFilter";
static CCHAR aTrap03[] = "ntoskrnl!_KiTrap03";
///////////////////////////////////////////////////////////////////////
//
// NewNtCreateFile
//
// New NtCreateFile service.
//
///////////////////////////////////////////////////////////////////////
static WCHAR FILT_STR1[] = L"\\??\\NTICE";
static WCHAR FILT_STR2[] = L"\\??\\SIWVIDSTART";
static WCHAR FILT_STR3[] = L"\\??\\SIWSYM";
#define FILT_STR1_SIZE ((sizeof(FILT_STR1)-1)/sizeof(WCHAR))
#define FILT_STR2_SIZE ((sizeof(FILT_STR2)-1)/sizeof(WCHAR))
#define FILT_STR3_SIZE ((sizeof(FILT_STR3)-1)/sizeof(WCHAR))
NTSTATUS NewNtCreateFile(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocationSize OPTIONAL,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer OPTIONAL,
ULONG EaLength)
{
NTSTATUS rc;
if (protect_MeltICE)
{
if (ObjectAttributes->ObjectName->Buffer)
{
if (
(_wcsnicmp(ObjectAttributes->ObjectName->Buffer,
FILT_STR1, FILT_STR1_SIZE) == 0) ||
(_wcsnicmp(ObjectAttributes->ObjectName->Buffer,
FILT_STR2, FILT_STR2_SIZE) == 0) ||
(_wcsnicmp(ObjectAttributes->ObjectName->Buffer,
FILT_STR3, FILT_STR3_SIZE) == 0)
)
{
DbgPrint(szMethodMeltICE);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
}
}
rc=((NTCREATEFILE)(OldNtCreateFile)) (
FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
AllocationSize,
FileAttributes,
ShareAccess,
CreateDisposition,
CreateOptions,
EaBuffer,
EaLength);
return rc;
}
NTSTATUS NewNtQuerySystemInformation(
IN SYSTEMINFOCLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL)
{
NTSTATUS rc;
rc=((NTQUERYSYSTEMINFORMATION)(OldNtQuerySystemInformation)) (
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength);
if (protect_NtQuerySystemInformation)
{
if (SystemInformationClass == SystemModuleInformation)
{
if ((SystemInformationLength != 0) && (SystemInformation))
{
PSYSTEM_MODULE_INFORMATION pModInfo
= (PSYSTEM_MODULE_INFORMATION)SystemInformation;
ULONG count = (SystemInformationLength - 4) / sizeof(SYSTEM_MODULE);
for (ULONG i=0; i<count; i++)
{
if (!_stricmp((char*)pModInfo->aSM[i].abName + pModInfo->aSM[i].wNameOffset,
"NTICE.SYS"))
{
strcpy((char*)pModInfo->aSM[i].abName + pModInfo->aSM[i].wNameOffset,
"TROF2.SYS");
break;
}
}
}
}
}
return rc;
}
///////////////////////////////////////////////////////////////////////
//
// NewNtQueryDirectoryObject
//
// Hooks NtQueryDirectoryObject.
//
///////////////////////////////////////////////////////////////////////
static WCHAR STR_NTICE[] = L"NTICE";
static WCHAR STR_DRIVER[] = L"DRIVER";
#define STR_NTICE_SIZE ((sizeof(STR_NTICE)-1)/sizeof(WCHAR))
#define STR_DRIVER_SIZE ((sizeof(STR_DRIVER)-1)/sizeof(WCHAR))
NTSTATUS NewNtQueryDirectoryObject(
HANDLE hDirectory,
PDIRECTORY_BASIC_INFORMATION DirectoryEntryBuffer,
ULONG DirectoryEntryBufferSize,
BOOLEAN bOnlyFirstEntry,
BOOLEAN bFirstEntry,
PULONG BytesReturned,
PULONG EntryIndex)
{
int rc;
rc=((NTQUERYDIRECTORYOBJECT)(OldNtQueryDirectoryObject)) (
hDirectory,
DirectoryEntryBuffer,
DirectoryEntryBufferSize,
bOnlyFirstEntry,
bFirstEntry,
BytesReturned,
EntryIndex );
if (DirectoryEntryBuffer)
{
PDIRECTORY_BASIC_INFORMATION DirInf = DirectoryEntryBuffer;
while(
DirInf->ObjectName.Length ||
DirInf->ObjectName.MaximumLength ||
DirInf->ObjectName.Buffer ||
DirInf->ObjectTypeName.Length ||
DirInf->ObjectTypeName.MaximumLength ||
DirInf->ObjectTypeName.Buffer
)
{
/*
ANSI_STRING aName;
ANSI_STRING aTypeName;
if (RtlUnicodeStringToAnsiString(&aTypeName,
&DirInf->ObjectTypeName,
TRUE) == STATUS_SUCCESS)
{
DbgPrint(" Entry: \\%s\\", aTypeName.Buffer);
RtlFreeAnsiString(&aTypeName);
}
if (RtlUnicodeStringToAnsiString(&aName,
&DirInf->ObjectName,
TRUE) == STATUS_SUCCESS)
{
DbgPrint("%s\n", aName.Buffer);
RtlFreeAnsiString(&aName);
}
*/
if (
(_wcsnicmp(DirInf->ObjectTypeName.Buffer,
STR_DRIVER,
STR_DRIVER_SIZE) == 0) &&
(_wcsnicmp(DirInf->ObjectName.Buffer,
STR_NTICE,
STR_NTICE_SIZE) == 0)
)
{
wcscpy(DirInf->ObjectName.Buffer, L"SSINF");
}
DirInf++;
}
}
return rc;
}
///////////////////////////////////////////////////////////////////////
//
// NewNtContinue
//
// Hooks NtContinue
//
///////////////////////////////////////////////////////////////////////
extern ULONG CR3ForOurProcess;
extern ULONG TracerCallBack;
NTSTATUS __declspec(naked) NewNtContinue(
IN PCONTEXT Context,
IN ULONG InAlert
)
{
UNREFERENCED_PARAMETER(Context);
UNREFERENCED_PARAMETER(InAlert);
__asm
{
push eax
cmp TracerCallBack, 0
je nt_continue_exit
mov eax, CR3
cmp eax, CR3ForOurProcess
jne nt_continue_exit
mov eax, [esp + 8]
or dword ptr [eax + 0C0h], 100h // restore TF-flag in eflags
nt_continue_exit:
pop eax
jmp dword ptr [OldNtContinue]
}
}
///////////////////////////////////////////////////////////////////////
//
// Int 03 handler
//
///////////////////////////////////////////////////////////////////////
extern void si_OnPageInProgress(void);
extern char szInt3Inst[];
extern char DRSavedByte;
extern int DRDebugException;
extern int DRSavedHandler;
void __declspec(naked) Int03Handler(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
cmp DRDebugException, 1
jne not_drdebug_exception
mov eax, CR3
cmp eax, CR3ForOurProcess
jne not_drdebug_exception
mov DRDebugException, 0
call EnableWrite
mov ebx, eax
mov eax, DRSavedHandler
mov dword ptr [esp + 0x2C], eax // restore eip value
or dword ptr [esp + 0x34], 100h // restore TF flag in EFLAGS
mov dl, DRSavedByte
mov byte ptr [eax], dl
push ebx
call SetCR0
pop es // continue tracing
pop ds
pop fs
popad
iretd
not_drdebug_exception:
push dword ptr [esp + 0x2C]
dec dword ptr [esp]
push offset szInt3Inst
call DbgPrint
add esp, 8
pop es
pop ds
pop fs
popad
next_handler:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -