added sha1 hook, also added image and log...

merge-requests/1/head
_xeroxz 3 years ago
parent 419f0c8778
commit 44e1817460

@ -3,17 +3,25 @@
//
//
#include <ntifs.h>
#include <intrin.h>
#include <vmhook.hpp>
#include "scn.hpp"
#include "shithook.hpp"
#include "sha1.hpp"
#include "md5.hpp"
//
// game cheat offset flash backs...
//
#define EAC_VM_HANDLE_OFFSET 0xE93D
#define EAC_SHA1_OFFSET 0x4C00
#define EAC_MD5_OFFSET 0x37378
#define EAC_CRC32_OFFSET 0x27C8C
#define EAC_IMAGE_BASE 0x140000000
#define DBG_PRINT(format, ...) \
DbgPrintEx( DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, \
"[vmhook-eac [core number = %d]]" format, KeGetCurrentProcessorNumber(), __VA_ARGS__)
//
// vm handler indexes for READQ...
//
@ -26,13 +34,21 @@ u8 readq_idxs[] = { 247, 215, 169, 159, 71, 60, 55, 43, 23 };
u8 readdw_idxs[] = { 218, 180, 179, 178, 163, 137, 92, 22, 12 };
//
// vm handler indexes for READB
//
u8 readb_idxs[] = { 249, 231, 184, 160, 88, 85, 48, 9, 2 };
vm::hook_t* g_vmhook = nullptr;
vm::handler::table_t* g_vm_table = nullptr;
u64 __image_base = 0u, __image_size = 0u, __image_clone = 0u;
inline_hook_t __crc32_hook, __sha1_hook, __md5_hook;
void*
operator new(
u64 size
)
)
{
//
// Could have also used ExAllocatePoolZero...
@ -46,12 +62,32 @@ operator delete
(
void* ptr,
u64 size
)
)
{
UNREFERENCED_PARAMETER(size);
ExFreePool(ptr);
}
__declspec(noinline)
void hook_sha1(
void *data, unsigned int len, void* result
)
{
sha1_ctx ctx;
sha1_init(&ctx);
if (scn::read_only(__image_base, (u64)data))
{
DBG_PRINT("sha1 hash data = 0x%p, len = 0x%x, result = 0x%p\n", data, len, result);
sha1_update(&ctx, (unsigned char*)__image_clone + (((u64)data) - __image_base), len);
sha1_final((unsigned char*)result, &ctx);
return;
}
sha1_update(&ctx, (unsigned char*) data, len);
sha1_final((unsigned char*)result, &ctx);
}
void
image_loaded(
PUNICODE_STRING image_name,
@ -65,8 +101,8 @@ image_loaded(
if (!pid && wcsstr(image_name->Buffer, L"EasyAntiCheat.sys"))
{
if (g_vmhook && g_vm_table)
delete g_vmhook, delete g_vm_table;
if (g_vmhook && g_vm_table && __image_clone)
delete g_vmhook, delete g_vm_table, ExFreePool((void*)__image_clone);
//
// allocate memory for a g_vmhook, g_vm_table and then zero it...
@ -123,34 +159,46 @@ image_loaded(
auto image_base = reinterpret_cast<u64>(image_info->ImageBase);
auto handler_table_ptr = reinterpret_cast<u64*>(image_base + EAC_VM_HANDLE_OFFSET);
__image_clone = reinterpret_cast<u64>(ExAllocatePool(NonPagedPool, image_info->ImageSize));
RtlCopyMemory((void*)__image_clone, (void*)image_base, image_info->ImageSize);
g_vm_table = new vm::handler::table_t(handler_table_ptr, _edit_entry);
g_vmhook = new vm::hook_t(image_base, EAC_IMAGE_BASE, _decrypt_handler, _encrypt_handler, g_vm_table);
__image_base = image_base, __image_size = image_info->ImageSize;
const auto callback = [](vm::registers* regs, u8 handler_idx)
{
const auto read_addr = reinterpret_cast<u64*>(regs->rbp)[0];
// shoot the tires right off the virtualized integrity checks in about 2 lines of code...
if (scn::read_only(__image_base, read_addr))
{
DBG_PRINT(" READ(Q/DW/B) EasyAntiCheat.sys+0x%x\n", (read_addr - __image_base));
reinterpret_cast<u64*>(regs->rbp)[0] = __image_clone + (read_addr - __image_base);
}
};
// install hooks on READQ virtual machine handlers...
for (auto idx = 0u; idx < sizeof readq_idxs; ++idx)
{
g_vm_table->set_callback(readq_idxs[idx],
[](vm::registers* regs, u8 handler_idx)
{
DbgPrint("> READQ, reading address = 0x%p\n", reinterpret_cast<u64*>(regs->rbp)[0]);
}
);
}
g_vm_table->set_callback(readq_idxs[idx], callback);
// install hooks on READDW virtual machine handlers...
for (auto idx = 0u; idx < sizeof readdw_idxs; ++idx)
{
g_vm_table->set_callback(readdw_idxs[idx],
[](vm::registers* regs, u8 handler_idx)
{
DbgPrint("> READDW, reading address = 0x%p\n", reinterpret_cast<u64*>(regs->rbp)[0]);
}
);
}
g_vm_table->set_callback(readdw_idxs[idx], callback);
// install hooks on READB virtual machine handlers...
for (auto idx = 0u; idx < sizeof readb_idxs; ++idx)
g_vm_table->set_callback(readb_idxs[idx], callback);
//
// hooks all vm handlers and starts callbacks...
//
g_vmhook->start();
// hook on sha1...
make_inline_hook(&__sha1_hook,
reinterpret_cast<void*>(
image_base + EAC_SHA1_OFFSET), &hook_sha1, true);
}
}
@ -184,6 +232,6 @@ DriverEntry( // entry called from ZwSwapCert...
// This is because ZwSwapCert will cause the system to crash...
//
DbgPrint("> Registering ImageLoad Callbacks...\n");
DBG_PRINT("> Registering ImageLoad Callbacks...\n");
return PsSetLoadImageNotifyRoutine(&image_loaded);
}

@ -0,0 +1,29 @@
#include "scn.hpp"
namespace scn
{
bool read_only(u64 image_base, u64 ptr)
{
auto dos_header = reinterpret_cast<PIMAGE_DOS_HEADER>(image_base);
auto nt_header = reinterpret_cast<PIMAGE_NT_HEADERS64>(
reinterpret_cast<u64>(dos_header) + dos_header->e_lfanew);
auto section_count = nt_header->FileHeader.NumberOfSections;
auto sections = reinterpret_cast<PIMAGE_SECTION_HEADER>(
reinterpret_cast<u64>(nt_header) + sizeof(u32) + sizeof(IMAGE_FILE_HEADER) +
nt_header->FileHeader.SizeOfOptionalHeader);
// for each section try and find the section that contains this pointer...
for (auto idx = 0u; idx < section_count; ++idx)
// if the section contains this pointer...
if (ptr >= sections[idx].VirtualAddress + image_base &&
ptr < sections[idx].VirtualAddress + image_base + sections[idx].Misc.VirtualSize)
// returns true if the section isnt discardable and isnt writeable (I.E in memory and readonly)...
return !(sections[idx].Characteristics & IMAGE_SCN_MEM_DISCARDABLE) &&
!(sections[idx].Characteristics & IMAGE_SCN_MEM_WRITE);
// pointer isnt inside of the driver...
return false;
}
}

@ -0,0 +1,121 @@
#pragma once
#include <ntifs.h>
#include <intrin.h>
#include <vmhook.hpp>
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
#define IMAGE_SCN_MEM_WRITE 0x80000000
namespace scn
{
typedef struct _IMAGE_DOS_HEADER
{
/* 0x0000 */ unsigned short e_magic;
/* 0x0002 */ unsigned short e_cblp;
/* 0x0004 */ unsigned short e_cp;
/* 0x0006 */ unsigned short e_crlc;
/* 0x0008 */ unsigned short e_cparhdr;
/* 0x000a */ unsigned short e_minalloc;
/* 0x000c */ unsigned short e_maxalloc;
/* 0x000e */ unsigned short e_ss;
/* 0x0010 */ unsigned short e_sp;
/* 0x0012 */ unsigned short e_csum;
/* 0x0014 */ unsigned short e_ip;
/* 0x0016 */ unsigned short e_cs;
/* 0x0018 */ unsigned short e_lfarlc;
/* 0x001a */ unsigned short e_ovno;
/* 0x001c */ unsigned short e_res[4];
/* 0x0024 */ unsigned short e_oemid;
/* 0x0026 */ unsigned short e_oeminfo;
/* 0x0028 */ unsigned short e_res2[10];
/* 0x003c */ long e_lfanew;
} IMAGE_DOS_HEADER, * PIMAGE_DOS_HEADER; /* size: 0x0040 */
typedef struct _IMAGE_FILE_HEADER
{
/* 0x0000 */ unsigned short Machine;
/* 0x0002 */ unsigned short NumberOfSections;
/* 0x0004 */ unsigned long TimeDateStamp;
/* 0x0008 */ unsigned long PointerToSymbolTable;
/* 0x000c */ unsigned long NumberOfSymbols;
/* 0x0010 */ unsigned short SizeOfOptionalHeader;
/* 0x0012 */ unsigned short Characteristics;
} IMAGE_FILE_HEADER, * PIMAGE_FILE_HEADER; /* size: 0x0014 */
typedef struct _IMAGE_DATA_DIRECTORY
{
/* 0x0000 */ unsigned long VirtualAddress;
/* 0x0004 */ unsigned long Size;
} IMAGE_DATA_DIRECTORY, * PIMAGE_DATA_DIRECTORY; /* size: 0x0008 */
typedef struct _IMAGE_OPTIONAL_HEADER64
{
/* 0x0000 */ unsigned short Magic;
/* 0x0002 */ unsigned char MajorLinkerVersion;
/* 0x0003 */ unsigned char MinorLinkerVersion;
/* 0x0004 */ unsigned long SizeOfCode;
/* 0x0008 */ unsigned long SizeOfInitializedData;
/* 0x000c */ unsigned long SizeOfUninitializedData;
/* 0x0010 */ unsigned long AddressOfEntryPoint;
/* 0x0014 */ unsigned long BaseOfCode;
/* 0x0018 */ unsigned __int64 ImageBase;
/* 0x0020 */ unsigned long SectionAlignment;
/* 0x0024 */ unsigned long FileAlignment;
/* 0x0028 */ unsigned short MajorOperatingSystemVersion;
/* 0x002a */ unsigned short MinorOperatingSystemVersion;
/* 0x002c */ unsigned short MajorImageVersion;
/* 0x002e */ unsigned short MinorImageVersion;
/* 0x0030 */ unsigned short MajorSubsystemVersion;
/* 0x0032 */ unsigned short MinorSubsystemVersion;
/* 0x0034 */ unsigned long Win32VersionValue;
/* 0x0038 */ unsigned long SizeOfImage;
/* 0x003c */ unsigned long SizeOfHeaders;
/* 0x0040 */ unsigned long CheckSum;
/* 0x0044 */ unsigned short Subsystem;
/* 0x0046 */ unsigned short DllCharacteristics;
/* 0x0048 */ unsigned __int64 SizeOfStackReserve;
/* 0x0050 */ unsigned __int64 SizeOfStackCommit;
/* 0x0058 */ unsigned __int64 SizeOfHeapReserve;
/* 0x0060 */ unsigned __int64 SizeOfHeapCommit;
/* 0x0068 */ unsigned long LoaderFlags;
/* 0x006c */ unsigned long NumberOfRvaAndSizes;
/* 0x0070 */ struct _IMAGE_DATA_DIRECTORY DataDirectory[16];
} IMAGE_OPTIONAL_HEADER64, * PIMAGE_OPTIONAL_HEADER64; /* size: 0x00f0 */
typedef struct _IMAGE_NT_HEADERS64
{
/* 0x0000 */ unsigned long Signature;
/* 0x0004 */ struct _IMAGE_FILE_HEADER FileHeader;
/* 0x0018 */ struct _IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, * PIMAGE_NT_HEADERS64; /* size: 0x0108 */
typedef struct _IMAGE_SECTION_HEADER
{
/* 0x0000 */ unsigned char Name[8];
union
{
union
{
/* 0x0008 */ unsigned long PhysicalAddress;
/* 0x0008 */ unsigned long VirtualSize;
}; /* size: 0x0004 */
} /* size: 0x0004 */ Misc;
/* 0x000c */ unsigned long VirtualAddress;
/* 0x0010 */ unsigned long SizeOfRawData;
/* 0x0014 */ unsigned long PointerToRawData;
/* 0x0018 */ unsigned long PointerToRelocations;
/* 0x001c */ unsigned long PointerToLinenumbers;
/* 0x0020 */ unsigned short NumberOfRelocations;
/* 0x0022 */ unsigned short NumberOfLinenumbers;
/* 0x0024 */ unsigned long Characteristics;
} IMAGE_SECTION_HEADER, * PIMAGE_SECTION_HEADER; /* size: 0x0028 */
/// <summary>
/// returns true if the ptr pointers to something in a section
/// that is read only...
/// </summary>
/// <param name="image_base">module base of the driver...</param>
/// <param name="ptr">a valid pointer that lands inside of the driver...</param>
/// <returns>returns true if the ptr pointers to something in a section that is read only</returns>
bool read_only(u64 image_base, u64 ptr);
}

@ -0,0 +1,316 @@
#pragma once
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
*/
using uint32_t = unsigned int;
typedef struct _sha1_ctx
{
uint32_t state[5];
uint32_t count[2];
unsigned char buffer[64];
} sha1_ctx, * psha1_ctx;
void sha1_transform(
uint32_t state[5],
const unsigned char buffer[64]
);
void sha1_init(
sha1_ctx* context
);
void sha1_update(
sha1_ctx* context,
const unsigned char* data,
uint32_t len
);
void sha1_final(
unsigned char digest[20],
sha1_ctx* context
);
void sha1(
char* hash_out,
const char* str,
int len);
#define SHA1HANDSOFF
#include <stdio.h>
#include <string.h>
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#if BYTE_ORDER == LITTLE_ENDIAN
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#elif BYTE_ORDER == BIG_ENDIAN
#define blk0(i) block->l[i]
#else
#error "Endianness not defined!"
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
void sha1_transform(
uint32_t state[5],
const unsigned char buffer[64]
)
{
uint32_t a, b, c, d, e;
typedef union
{
unsigned char c[64];
uint32_t l[16];
} CHAR64LONG16;
#ifdef SHA1HANDSOFF
CHAR64LONG16 block[1]; /* use array to appear as a pointer */
memcpy(block, buffer, 64);
#else
/* The following had better never be used because it causes the
* pointer-to-const buffer to be cast into a pointer to non-const.
* And the result is written through. I threw a "const" in, hoping
* this will cause a diagnostic.
*/
CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
#endif
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a, b, c, d, e, 0);
R0(e, a, b, c, d, 1);
R0(d, e, a, b, c, 2);
R0(c, d, e, a, b, 3);
R0(b, c, d, e, a, 4);
R0(a, b, c, d, e, 5);
R0(e, a, b, c, d, 6);
R0(d, e, a, b, c, 7);
R0(c, d, e, a, b, 8);
R0(b, c, d, e, a, 9);
R0(a, b, c, d, e, 10);
R0(e, a, b, c, d, 11);
R0(d, e, a, b, c, 12);
R0(c, d, e, a, b, 13);
R0(b, c, d, e, a, 14);
R0(a, b, c, d, e, 15);
R1(e, a, b, c, d, 16);
R1(d, e, a, b, c, 17);
R1(c, d, e, a, b, 18);
R1(b, c, d, e, a, 19);
R2(a, b, c, d, e, 20);
R2(e, a, b, c, d, 21);
R2(d, e, a, b, c, 22);
R2(c, d, e, a, b, 23);
R2(b, c, d, e, a, 24);
R2(a, b, c, d, e, 25);
R2(e, a, b, c, d, 26);
R2(d, e, a, b, c, 27);
R2(c, d, e, a, b, 28);
R2(b, c, d, e, a, 29);
R2(a, b, c, d, e, 30);
R2(e, a, b, c, d, 31);
R2(d, e, a, b, c, 32);
R2(c, d, e, a, b, 33);
R2(b, c, d, e, a, 34);
R2(a, b, c, d, e, 35);
R2(e, a, b, c, d, 36);
R2(d, e, a, b, c, 37);
R2(c, d, e, a, b, 38);
R2(b, c, d, e, a, 39);
R3(a, b, c, d, e, 40);
R3(e, a, b, c, d, 41);
R3(d, e, a, b, c, 42);
R3(c, d, e, a, b, 43);
R3(b, c, d, e, a, 44);
R3(a, b, c, d, e, 45);
R3(e, a, b, c, d, 46);
R3(d, e, a, b, c, 47);
R3(c, d, e, a, b, 48);
R3(b, c, d, e, a, 49);
R3(a, b, c, d, e, 50);
R3(e, a, b, c, d, 51);
R3(d, e, a, b, c, 52);
R3(c, d, e, a, b, 53);
R3(b, c, d, e, a, 54);
R3(a, b, c, d, e, 55);
R3(e, a, b, c, d, 56);
R3(d, e, a, b, c, 57);
R3(c, d, e, a, b, 58);
R3(b, c, d, e, a, 59);
R4(a, b, c, d, e, 60);
R4(e, a, b, c, d, 61);
R4(d, e, a, b, c, 62);
R4(c, d, e, a, b, 63);
R4(b, c, d, e, a, 64);
R4(a, b, c, d, e, 65);
R4(e, a, b, c, d, 66);
R4(d, e, a, b, c, 67);
R4(c, d, e, a, b, 68);
R4(b, c, d, e, a, 69);
R4(a, b, c, d, e, 70);
R4(e, a, b, c, d, 71);
R4(d, e, a, b, c, 72);
R4(c, d, e, a, b, 73);
R4(b, c, d, e, a, 74);
R4(a, b, c, d, e, 75);
R4(e, a, b, c, d, 76);
R4(d, e, a, b, c, 77);
R4(c, d, e, a, b, 78);
R4(b, c, d, e, a, 79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
#ifdef SHA1HANDSOFF
memset(block, '\0', sizeof(block));
#endif
}
/* SHA1Init - Initialize new context */
void sha1_init(
sha1_ctx* context
)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void sha1_update(
sha1_ctx* context,
const unsigned char* data,
uint32_t len
)
{
uint32_t i;
uint32_t j;
j = context->count[0];
if ((context->count[0] += len << 3) < j)
context->count[1]++;
context->count[1] += (len >> 29);
j = (j >> 3) & 63;
if ((j + len) > 63)
{
memcpy(&context->buffer[j], data, (i = 64 - j));
sha1_transform(context->state, context->buffer);
for (; i + 63 < len; i += 64)
{
sha1_transform(context->state, &data[i]);
}
j = 0;
}
else
i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void sha1_final(
unsigned char digest[20],
sha1_ctx* context
)
{
unsigned i;
unsigned char finalcount[8];
unsigned char c;
#if 0 /* untested "improvement" by DHR */
/* Convert context->count to a sequence of bytes
* in finalcount. Second element first, but
* big-endian order within element.
* But we do it all backwards.
*/
unsigned char* fcp = &finalcount[8];
for (i = 0; i < 2; i++)
{
uint32_t t = context->count[i];
int j;
for (j = 0; j < 4; t >>= 8, j++)
*--fcp = (unsigned char)t
}
#else
for (i = 0; i < 8; i++)
{
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */
}
#endif
c = 0200;
sha1_update(context, &c, 1);
while ((context->count[0] & 504) != 448)
{
c = 0000;
sha1_update(context, &c, 1);
}
sha1_update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++)
{
digest[i] = (unsigned char)
((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
}
/* Wipe variables */
memset(context, '\0', sizeof(*context));
memset(&finalcount, '\0', sizeof(finalcount));
}
void sha1(
char* hash_out,
const char* str,
int len)
{
sha1_ctx ctx;
unsigned int ii;
sha1_init(&ctx);
for (ii = 0; ii < len; ii += 1)
sha1_update(&ctx, (const unsigned char*)str + ii, 1);
sha1_final((unsigned char*)hash_out, &ctx);
hash_out[20] = '\0';
}

@ -0,0 +1,75 @@
#pragma once
#include <ntifs.h>
typedef struct _inline_hook_t
{
unsigned char code[14];
unsigned char jmp_code[14];
void* address;
void* hook_address;
} inline_hook_t, * pinline_hook_t;
void make_inline_hook(pinline_hook_t, void*, void*, bool);
void enable_inline_hook(pinline_hook_t);
void disable_inline_hook(pinline_hook_t);
inline void make_inline_hook(pinline_hook_t hook, void* hook_from, void* hook_to, bool install)
{
unsigned char jmp_code[14] =
{
0xff, 0x25, 0x0, 0x0, 0x0, 0x0, // jmp QWORD PTR[rip + 0x0]
// jmp address...
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0
};
// save original bytes, and hook related addresses....
hook->address = hook_from;
hook->hook_address = hook_to;
memcpy(hook->code, hook_from, sizeof hook->code);
// setup hook...
memcpy(jmp_code + 6, &hook_to, sizeof hook_to);
memcpy(hook->jmp_code, jmp_code, sizeof jmp_code);
if (install) enable_inline_hook(hook);
}
inline void enable_inline_hook(pinline_hook_t hook)
{
{
auto cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();
}
memcpy(hook->address, hook->jmp_code, sizeof hook->jmp_code);
{
auto cr0 = __readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
}
}
inline void disable_inline_hook(pinline_hook_t hook)
{
{
auto cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();
}
memcpy(hook->address, hook->code, sizeof hook->code);
{
auto cr0 = __readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 KiB

Binary file not shown.

@ -71,9 +71,14 @@
<ItemGroup>
<ClCompile Include="dependencies\vmhook\src\vmhook.cpp" />
<ClCompile Include="drv_entry.cpp" />
<ClCompile Include="scn.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="dependencies\vmhook\include\vmhook.hpp" />
<ClInclude Include="md5.hpp" />
<ClInclude Include="scn.hpp" />
<ClInclude Include="sha1.hpp" />
<ClInclude Include="shithook.hpp" />
</ItemGroup>
<ItemGroup>
<MASM Include="dependencies\vmhook\src\vtrap.asm" />

@ -17,11 +17,26 @@
<ClCompile Include="dependencies\vmhook\src\vmhook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="scn.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="dependencies\vmhook\include\vmhook.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="scn.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="md5.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sha1.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="shithook.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="dependencies\vmhook\src\vtrap.asm">

Loading…
Cancel
Save