#pragma
#include "ntifs.h"
#include <windef.h>
#include "gtc.h"
#include "dbkfunc.h"
#include <stdlib.h>
#define SYSCALL_INDEX(_function) *(PULONG)((PUCHAR)_function+1)
#define SYSTEMSERVICE(_callnumber) KeServiceDescriptorTable->ServiceTable[_callnumber]
//--------------
typedef ULONG (*NTGETCONTEXTTHREAD)(HANDLE hThread, PCONTEXT pContext);
//-------
typedef ULONG (*ZWSETCONTEXTTHREAD)(HANDLE hThread, PCONTEXT pContext);
//--------------
typedef ULONG (*ZWCREATEFILE)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize ,ULONG FileAttributes,ULONG ShareAccess,ULONG CreateDisposition,ULONG CreateOptions,PVOID EaBuffer ,ULONG EaLength);
//--------------
typedef ULONG (*NTSETINFORMATIONFILE) (FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass);
//--------------
NTGETCONTEXTTHREAD OldNtGTC;
ZWSETCONTEXTTHREAD OldZwSTC;
ZWCREATEFILE OldZwCF;
NTSETINFORMATIONFILE OldNtSIF;
//--------------
//--------------
ULONG NtGetContextThread_callnumber = 0x0055;
ULONG ZwSetContextThread_callnumber = 0x00d5;
ULONG ZwCreateFile_callnumber = 0x0025;
ULONG NtSetInformationFile_callnumber = 0x00E0;
//--------------
PVOID AddressOfZwGetContextThread;
INT IsGameGuard (PCHAR FileName) {
if(strncmp("GameMon.des",FileName , strlen("GameMon.des"))==0){
DbgPrint("GTC:: GameMon Is calling me");
return 1;
} else {
return 0;
}
}
INT IsMaple (PCHAR FileName) {
if(strncmp("MapleStory.exe",FileName , strlen("MapleStory.exe"))==0){
DbgPrint("GTC:: Maple Is calling me");
return 1;
} else {
return 0;
}
}
NTSTATUS NZwCF(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize ,ULONG FileAttributes,ULONG ShareAccess,ULONG CreateDisposition,ULONG CreateOptions,PVOID EaBuffer ,ULONG EaLength)
{
ACCESS_MASK OrigMask = DesiredAccess;
PEPROCESS pe = PsGetCurrentProcess();
if (IsGameGuard((PCHAR)pe->ImageFileName)) {
DbgPrint("GTC: NewZwCF(FileHandle:0x%.8X;DesiredAccess:0x%.8X;ObjectAttributes:0x%.8X;IoStatusBlock:0x%.8X;AllocationSize:0x%.8X;FileAttributes:0x%.8X;ShareAccess:0x%.8X;CreateDisposition:0x%.8X;CreateOptions:0x%.8X;EaBuffer:0x%.8X;EaLength:0x%.8X)",
FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,AllocationSize,FileAttributes,ShareAccess,CreateDisposition,CreateOptions,EaBuffer,EaLength);
DbgPrint("GTC: NewZwCreateFile:filename: %S",(PCHAR)ObjectAttributes->ObjectName->Buffer);
// DbgPrint("GTC: NewZwCreateFile: Doing Dump_wmimmc compare");
//wcsncmp()
if(wcsstr(ObjectAttributes->ObjectName->Buffer,L"dump_wmimmc")!= NULL) {
DbgPrint("GTC: NewZwCreateFile: Dump_wmimmc match");
if ((DesiredAccess == 0xC0100080) || (DesiredAccess == 0x40100080) || (DesiredAccess == DELETE) || (DesiredAccess=FILE_WRITE_DATA)) {
return OldZwCF(FileHandle, GENERIC_READ, ObjectAttributes, IoStatusBlock, AllocationSize , FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength);
}
}
DbgPrint("GTC: NewZwCreateFile: NO MATCH");
DbgPrint("GTC: NewZwCreateFile:--------------------------------------------");
}
return OldZwCF(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize , FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength);
}
ULONG NNtSIF(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass )
{
ULONG status;
PEPROCESS pe = PsGetCurrentProcess();
PFILE_NAME_INFORMATION ni;
//if gamemon.des and trying to delete a file
if(IsGameGuard((PCHAR)pe->ImageFileName) && FileInformationClass==FileDispositionInformation)
{
ni = ExAllocatePool(PagedPool, 1024);
if(ni!=NULL)
{
status = ZwQueryInformationFile(FileHandle, IoStatusBlock, ni, 1024, FileNameInformation);
if(status==STATUS_SUCCESS)
{
PWCHAR dump = wcsstr(&ni->FileName[1], L"dump_wmimmc.sys");
if(dump!=NULL)
{
ExFreePool(ni);
return STATUS_SUCCESS; //return success without deleting
}
}
ExFreePool(ni);
}
}
return OldNtSIF(FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass);
}
NTSTATUS NNtGTC(HANDLE hThread, PCONTEXT pContext)
{
PEPROCESS pe = PsGetCurrentProcess();
DbgPrint("GTC:NewGTC Called");
if(IsGameGuard((PCHAR)pe->ImageFileName)){
OldNtGTC(hThread, pContext);
pContext->Dr0 = gga.DR0;
pContext->Dr1 = gga.DR1;
pContext->Dr2 = gga.DR2;
pContext->Dr3 = gga.DR3;
pContext->Dr6 = gga.DR6;
pContext->Dr7 = gga.DR7;
/*pContext->Dr0 = 0;
pContext->Dr1 = 0;
pContext->Dr2 = 0;
pContext->Dr3 = 0;
pContext->Dr6 = 0;
pContext->Dr7 = 0; */
return STATUS_SUCCESS;
} else {
return OldNtGTC(hThread, pContext);
}
}
NTSTATUS NZwSTC(HANDLE hThread, PCONTEXT pContext)
{
PEPROCESS pe = PsGetCurrentProcess();
if(IsGameGuard((PCHAR)pe->ImageFileName)){
gga.DR0 = pContext->Dr0;
gga.DR1 = pContext->Dr1;
gga.DR2 = pContext->Dr2;
gga.DR3 = pContext->Dr3;
gga.DR6 = pContext->Dr6;
gga.DR7 = pContext->Dr7;
return STATUS_SUCCESS;
}else{
OldZwSTC(hThread, pContext);
return STATUS_SUCCESS;
}
}
void gtc()
{
//--------------
OldNtGTC = SYSTEMSERVICE(NtGetContextThread_callnumber);
//--------------
OldZwSTC = SYSTEMSERVICE(ZwSetContextThread_callnumber);
//--------------
OldZwCF = SYSTEMSERVICE(ZwCreateFile_callnumber);
//--------------
OldNtSIF = SYSTEMSERVICE(NtSetInformationFile_callnumber);
//--------------
__asm {
push eax
mov eax, CR0
and eax, 0x0FFFEFFFF
mov CR0, eax
pop eax
cli
}
//--------------
SYSTEMSERVICE(NtGetContextThread_callnumber) = (PVOID)NNtGTC;
SYSTEMSERVICE(ZwSetContextThread_callnumber) = (PVOID)NZwSTC;
SYSTEMSERVICE(ZwCreateFile_callnumber) = (PVOID)NZwCF;
SYSTEMSERVICE(NtSetInformationFile_callnumber) = (PVOID)NNtSIF;
//--------------
__asm {
push eax
mov eax, CR0
or eax, NOT 0x0FFFEFFFF
mov CR0, eax
pop eax
sti
}
}