1.0.4
This commit is contained in:
parent
5e3103bb40
commit
d4719a9811
|
@ -4,6 +4,15 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.0.4 / 5.55.4] - 2021-12-xx
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- mechanism to hook Win32 system calls now also works for 32 bit applications running under WoW64
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.3 / 5.55.3] - 2021-12-12
|
## [1.0.3 / 5.55.3] - 2021-12-12
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
#ifndef _MY_VERSION_H
|
#ifndef _MY_VERSION_H
|
||||||
#define _MY_VERSION_H
|
#define _MY_VERSION_H
|
||||||
|
|
||||||
#define MY_VERSION_BINARY 5,55,3
|
#define MY_VERSION_BINARY 5,55,4
|
||||||
#define MY_VERSION_STRING "5.55.3"
|
#define MY_VERSION_STRING "5.55.4"
|
||||||
#define MY_VERSION_COMPAT "5.55.0" // this refers to the driver ABI compatibility
|
#define MY_VERSION_COMPAT "5.55.0" // this refers to the driver ABI compatibility
|
||||||
|
|
||||||
// These #defines are used by either Resource Compiler, or by NSIC installer
|
// These #defines are used by either Resource Compiler, or by NSIC installer
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* WOW64Ext Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 ReWolf
|
||||||
|
* http://blog.rewolf.pl/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CMemPtr
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void** m_ptr;
|
||||||
|
bool watchActive;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CMemPtr(void** ptr) : m_ptr(ptr), watchActive(true) {}
|
||||||
|
|
||||||
|
~CMemPtr()
|
||||||
|
{
|
||||||
|
if (*m_ptr && watchActive)
|
||||||
|
{
|
||||||
|
free(*m_ptr);
|
||||||
|
*m_ptr = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void disableWatch() { watchActive = false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define WATCH(ptr) \
|
||||||
|
CMemPtr watch_##ptr((void**)&ptr)
|
||||||
|
|
||||||
|
#define DISABLE_WATCH(ptr) \
|
||||||
|
watch_##ptr.disableWatch()
|
|
@ -0,0 +1,73 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* WOW64Ext Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 ReWolf
|
||||||
|
* http://blog.rewolf.pl/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define EMIT(a) __asm __emit (a)
|
||||||
|
|
||||||
|
#define X64_Start_with_CS(_cs) \
|
||||||
|
{ \
|
||||||
|
EMIT(0x6A) EMIT(_cs) /* push _cs */ \
|
||||||
|
EMIT(0xE8) EMIT(0) EMIT(0) EMIT(0) EMIT(0) /* call $+5 */ \
|
||||||
|
EMIT(0x83) EMIT(4) EMIT(0x24) EMIT(5) /* add dword [esp], 5 */ \
|
||||||
|
EMIT(0xCB) /* retf */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define X64_End_with_CS(_cs) \
|
||||||
|
{ \
|
||||||
|
EMIT(0xE8) EMIT(0) EMIT(0) EMIT(0) EMIT(0) /* call $+5 */ \
|
||||||
|
EMIT(0xC7) EMIT(0x44) EMIT(0x24) EMIT(4) EMIT(_cs) EMIT(0) EMIT(0) EMIT(0) /* mov dword [rsp + 4], _cs */ \
|
||||||
|
EMIT(0x83) EMIT(4) EMIT(0x24) EMIT(0xD) /* add dword [rsp], 0xD */ \
|
||||||
|
EMIT(0xCB) /* retf */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define X64_Start() X64_Start_with_CS(0x33)
|
||||||
|
#define X64_End() X64_End_with_CS(0x23)
|
||||||
|
|
||||||
|
#define _RAX 0
|
||||||
|
#define _RCX 1
|
||||||
|
#define _RDX 2
|
||||||
|
#define _RBX 3
|
||||||
|
#define _RSP 4
|
||||||
|
#define _RBP 5
|
||||||
|
#define _RSI 6
|
||||||
|
#define _RDI 7
|
||||||
|
#define _R8 8
|
||||||
|
#define _R9 9
|
||||||
|
#define _R10 10
|
||||||
|
#define _R11 11
|
||||||
|
#define _R12 12
|
||||||
|
#define _R13 13
|
||||||
|
#define _R14 14
|
||||||
|
#define _R15 15
|
||||||
|
|
||||||
|
#define X64_Push(r) EMIT(0x48 | ((r) >> 3)) EMIT(0x50 | ((r) & 7))
|
||||||
|
#define X64_Pop(r) EMIT(0x48 | ((r) >> 3)) EMIT(0x58 | ((r) & 7))
|
||||||
|
|
||||||
|
#define REX_W EMIT(0x48) __asm
|
||||||
|
|
||||||
|
//to fool M$ inline asm compiler I'm using 2 DWORDs instead of DWORD64
|
||||||
|
//use of DWORD64 will generate wrong 'pop word ptr[]' and it will break stack
|
||||||
|
union reg64
|
||||||
|
{
|
||||||
|
DWORD64 v;
|
||||||
|
DWORD dw[2];
|
||||||
|
};
|
|
@ -0,0 +1,611 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* WOW64Ext Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 ReWolf
|
||||||
|
* http://blog.rewolf.pl/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include "internal.h"
|
||||||
|
#include "wow64ext.h"
|
||||||
|
|
||||||
|
#if defined _MSC_VER && !defined _CRT_USE_BUILTIN_OFFSETOF
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define offsetof(s,m) ((::size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
|
||||||
|
#else
|
||||||
|
#define offsetof(s,m) ((size_t)&(((s*)0)->m))
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define offsetof(s,m) __builtin_offsetof(s,m)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//HANDLE g_heap;
|
||||||
|
BOOL g_isWow64 = TRUE;
|
||||||
|
|
||||||
|
void* malloc(size_t size)
|
||||||
|
{
|
||||||
|
return HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void* ptr)
|
||||||
|
{
|
||||||
|
if (nullptr != ptr)
|
||||||
|
HeapFree(GetProcessHeap(), 0, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "CMemPtr.h"
|
||||||
|
|
||||||
|
/*int _wcsicmp(const wchar_t *string1, const wchar_t *string2)
|
||||||
|
{
|
||||||
|
wchar_t c1;
|
||||||
|
wchar_t c2;
|
||||||
|
int i = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c1 = string1[i];
|
||||||
|
if (c1 >= 'A' && c1 <= 'Z')
|
||||||
|
c1 += 0x20;
|
||||||
|
|
||||||
|
c2 = string2[i];
|
||||||
|
if (c2 >= 'A' && c2 <= 'Z')
|
||||||
|
c2 += 0x20;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
} while (c1 && c1 == c2);
|
||||||
|
return c1 - c2;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
|
{
|
||||||
|
if (DLL_PROCESS_ATTACH == fdwReason)
|
||||||
|
{
|
||||||
|
IsWow64Process(GetCurrentProcess(), &g_isWow64);
|
||||||
|
g_heap = GetProcessHeap();
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4409)
|
||||||
|
extern "C" DWORD64 __cdecl X64Call(DWORD64 func, int argC, ...)
|
||||||
|
{
|
||||||
|
if (!g_isWow64)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, argC);
|
||||||
|
reg64 _rcx = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 };
|
||||||
|
reg64 _rdx = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 };
|
||||||
|
reg64 _r8 = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 };
|
||||||
|
reg64 _r9 = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 };
|
||||||
|
reg64 _rax = { 0 };
|
||||||
|
|
||||||
|
reg64 restArgs = { (DWORD64)&va_arg(args, DWORD64) };
|
||||||
|
|
||||||
|
// conversion to QWORD for easier use in inline assembly
|
||||||
|
#ifdef _M_IX86
|
||||||
|
reg64 _argC = { (DWORD64)argC };
|
||||||
|
DWORD back_esp = 0;
|
||||||
|
WORD back_fs = 0;
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
;// reset FS segment, to properly handle RFG
|
||||||
|
mov back_fs, fs
|
||||||
|
mov eax, 0x2B
|
||||||
|
mov fs, ax
|
||||||
|
|
||||||
|
;// keep original esp in back_esp variable
|
||||||
|
mov back_esp, esp
|
||||||
|
|
||||||
|
;// align esp to 0x10, without aligned stack some syscalls may return errors !
|
||||||
|
;// (actually, for syscalls it is sufficient to align to 8, but SSE opcodes
|
||||||
|
;// requires 0x10 alignment), it will be further adjusted according to the
|
||||||
|
;// number of arguments above 4
|
||||||
|
and esp, 0xFFFFFFF0
|
||||||
|
|
||||||
|
X64_Start();
|
||||||
|
|
||||||
|
;// below code is compiled as x86 inline asm, but it is executed as x64 code
|
||||||
|
;// that's why it need sometimes REX_W() macro, right column contains detailed
|
||||||
|
;// transcription how it will be interpreted by CPU
|
||||||
|
|
||||||
|
;// fill first four arguments
|
||||||
|
REX_W mov ecx, _rcx.dw[0] ;// mov rcx, qword ptr [_rcx]
|
||||||
|
REX_W mov edx, _rdx.dw[0] ;// mov rdx, qword ptr [_rdx]
|
||||||
|
push _r8.v ;// push qword ptr [_r8]
|
||||||
|
X64_Pop(_R8); ;// pop r8
|
||||||
|
push _r9.v ;// push qword ptr [_r9]
|
||||||
|
X64_Pop(_R9); ;// pop r9
|
||||||
|
;//
|
||||||
|
REX_W mov eax, _argC.dw[0] ;// mov rax, qword ptr [_argC]
|
||||||
|
;//
|
||||||
|
;// final stack adjustment, according to the ;//
|
||||||
|
;// number of arguments above 4 ;//
|
||||||
|
test al, 1 ;// test al, 1
|
||||||
|
jnz _no_adjust ;// jnz _no_adjust
|
||||||
|
sub esp, 8 ;// sub rsp, 8
|
||||||
|
_no_adjust: ;//
|
||||||
|
;//
|
||||||
|
push edi ;// push rdi
|
||||||
|
REX_W mov edi, restArgs.dw[0] ;// mov rdi, qword ptr [restArgs]
|
||||||
|
;//
|
||||||
|
;// put rest of arguments on the stack ;//
|
||||||
|
REX_W test eax, eax ;// test rax, rax
|
||||||
|
jz _ls_e ;// je _ls_e
|
||||||
|
REX_W lea edi, dword ptr [edi + 8*eax - 8] ;// lea rdi, [rdi + rax*8 - 8]
|
||||||
|
;//
|
||||||
|
_ls: ;//
|
||||||
|
REX_W test eax, eax ;// test rax, rax
|
||||||
|
jz _ls_e ;// je _ls_e
|
||||||
|
push dword ptr [edi] ;// push qword ptr [rdi]
|
||||||
|
REX_W sub edi, 8 ;// sub rdi, 8
|
||||||
|
REX_W sub eax, 1 ;// sub rax, 1
|
||||||
|
jmp _ls ;// jmp _ls
|
||||||
|
_ls_e: ;//
|
||||||
|
;//
|
||||||
|
;// create stack space for spilling registers ;//
|
||||||
|
REX_W sub esp, 0x20 ;// sub rsp, 20h
|
||||||
|
;//
|
||||||
|
call func ;// call qword ptr [func]
|
||||||
|
;//
|
||||||
|
;// cleanup stack ;//
|
||||||
|
REX_W mov ecx, _argC.dw[0] ;// mov rcx, qword ptr [_argC]
|
||||||
|
REX_W lea esp, dword ptr [esp + 8*ecx + 0x20] ;// lea rsp, [rsp + rcx*8 + 20h]
|
||||||
|
;//
|
||||||
|
pop edi ;// pop rdi
|
||||||
|
;//
|
||||||
|
// set return value ;//
|
||||||
|
REX_W mov _rax.dw[0], eax ;// mov qword ptr [_rax], rax
|
||||||
|
|
||||||
|
X64_End();
|
||||||
|
|
||||||
|
mov ax, ds
|
||||||
|
mov ss, ax
|
||||||
|
mov esp, back_esp
|
||||||
|
|
||||||
|
;// restore FS segment
|
||||||
|
mov ax, back_fs
|
||||||
|
mov fs, ax
|
||||||
|
}
|
||||||
|
#endif // _M_IX86
|
||||||
|
|
||||||
|
return _rax.v;
|
||||||
|
}
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
void getMem64(void* dstMem, DWORD64 srcMem, size_t sz)
|
||||||
|
{
|
||||||
|
if ((nullptr == dstMem) || (0 == srcMem) || (0 == sz))
|
||||||
|
return;
|
||||||
|
|
||||||
|
reg64 _src = { srcMem };
|
||||||
|
#ifdef _M_IX86
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
X64_Start();
|
||||||
|
|
||||||
|
;// below code is compiled as x86 inline asm, but it is executed as x64 code
|
||||||
|
;// that's why it need sometimes REX_W() macro, right column contains detailed
|
||||||
|
;// transcription how it will be interpreted by CPU
|
||||||
|
|
||||||
|
push edi ;// push rdi
|
||||||
|
push esi ;// push rsi
|
||||||
|
;//
|
||||||
|
mov edi, dstMem ;// mov edi, dword ptr [dstMem] ; high part of RDI is zeroed
|
||||||
|
REX_W mov esi, _src.dw[0] ;// mov rsi, qword ptr [_src]
|
||||||
|
mov ecx, sz ;// mov ecx, dword ptr [sz] ; high part of RCX is zeroed
|
||||||
|
;//
|
||||||
|
mov eax, ecx ;// mov eax, ecx
|
||||||
|
and eax, 3 ;// and eax, 3
|
||||||
|
shr ecx, 2 ;// shr ecx, 2
|
||||||
|
;//
|
||||||
|
rep movsd ;// rep movs dword ptr [rdi], dword ptr [rsi]
|
||||||
|
;//
|
||||||
|
test eax, eax ;// test eax, eax
|
||||||
|
je _move_0 ;// je _move_0
|
||||||
|
cmp eax, 1 ;// cmp eax, 1
|
||||||
|
je _move_1 ;// je _move_1
|
||||||
|
;//
|
||||||
|
movsw ;// movs word ptr [rdi], word ptr [rsi]
|
||||||
|
cmp eax, 2 ;// cmp eax, 2
|
||||||
|
je _move_0 ;// je _move_0
|
||||||
|
;//
|
||||||
|
_move_1: ;//
|
||||||
|
movsb ;// movs byte ptr [rdi], byte ptr [rsi]
|
||||||
|
;//
|
||||||
|
_move_0: ;//
|
||||||
|
pop esi ;// pop rsi
|
||||||
|
pop edi ;// pop rdi
|
||||||
|
|
||||||
|
X64_End();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmpMem64(const void* dstMem, DWORD64 srcMem, size_t sz)
|
||||||
|
{
|
||||||
|
if ((nullptr == dstMem) || (0 == srcMem) || (0 == sz))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
reg64 _src = { srcMem };
|
||||||
|
#ifdef _M_IX86
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
X64_Start();
|
||||||
|
|
||||||
|
;// below code is compiled as x86 inline asm, but it is executed as x64 code
|
||||||
|
;// that's why it need sometimes REX_W() macro, right column contains detailed
|
||||||
|
;// transcription how it will be interpreted by CPU
|
||||||
|
|
||||||
|
push edi ;// push rdi
|
||||||
|
push esi ;// push rsi
|
||||||
|
;//
|
||||||
|
mov edi, dstMem ;// mov edi, dword ptr [dstMem] ; high part of RDI is zeroed
|
||||||
|
REX_W mov esi, _src.dw[0] ;// mov rsi, qword ptr [_src]
|
||||||
|
mov ecx, sz ;// mov ecx, dword ptr [sz] ; high part of RCX is zeroed
|
||||||
|
;//
|
||||||
|
mov eax, ecx ;// mov eax, ecx
|
||||||
|
and eax, 3 ;// and eax, 3
|
||||||
|
shr ecx, 2 ;// shr ecx, 2
|
||||||
|
;//
|
||||||
|
repe cmpsd ;// repe cmps dword ptr [rsi], dword ptr [rdi]
|
||||||
|
jnz _ret_false ;// jnz _ret_false
|
||||||
|
;//
|
||||||
|
test eax, eax ;// test eax, eax
|
||||||
|
je _move_0 ;// je _move_0
|
||||||
|
cmp eax, 1 ;// cmp eax, 1
|
||||||
|
je _move_1 ;// je _move_1
|
||||||
|
;//
|
||||||
|
cmpsw ;// cmps word ptr [rsi], word ptr [rdi]
|
||||||
|
jnz _ret_false ;// jnz _ret_false
|
||||||
|
cmp eax, 2 ;// cmp eax, 2
|
||||||
|
je _move_0 ;// je _move_0
|
||||||
|
;//
|
||||||
|
_move_1: ;//
|
||||||
|
cmpsb ;// cmps byte ptr [rsi], byte ptr [rdi]
|
||||||
|
jnz _ret_false ;// jnz _ret_false
|
||||||
|
;//
|
||||||
|
_move_0: ;//
|
||||||
|
mov result, 1 ;// mov byte ptr [result], 1
|
||||||
|
;//
|
||||||
|
_ret_false: ;//
|
||||||
|
pop esi ;// pop rsi
|
||||||
|
pop edi ;// pop rdi
|
||||||
|
|
||||||
|
X64_End();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD64 getTEB64()
|
||||||
|
{
|
||||||
|
reg64 reg;
|
||||||
|
reg.v = 0;
|
||||||
|
#ifdef _M_IX86
|
||||||
|
X64_Start();
|
||||||
|
// R12 register should always contain pointer to TEB64 in WoW64 processes
|
||||||
|
X64_Push(_R12);
|
||||||
|
// below pop will pop QWORD from stack, as we're in x64 mode now
|
||||||
|
__asm pop reg.dw[0]
|
||||||
|
X64_End();
|
||||||
|
#endif
|
||||||
|
return reg.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" DWORD64 __cdecl GetModuleHandle64(const wchar_t* lpModuleName)
|
||||||
|
{
|
||||||
|
if (!g_isWow64)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
TEB64 teb64;
|
||||||
|
getMem64(&teb64, getTEB64(), sizeof(TEB64));
|
||||||
|
|
||||||
|
PEB64 peb64;
|
||||||
|
getMem64(&peb64, teb64.ProcessEnvironmentBlock, sizeof(PEB64));
|
||||||
|
PEB_LDR_DATA64 ldr;
|
||||||
|
getMem64(&ldr, peb64.Ldr, sizeof(PEB_LDR_DATA64));
|
||||||
|
|
||||||
|
DWORD64 LastEntry = peb64.Ldr + offsetof(PEB_LDR_DATA64, InLoadOrderModuleList);
|
||||||
|
LDR_DATA_TABLE_ENTRY64 head;
|
||||||
|
head.InLoadOrderLinks.Flink = ldr.InLoadOrderModuleList.Flink;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
getMem64(&head, head.InLoadOrderLinks.Flink, sizeof(LDR_DATA_TABLE_ENTRY64));
|
||||||
|
|
||||||
|
wchar_t* tempBuf = (wchar_t*)malloc(head.BaseDllName.MaximumLength);
|
||||||
|
if (nullptr == tempBuf)
|
||||||
|
return 0;
|
||||||
|
WATCH(tempBuf);
|
||||||
|
getMem64(tempBuf, head.BaseDllName.Buffer, head.BaseDllName.MaximumLength);
|
||||||
|
|
||||||
|
if (0 == _wcsicmp(lpModuleName, tempBuf))
|
||||||
|
return head.DllBase;
|
||||||
|
}
|
||||||
|
while (head.InLoadOrderLinks.Flink != LastEntry);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD64 __cdecl getNTDLL64()
|
||||||
|
{
|
||||||
|
static DWORD64 ntdll64 = 0;
|
||||||
|
if (0 != ntdll64)
|
||||||
|
return ntdll64;
|
||||||
|
|
||||||
|
ntdll64 = GetModuleHandle64(L"ntdll.dll");
|
||||||
|
return ntdll64;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD64 getLdrGetProcedureAddress()
|
||||||
|
{
|
||||||
|
DWORD64 modBase = getNTDLL64();
|
||||||
|
if (0 == modBase)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
IMAGE_DOS_HEADER idh;
|
||||||
|
getMem64(&idh, modBase, sizeof(idh));
|
||||||
|
|
||||||
|
IMAGE_NT_HEADERS64 inh;
|
||||||
|
getMem64(&inh, modBase + idh.e_lfanew, sizeof(IMAGE_NT_HEADERS64));
|
||||||
|
|
||||||
|
IMAGE_DATA_DIRECTORY& idd = inh.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
|
||||||
|
|
||||||
|
if (0 == idd.VirtualAddress)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
IMAGE_EXPORT_DIRECTORY ied;
|
||||||
|
getMem64(&ied, modBase + idd.VirtualAddress, sizeof(ied));
|
||||||
|
|
||||||
|
DWORD* rvaTable = (DWORD*)malloc(sizeof(DWORD)*ied.NumberOfFunctions);
|
||||||
|
if (nullptr == rvaTable)
|
||||||
|
return 0;
|
||||||
|
WATCH(rvaTable);
|
||||||
|
getMem64(rvaTable, modBase + ied.AddressOfFunctions, sizeof(DWORD)*ied.NumberOfFunctions);
|
||||||
|
|
||||||
|
WORD* ordTable = (WORD*)malloc(sizeof(WORD)*ied.NumberOfFunctions);
|
||||||
|
if (nullptr == ordTable)
|
||||||
|
return 0;
|
||||||
|
WATCH(ordTable);
|
||||||
|
getMem64(ordTable, modBase + ied.AddressOfNameOrdinals, sizeof(WORD)*ied.NumberOfFunctions);
|
||||||
|
|
||||||
|
DWORD* nameTable = (DWORD*)malloc(sizeof(DWORD)*ied.NumberOfNames);
|
||||||
|
if (nullptr == nameTable)
|
||||||
|
return 0;
|
||||||
|
WATCH(nameTable);
|
||||||
|
getMem64(nameTable, modBase + ied.AddressOfNames, sizeof(DWORD)*ied.NumberOfNames);
|
||||||
|
|
||||||
|
// lazy search, there is no need to use binsearch for just one function
|
||||||
|
for (DWORD i = 0; i < ied.NumberOfFunctions; i++)
|
||||||
|
{
|
||||||
|
if (!cmpMem64("LdrGetProcedureAddress", modBase + nameTable[i], sizeof("LdrGetProcedureAddress")))
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
return modBase + rvaTable[ordTable[i]];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" VOID __cdecl SetLastErrorFromX64Call(DWORD64 status)
|
||||||
|
{
|
||||||
|
typedef ULONG (WINAPI *RtlNtStatusToDosError_t)(LONG Status);
|
||||||
|
typedef ULONG (WINAPI *RtlSetLastWin32Error_t)(LONG Status);
|
||||||
|
|
||||||
|
static RtlNtStatusToDosError_t RtlNtStatusToDosError = nullptr;
|
||||||
|
static RtlSetLastWin32Error_t RtlSetLastWin32Error = nullptr;
|
||||||
|
|
||||||
|
if ((nullptr == RtlNtStatusToDosError) || (nullptr == RtlSetLastWin32Error))
|
||||||
|
{
|
||||||
|
HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
|
||||||
|
RtlNtStatusToDosError = (RtlNtStatusToDosError_t)GetProcAddress(ntdll, "RtlNtStatusToDosError");
|
||||||
|
RtlSetLastWin32Error = (RtlSetLastWin32Error_t)GetProcAddress(ntdll, "RtlSetLastWin32Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((nullptr != RtlNtStatusToDosError) && (nullptr != RtlSetLastWin32Error))
|
||||||
|
{
|
||||||
|
RtlSetLastWin32Error(RtlNtStatusToDosError((DWORD)status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" DWORD64 __cdecl GetProcAddress64(DWORD64 hModule, const char* funcName)
|
||||||
|
{
|
||||||
|
static DWORD64 _LdrGetProcedureAddress = 0;
|
||||||
|
if (0 == _LdrGetProcedureAddress)
|
||||||
|
{
|
||||||
|
_LdrGetProcedureAddress = getLdrGetProcedureAddress();
|
||||||
|
if (0 == _LdrGetProcedureAddress)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_UNICODE_STRING_T<DWORD64> fName = { 0 };
|
||||||
|
fName.Buffer = (DWORD64)funcName;
|
||||||
|
fName.Length = (WORD)strlen(funcName);
|
||||||
|
fName.MaximumLength = fName.Length + 1;
|
||||||
|
DWORD64 funcRet = 0;
|
||||||
|
X64Call(_LdrGetProcedureAddress, 4, (DWORD64)hModule, (DWORD64)&fName, (DWORD64)0, (DWORD64)&funcRet);
|
||||||
|
return funcRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" SIZE_T __cdecl VirtualQueryEx64(HANDLE hProcess, DWORD64 lpAddress, MEMORY_BASIC_INFORMATION64* lpBuffer, SIZE_T dwLength)
|
||||||
|
{
|
||||||
|
static DWORD64 ntqvm = 0;
|
||||||
|
if (0 == ntqvm)
|
||||||
|
{
|
||||||
|
ntqvm = GetProcAddress64(getNTDLL64(), "NtQueryVirtualMemory");
|
||||||
|
if (0 == ntqvm)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DWORD64 ret = 0;
|
||||||
|
DWORD64 status = X64Call(ntqvm, 6, (DWORD64)hProcess, lpAddress, (DWORD64)0, (DWORD64)lpBuffer, (DWORD64)dwLength, (DWORD64)&ret);
|
||||||
|
if (STATUS_SUCCESS != status)
|
||||||
|
SetLastErrorFromX64Call(status);
|
||||||
|
return (SIZE_T)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" DWORD64 __cdecl VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect)
|
||||||
|
{
|
||||||
|
static DWORD64 ntavm = 0;
|
||||||
|
if (0 == ntavm)
|
||||||
|
{
|
||||||
|
ntavm = GetProcAddress64(getNTDLL64(), "NtAllocateVirtualMemory");
|
||||||
|
if (0 == ntavm)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD64 tmpAddr = lpAddress;
|
||||||
|
DWORD64 tmpSize = dwSize;
|
||||||
|
DWORD64 ret = X64Call(ntavm, 6, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)0, (DWORD64)&tmpSize, (DWORD64)flAllocationType, (DWORD64)flProtect);
|
||||||
|
if (STATUS_SUCCESS != ret)
|
||||||
|
{
|
||||||
|
SetLastErrorFromX64Call(ret);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return tmpAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" BOOL __cdecl VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD dwFreeType)
|
||||||
|
{
|
||||||
|
static DWORD64 ntfvm = 0;
|
||||||
|
if (0 == ntfvm)
|
||||||
|
{
|
||||||
|
ntfvm = GetProcAddress64(getNTDLL64(), "NtFreeVirtualMemory");
|
||||||
|
if (0 == ntfvm)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD64 tmpAddr = lpAddress;
|
||||||
|
DWORD64 tmpSize = dwSize;
|
||||||
|
DWORD64 ret = X64Call(ntfvm, 4, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)&tmpSize, (DWORD64)dwFreeType);
|
||||||
|
if (STATUS_SUCCESS != ret)
|
||||||
|
{
|
||||||
|
SetLastErrorFromX64Call(ret);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" BOOL __cdecl VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect)
|
||||||
|
{
|
||||||
|
static DWORD64 ntpvm = 0;
|
||||||
|
if (0 == ntpvm)
|
||||||
|
{
|
||||||
|
ntpvm = GetProcAddress64(getNTDLL64(), "NtProtectVirtualMemory");
|
||||||
|
if (0 == ntpvm)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD64 tmpAddr = lpAddress;
|
||||||
|
DWORD64 tmpSize = dwSize;
|
||||||
|
DWORD64 ret = X64Call(ntpvm, 5, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)&tmpSize, (DWORD64)flNewProtect, (DWORD64)lpflOldProtect);
|
||||||
|
if (STATUS_SUCCESS != ret)
|
||||||
|
{
|
||||||
|
SetLastErrorFromX64Call(ret);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" BOOL __cdecl ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead)
|
||||||
|
{
|
||||||
|
static DWORD64 nrvm = 0;
|
||||||
|
if (0 == nrvm)
|
||||||
|
{
|
||||||
|
nrvm = GetProcAddress64(getNTDLL64(), "NtReadVirtualMemory");
|
||||||
|
if (0 == nrvm)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DWORD64 numOfBytes = lpNumberOfBytesRead ? *lpNumberOfBytesRead : 0;
|
||||||
|
DWORD64 ret = X64Call(nrvm, 5, (DWORD64)hProcess, lpBaseAddress, (DWORD64)lpBuffer, (DWORD64)nSize, (DWORD64)&numOfBytes);
|
||||||
|
if (STATUS_SUCCESS != ret && ret != 0x8000000DL) // STATUS_PARTIAL_COPY
|
||||||
|
{
|
||||||
|
SetLastErrorFromX64Call(ret);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (lpNumberOfBytesRead)
|
||||||
|
*lpNumberOfBytesRead = (SIZE_T)numOfBytes;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" BOOL __cdecl WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten)
|
||||||
|
{
|
||||||
|
static DWORD64 nrvm = 0;
|
||||||
|
if (0 == nrvm)
|
||||||
|
{
|
||||||
|
nrvm = GetProcAddress64(getNTDLL64(), "NtWriteVirtualMemory");
|
||||||
|
if (0 == nrvm)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DWORD64 numOfBytes = lpNumberOfBytesWritten ? *lpNumberOfBytesWritten : 0;
|
||||||
|
DWORD64 ret = X64Call(nrvm, 5, (DWORD64)hProcess, lpBaseAddress, (DWORD64)lpBuffer, (DWORD64)nSize, (DWORD64)&numOfBytes);
|
||||||
|
if (STATUS_SUCCESS != ret)
|
||||||
|
{
|
||||||
|
SetLastErrorFromX64Call(ret);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (lpNumberOfBytesWritten)
|
||||||
|
*lpNumberOfBytesWritten = (SIZE_T)numOfBytes;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" BOOL __cdecl GetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext)
|
||||||
|
{
|
||||||
|
static DWORD64 gtc = 0;
|
||||||
|
if (0 == gtc)
|
||||||
|
{
|
||||||
|
gtc = GetProcAddress64(getNTDLL64(), "NtGetContextThread");
|
||||||
|
if (0 == gtc)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DWORD64 ret = X64Call(gtc, 2, (DWORD64)hThread, (DWORD64)lpContext);
|
||||||
|
if(STATUS_SUCCESS != ret)
|
||||||
|
{
|
||||||
|
SetLastErrorFromX64Call(ret);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" BOOL __cdecl SetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext)
|
||||||
|
{
|
||||||
|
static DWORD64 stc = 0;
|
||||||
|
if (0 == stc)
|
||||||
|
{
|
||||||
|
stc = GetProcAddress64(getNTDLL64(), "NtSetContextThread");
|
||||||
|
if (0 == stc)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DWORD64 ret = X64Call(stc, 2, (DWORD64)hThread, (DWORD64)lpContext);
|
||||||
|
if (STATUS_SUCCESS != ret)
|
||||||
|
{
|
||||||
|
SetLastErrorFromX64Call(ret);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
}
|
|
@ -0,0 +1,377 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* WOW64Ext Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 ReWolf
|
||||||
|
* http://blog.rewolf.pl/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#ifndef STATUS_SUCCESS
|
||||||
|
# define STATUS_SUCCESS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma warning(disable : 4201)
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(1)
|
||||||
|
template <class T>
|
||||||
|
struct _LIST_ENTRY_T
|
||||||
|
{
|
||||||
|
T Flink;
|
||||||
|
T Blink;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct _UNICODE_STRING_T
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
WORD Length;
|
||||||
|
WORD MaximumLength;
|
||||||
|
};
|
||||||
|
T dummy;
|
||||||
|
};
|
||||||
|
T Buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct _NT_TIB_T
|
||||||
|
{
|
||||||
|
T ExceptionList;
|
||||||
|
T StackBase;
|
||||||
|
T StackLimit;
|
||||||
|
T SubSystemTib;
|
||||||
|
T FiberData;
|
||||||
|
T ArbitraryUserPointer;
|
||||||
|
T Self;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct _CLIENT_ID_T
|
||||||
|
{
|
||||||
|
T UniqueProcess;
|
||||||
|
T UniqueThread;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct _TEB_T_
|
||||||
|
{
|
||||||
|
_NT_TIB_T<T> NtTib;
|
||||||
|
T EnvironmentPointer;
|
||||||
|
_CLIENT_ID_T<T> ClientId;
|
||||||
|
T ActiveRpcHandle;
|
||||||
|
T ThreadLocalStoragePointer;
|
||||||
|
T ProcessEnvironmentBlock;
|
||||||
|
DWORD LastErrorValue;
|
||||||
|
DWORD CountOfOwnedCriticalSections;
|
||||||
|
T CsrClientThread;
|
||||||
|
T Win32ThreadInfo;
|
||||||
|
DWORD User32Reserved[26];
|
||||||
|
//rest of the structure is not defined for now, as it is not needed
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct _LDR_DATA_TABLE_ENTRY_T
|
||||||
|
{
|
||||||
|
_LIST_ENTRY_T<T> InLoadOrderLinks;
|
||||||
|
_LIST_ENTRY_T<T> InMemoryOrderLinks;
|
||||||
|
_LIST_ENTRY_T<T> InInitializationOrderLinks;
|
||||||
|
T DllBase;
|
||||||
|
T EntryPoint;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
DWORD SizeOfImage;
|
||||||
|
T dummy01;
|
||||||
|
};
|
||||||
|
_UNICODE_STRING_T<T> FullDllName;
|
||||||
|
_UNICODE_STRING_T<T> BaseDllName;
|
||||||
|
DWORD Flags;
|
||||||
|
WORD LoadCount;
|
||||||
|
WORD TlsIndex;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
_LIST_ENTRY_T<T> HashLinks;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
T SectionPointer;
|
||||||
|
T CheckSum;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
T LoadedImports;
|
||||||
|
DWORD TimeDateStamp;
|
||||||
|
};
|
||||||
|
T EntryPointActivationContext;
|
||||||
|
T PatchInformation;
|
||||||
|
_LIST_ENTRY_T<T> ForwarderLinks;
|
||||||
|
_LIST_ENTRY_T<T> ServiceTagLinks;
|
||||||
|
_LIST_ENTRY_T<T> StaticLinks;
|
||||||
|
T ContextInformation;
|
||||||
|
T OriginalBase;
|
||||||
|
_LARGE_INTEGER LoadTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct _PEB_LDR_DATA_T
|
||||||
|
{
|
||||||
|
DWORD Length;
|
||||||
|
DWORD Initialized;
|
||||||
|
T SsHandle;
|
||||||
|
_LIST_ENTRY_T<T> InLoadOrderModuleList;
|
||||||
|
_LIST_ENTRY_T<T> InMemoryOrderModuleList;
|
||||||
|
_LIST_ENTRY_T<T> InInitializationOrderModuleList;
|
||||||
|
T EntryInProgress;
|
||||||
|
DWORD ShutdownInProgress;
|
||||||
|
T ShutdownThreadId;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class NGF, int A>
|
||||||
|
struct _PEB_T
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
BYTE InheritedAddressSpace;
|
||||||
|
BYTE ReadImageFileExecOptions;
|
||||||
|
BYTE BeingDebugged;
|
||||||
|
BYTE BitField;
|
||||||
|
};
|
||||||
|
T dummy01;
|
||||||
|
};
|
||||||
|
T Mutant;
|
||||||
|
T ImageBaseAddress;
|
||||||
|
T Ldr;
|
||||||
|
T ProcessParameters;
|
||||||
|
T SubSystemData;
|
||||||
|
T ProcessHeap;
|
||||||
|
T FastPebLock;
|
||||||
|
T AtlThunkSListPtr;
|
||||||
|
T IFEOKey;
|
||||||
|
T CrossProcessFlags;
|
||||||
|
T UserSharedInfoPtr;
|
||||||
|
DWORD SystemReserved;
|
||||||
|
DWORD AtlThunkSListPtr32;
|
||||||
|
T ApiSetMap;
|
||||||
|
T TlsExpansionCounter;
|
||||||
|
T TlsBitmap;
|
||||||
|
DWORD TlsBitmapBits[2];
|
||||||
|
T ReadOnlySharedMemoryBase;
|
||||||
|
T HotpatchInformation;
|
||||||
|
T ReadOnlyStaticServerData;
|
||||||
|
T AnsiCodePageData;
|
||||||
|
T OemCodePageData;
|
||||||
|
T UnicodeCaseTableData;
|
||||||
|
DWORD NumberOfProcessors;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
DWORD NtGlobalFlag;
|
||||||
|
NGF dummy02;
|
||||||
|
};
|
||||||
|
LARGE_INTEGER CriticalSectionTimeout;
|
||||||
|
T HeapSegmentReserve;
|
||||||
|
T HeapSegmentCommit;
|
||||||
|
T HeapDeCommitTotalFreeThreshold;
|
||||||
|
T HeapDeCommitFreeBlockThreshold;
|
||||||
|
DWORD NumberOfHeaps;
|
||||||
|
DWORD MaximumNumberOfHeaps;
|
||||||
|
T ProcessHeaps;
|
||||||
|
T GdiSharedHandleTable;
|
||||||
|
T ProcessStarterHelper;
|
||||||
|
T GdiDCAttributeList;
|
||||||
|
T LoaderLock;
|
||||||
|
DWORD OSMajorVersion;
|
||||||
|
DWORD OSMinorVersion;
|
||||||
|
WORD OSBuildNumber;
|
||||||
|
WORD OSCSDVersion;
|
||||||
|
DWORD OSPlatformId;
|
||||||
|
DWORD ImageSubsystem;
|
||||||
|
DWORD ImageSubsystemMajorVersion;
|
||||||
|
T ImageSubsystemMinorVersion;
|
||||||
|
T ActiveProcessAffinityMask;
|
||||||
|
T GdiHandleBuffer[A];
|
||||||
|
T PostProcessInitRoutine;
|
||||||
|
T TlsExpansionBitmap;
|
||||||
|
DWORD TlsExpansionBitmapBits[32];
|
||||||
|
T SessionId;
|
||||||
|
ULARGE_INTEGER AppCompatFlags;
|
||||||
|
ULARGE_INTEGER AppCompatFlagsUser;
|
||||||
|
T pShimData;
|
||||||
|
T AppCompatInfo;
|
||||||
|
_UNICODE_STRING_T<T> CSDVersion;
|
||||||
|
T ActivationContextData;
|
||||||
|
T ProcessAssemblyStorageMap;
|
||||||
|
T SystemDefaultActivationContextData;
|
||||||
|
T SystemAssemblyStorageMap;
|
||||||
|
T MinimumStackCommit;
|
||||||
|
T FlsCallback;
|
||||||
|
_LIST_ENTRY_T<T> FlsListHead;
|
||||||
|
T FlsBitmap;
|
||||||
|
DWORD FlsBitmapBits[4];
|
||||||
|
T FlsHighIndex;
|
||||||
|
T WerRegistrationData;
|
||||||
|
T WerShipAssertPtr;
|
||||||
|
T pContextData;
|
||||||
|
T pImageHeaderHash;
|
||||||
|
T TracingFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef _LDR_DATA_TABLE_ENTRY_T<DWORD> LDR_DATA_TABLE_ENTRY32;
|
||||||
|
typedef _LDR_DATA_TABLE_ENTRY_T<DWORD64> LDR_DATA_TABLE_ENTRY64;
|
||||||
|
|
||||||
|
typedef _TEB_T_<DWORD> TEB32;
|
||||||
|
typedef _TEB_T_<DWORD64> TEB64;
|
||||||
|
|
||||||
|
typedef _PEB_LDR_DATA_T<DWORD> PEB_LDR_DATA32;
|
||||||
|
typedef _PEB_LDR_DATA_T<DWORD64> PEB_LDR_DATA64;
|
||||||
|
|
||||||
|
typedef _PEB_T<DWORD, DWORD64, 34> PEB32;
|
||||||
|
typedef _PEB_T<DWORD64, DWORD, 30> PEB64;
|
||||||
|
|
||||||
|
struct _XSAVE_FORMAT64
|
||||||
|
{
|
||||||
|
WORD ControlWord;
|
||||||
|
WORD StatusWord;
|
||||||
|
BYTE TagWord;
|
||||||
|
BYTE Reserved1;
|
||||||
|
WORD ErrorOpcode;
|
||||||
|
DWORD ErrorOffset;
|
||||||
|
WORD ErrorSelector;
|
||||||
|
WORD Reserved2;
|
||||||
|
DWORD DataOffset;
|
||||||
|
WORD DataSelector;
|
||||||
|
WORD Reserved3;
|
||||||
|
DWORD MxCsr;
|
||||||
|
DWORD MxCsr_Mask;
|
||||||
|
_M128A FloatRegisters[8];
|
||||||
|
_M128A XmmRegisters[16];
|
||||||
|
BYTE Reserved4[96];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _CONTEXT64_2
|
||||||
|
{
|
||||||
|
DWORD64 P1Home;
|
||||||
|
DWORD64 P2Home;
|
||||||
|
DWORD64 P3Home;
|
||||||
|
DWORD64 P4Home;
|
||||||
|
DWORD64 P5Home;
|
||||||
|
DWORD64 P6Home;
|
||||||
|
DWORD ContextFlags;
|
||||||
|
DWORD MxCsr;
|
||||||
|
WORD SegCs;
|
||||||
|
WORD SegDs;
|
||||||
|
WORD SegEs;
|
||||||
|
WORD SegFs;
|
||||||
|
WORD SegGs;
|
||||||
|
WORD SegSs;
|
||||||
|
DWORD EFlags;
|
||||||
|
DWORD64 Dr0;
|
||||||
|
DWORD64 Dr1;
|
||||||
|
DWORD64 Dr2;
|
||||||
|
DWORD64 Dr3;
|
||||||
|
DWORD64 Dr6;
|
||||||
|
DWORD64 Dr7;
|
||||||
|
DWORD64 Rax;
|
||||||
|
DWORD64 Rcx;
|
||||||
|
DWORD64 Rdx;
|
||||||
|
DWORD64 Rbx;
|
||||||
|
DWORD64 Rsp;
|
||||||
|
DWORD64 Rbp;
|
||||||
|
DWORD64 Rsi;
|
||||||
|
DWORD64 Rdi;
|
||||||
|
DWORD64 R8;
|
||||||
|
DWORD64 R9;
|
||||||
|
DWORD64 R10;
|
||||||
|
DWORD64 R11;
|
||||||
|
DWORD64 R12;
|
||||||
|
DWORD64 R13;
|
||||||
|
DWORD64 R14;
|
||||||
|
DWORD64 R15;
|
||||||
|
DWORD64 Rip;
|
||||||
|
_XSAVE_FORMAT64 FltSave;
|
||||||
|
_M128A Header[2];
|
||||||
|
_M128A Legacy[8];
|
||||||
|
_M128A Xmm0;
|
||||||
|
_M128A Xmm1;
|
||||||
|
_M128A Xmm2;
|
||||||
|
_M128A Xmm3;
|
||||||
|
_M128A Xmm4;
|
||||||
|
_M128A Xmm5;
|
||||||
|
_M128A Xmm6;
|
||||||
|
_M128A Xmm7;
|
||||||
|
_M128A Xmm8;
|
||||||
|
_M128A Xmm9;
|
||||||
|
_M128A Xmm10;
|
||||||
|
_M128A Xmm11;
|
||||||
|
_M128A Xmm12;
|
||||||
|
_M128A Xmm13;
|
||||||
|
_M128A Xmm14;
|
||||||
|
_M128A Xmm15;
|
||||||
|
_M128A VectorRegister[26];
|
||||||
|
DWORD64 VectorControl;
|
||||||
|
DWORD64 DebugControl;
|
||||||
|
DWORD64 LastBranchToRip;
|
||||||
|
DWORD64 LastBranchFromRip;
|
||||||
|
DWORD64 LastExceptionToRip;
|
||||||
|
DWORD64 LastExceptionFromRip;
|
||||||
|
};
|
||||||
|
#pragma warning(default : 4201)
|
||||||
|
|
||||||
|
// Below defines for .ContextFlags field are taken from WinNT.h
|
||||||
|
#ifndef CONTEXT_AMD64
|
||||||
|
#define CONTEXT_AMD64 0x100000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONTEXT64_CONTROL (CONTEXT_AMD64 | 0x1L)
|
||||||
|
#define CONTEXT64_INTEGER (CONTEXT_AMD64 | 0x2L)
|
||||||
|
#define CONTEXT64_SEGMENTS (CONTEXT_AMD64 | 0x4L)
|
||||||
|
#define CONTEXT64_FLOATING_POINT (CONTEXT_AMD64 | 0x8L)
|
||||||
|
#define CONTEXT64_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L)
|
||||||
|
#define CONTEXT64_FULL (CONTEXT64_CONTROL | CONTEXT64_INTEGER | CONTEXT64_FLOATING_POINT)
|
||||||
|
#define CONTEXT64_ALL (CONTEXT64_CONTROL | CONTEXT64_INTEGER | CONTEXT64_SEGMENTS | CONTEXT64_FLOATING_POINT | CONTEXT64_DEBUG_REGISTERS)
|
||||||
|
#define CONTEXT64_XSTATE (CONTEXT_AMD64 | 0x20L)
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#ifdef WOW64EXT_EXPORTS
|
||||||
|
# define SPEC dllexport
|
||||||
|
#else
|
||||||
|
# define SPEC dllimport
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
DWORD64 __cdecl X64Call(DWORD64 func, int argC, ...);
|
||||||
|
DWORD64 __cdecl GetModuleHandle64(const wchar_t* lpModuleName);
|
||||||
|
DWORD64 __cdecl getNTDLL64();
|
||||||
|
DWORD64 __cdecl GetProcAddress64(DWORD64 hModule, const char* funcName);
|
||||||
|
SIZE_T __cdecl VirtualQueryEx64(HANDLE hProcess, DWORD64 lpAddress, MEMORY_BASIC_INFORMATION64* lpBuffer, SIZE_T dwLength);
|
||||||
|
DWORD64 __cdecl VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
|
||||||
|
BOOL __cdecl VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD dwFreeType);
|
||||||
|
BOOL __cdecl VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect);
|
||||||
|
BOOL __cdecl ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead);
|
||||||
|
BOOL __cdecl WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten);
|
||||||
|
BOOL __cdecl GetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext);
|
||||||
|
BOOL __cdecl SetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext);
|
||||||
|
VOID __cdecl SetLastErrorFromX64Call(DWORD64 status);
|
||||||
|
}
|
|
@ -219,6 +219,10 @@
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\common\wow64ext\wow64ext.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="advapi.c">
|
<ClCompile Include="advapi.c">
|
||||||
<ShowIncludes Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">false</ShowIncludes>
|
<ShowIncludes Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">false</ShowIncludes>
|
||||||
<ShowIncludes Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">false</ShowIncludes>
|
<ShowIncludes Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">false</ShowIncludes>
|
||||||
|
@ -412,6 +416,9 @@
|
||||||
<ClInclude Include="..\..\common\rbtree.h" />
|
<ClInclude Include="..\..\common\rbtree.h" />
|
||||||
<ClInclude Include="..\..\common\stream.h" />
|
<ClInclude Include="..\..\common\stream.h" />
|
||||||
<ClInclude Include="..\..\common\win32_ntddk.h" />
|
<ClInclude Include="..\..\common\win32_ntddk.h" />
|
||||||
|
<ClInclude Include="..\..\common\wow64ext\CMemPtr.h" />
|
||||||
|
<ClInclude Include="..\..\common\wow64ext\internal.h" />
|
||||||
|
<ClInclude Include="..\..\common\wow64ext\wow64ext.h" />
|
||||||
<ClInclude Include="advapi.h" />
|
<ClInclude Include="advapi.h" />
|
||||||
<ClInclude Include="debug.h" />
|
<ClInclude Include="debug.h" />
|
||||||
<ClInclude Include="dll.h" />
|
<ClInclude Include="dll.h" />
|
||||||
|
|
|
@ -208,6 +208,9 @@
|
||||||
<ClCompile Include="cred.c">
|
<ClCompile Include="cred.c">
|
||||||
<Filter>pst</Filter>
|
<Filter>pst</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\common\wow64ext\wow64ext.cpp">
|
||||||
|
<Filter>common\wow64ext</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="advapi.h" />
|
<ClInclude Include="advapi.h" />
|
||||||
|
@ -283,6 +286,15 @@
|
||||||
<ClInclude Include="..\..\common\win32_ntddk.h">
|
<ClInclude Include="..\..\common\win32_ntddk.h">
|
||||||
<Filter>common</Filter>
|
<Filter>common</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\common\wow64ext\CMemPtr.h">
|
||||||
|
<Filter>common\wow64ext</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\common\wow64ext\internal.h">
|
||||||
|
<Filter>common\wow64ext</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\common\wow64ext\wow64ext.h">
|
||||||
|
<Filter>common\wow64ext</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="resource.rc" />
|
<ResourceCompile Include="resource.rc" />
|
||||||
|
@ -338,6 +350,9 @@
|
||||||
<Filter Include="net">
|
<Filter Include="net">
|
||||||
<UniqueIdentifier>{bbd6a003-d74d-405a-bd10-e2fea62301f9}</UniqueIdentifier>
|
<UniqueIdentifier>{bbd6a003-d74d-405a-bd10-e2fea62301f9}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="common\wow64ext">
|
||||||
|
<UniqueIdentifier>{c6a9654a-9f55-43ca-9cd1-7571bb879288}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Midl Include="pstore.idl">
|
<Midl Include="pstore.idl">
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
|
|
||||||
#define HOOK_WIN32K
|
#define HOOK_WIN32K
|
||||||
|
|
||||||
//#define WOW64_EXPERIMEN
|
|
||||||
|
|
||||||
#ifdef HOOK_WIN32K
|
#ifdef HOOK_WIN32K
|
||||||
|
|
||||||
#include "core/drv/api_defs.h"
|
#include "core/drv/api_defs.h"
|
||||||
|
@ -83,7 +81,7 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
|
||||||
RegionBase = ZwXxxPtr;
|
RegionBase = ZwXxxPtr;
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
RegionSize = 12;
|
RegionSize = 14;
|
||||||
#else ! _WIN64
|
#else ! _WIN64
|
||||||
RegionSize = 10;
|
RegionSize = 10;
|
||||||
#endif _WIN64
|
#endif _WIN64
|
||||||
|
@ -106,7 +104,7 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
SyscallNum &= 0xFFFF; // clear the not needed param count
|
SyscallNum &= 0xFFFF; // clear the not needed param count
|
||||||
|
|
||||||
ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
|
ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
|
||||||
ZwXxxPtr[1] = 0xC7;
|
ZwXxxPtr[1] = 0xC7;
|
||||||
ZwXxxPtr[2] = 0xC2;
|
ZwXxxPtr[2] = 0xC2;
|
||||||
*(ULONG *)&ZwXxxPtr[3] = SyscallNum;
|
*(ULONG *)&ZwXxxPtr[3] = SyscallNum;
|
||||||
|
@ -124,7 +122,7 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
ZwXxxPtr[7] = 0xB8; // mov eax, SystemServiceAsm
|
ZwXxxPtr[7] = 0xB8; // mov eax, SystemServiceAsm
|
||||||
*(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)SystemServiceAsm;
|
*(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)SystemServiceAsm;
|
||||||
*(USHORT *)&ZwXxxPtr[12] = 0xE0FF; // jmp rax
|
*(USHORT *)&ZwXxxPtr[12] = 0xE0FF; // jmp rax
|
||||||
}
|
}
|
||||||
|
@ -151,144 +149,9 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
#ifdef WOW64_EXPERIMEN
|
|
||||||
_FX NTSTATUS SbieDll_WoW64SysCall(ULONG syscall, ULONG* args)
|
|
||||||
{
|
|
||||||
extern HANDLE SbieApi_DeviceHandle;
|
|
||||||
extern P_NtDeviceIoControlFile __sys_NtDeviceIoControlFile;
|
|
||||||
|
|
||||||
ULONG argc = (syscall >> 24);
|
BOOLEAN SbieDll_HookWoW64SysCalls();
|
||||||
syscall &= 0xFFFF;
|
|
||||||
|
|
||||||
ULONG64 stack[19];
|
|
||||||
for (ULONG i = 0; i < argc; i++)
|
|
||||||
stack[i] = args[i];
|
|
||||||
|
|
||||||
NTSTATUS status;
|
|
||||||
__declspec(align(8)) ULONG64 parms[API_NUM_ARGS];
|
|
||||||
|
|
||||||
memset(parms, 0, sizeof(parms));
|
|
||||||
parms[0] = API_INVOKE_SYSCALL;
|
|
||||||
parms[1] = (ULONG64)(ULONG_PTR)syscall;
|
|
||||||
parms[2] = (ULONG64)(ULONG_PTR)stack; // pointer to system service arguments on stack
|
|
||||||
|
|
||||||
IO_STATUS_BLOCK MyIoStatusBlock;
|
|
||||||
status = __sys_NtDeviceIoControlFile(
|
|
||||||
SbieApi_DeviceHandle, NULL, NULL, NULL, &MyIoStatusBlock,
|
|
||||||
API_SBIEDRV_CTLCODE, parms, sizeof(ULONG64) * 8, NULL, 0);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma runtime_checks( "", off )
|
|
||||||
_FX NTSTATUS SbieDll_WoW64SysCallProc(ULONG arg0)
|
|
||||||
{
|
|
||||||
//push ebp
|
|
||||||
//mov ebp,esp
|
|
||||||
//sub esp,40h
|
|
||||||
//push ebx
|
|
||||||
//push esi
|
|
||||||
//push edi
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
mov ecx,eax // get the syscall number
|
|
||||||
//return SbieDll_WoW64SysCall(syscall, 19, &arg0);
|
|
||||||
lea eax,[ebp+8] // get address of arg0
|
|
||||||
push eax // args
|
|
||||||
push ecx // syscall
|
|
||||||
call SbieDll_WoW64SysCall
|
|
||||||
}
|
|
||||||
//pop edi
|
|
||||||
//pop esi
|
|
||||||
//pop ebx
|
|
||||||
//mov esp,ebp
|
|
||||||
//pop ebp
|
|
||||||
//ret 4
|
|
||||||
}
|
|
||||||
#pragma runtime_checks( "", restore )
|
|
||||||
|
|
||||||
_FX BOOLEAN SbieDll_HookWoW64SysCalls(HMODULE win32u_base)
|
|
||||||
{
|
|
||||||
UCHAR *SystemServiceAsm, *ZwXxxPtr;
|
|
||||||
ULONG *SyscallPtr;
|
|
||||||
ULONG SyscallNum;
|
|
||||||
char FuncName[68] = "Nt";
|
|
||||||
void *RegionBase;
|
|
||||||
SIZE_T RegionSize;
|
|
||||||
ULONG OldProtect;
|
|
||||||
|
|
||||||
SystemServiceAsm = (UCHAR*)SbieDll_WoW64SysCallProc;
|
|
||||||
|
|
||||||
UCHAR* syscall_data = (UCHAR *)HeapAlloc(GetProcessHeap(), 0, 144000); // enough room for 2000 syscalls with names
|
|
||||||
if (!syscall_data)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
NTSTATUS status = SbieApi_Call(API_QUERY_SYSCALLS, 3, (ULONG_PTR)syscall_data, 1, 1);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(status)) {
|
|
||||||
HeapFree(GetProcessHeap(), 0, syscall_data);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIST DisabledHookList;
|
|
||||||
List_Init(&DisabledHookList);
|
|
||||||
Config_InitPatternList(L"SkipWin32Hook", &DisabledHookList);
|
|
||||||
|
|
||||||
SyscallPtr = (ULONG *)(syscall_data
|
|
||||||
+ sizeof(ULONG)); // size of buffer
|
|
||||||
|
|
||||||
while (SyscallPtr[0] || SyscallPtr[1]) {
|
|
||||||
|
|
||||||
SyscallNum = SyscallPtr[0] | 0x1000;
|
|
||||||
strcpy(FuncName + 2, (char*)&SyscallPtr[2]);
|
|
||||||
ZwXxxPtr = (UCHAR*)GetProcAddress(win32u_base, FuncName);
|
|
||||||
if (!ZwXxxPtr)
|
|
||||||
goto next;
|
|
||||||
|
|
||||||
{
|
|
||||||
ULONG len = strlen((char*)&SyscallPtr[2]);
|
|
||||||
WCHAR wname[68];
|
|
||||||
for (ULONG i = 0; i < len; i++)
|
|
||||||
wname[i] = ((char*)&SyscallPtr[2])[i];
|
|
||||||
wname[len] = 0;
|
|
||||||
|
|
||||||
PATTERN* pat = List_Head(&DisabledHookList);
|
|
||||||
while (pat)
|
|
||||||
{
|
|
||||||
if (Pattern_Match(pat, _wcslwr(wname), len))
|
|
||||||
goto next;
|
|
||||||
|
|
||||||
pat = List_Next(pat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RegionBase = ZwXxxPtr;
|
|
||||||
RegionSize = 10;
|
|
||||||
|
|
||||||
NtProtectVirtualMemory(
|
|
||||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
|
||||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
|
||||||
|
|
||||||
ZwXxxPtr[0] = 0xB8; // mov eax, SyscallNumber
|
|
||||||
*(ULONG *)&ZwXxxPtr[1] = SyscallNum;
|
|
||||||
ZwXxxPtr[5] = 0xE9; // jmp SystemServiceAsm
|
|
||||||
*(ULONG *)&ZwXxxPtr[6] =
|
|
||||||
(ULONG)(ULONG_PTR)(SystemServiceAsm - (ZwXxxPtr + 10));
|
|
||||||
|
|
||||||
NtProtectVirtualMemory(
|
|
||||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
|
||||||
OldProtect, &OldProtect);
|
|
||||||
|
|
||||||
next:
|
|
||||||
SyscallPtr += 2 + 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
Config_FreePatternList(&DisabledHookList);
|
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, syscall_data);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -305,12 +168,6 @@ _FX BOOLEAN Win32_Init(HMODULE hmodule)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
// NoSysCallHooks END
|
// NoSysCallHooks END
|
||||||
|
|
||||||
#ifndef WOW64_EXPERIMEN
|
|
||||||
// ToDo: add no WoW64 support
|
|
||||||
if (Dll_IsWow64)
|
|
||||||
return TRUE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// disable Electron Workaround when we are ready to hook the required win32k syscalls
|
// disable Electron Workaround when we are ready to hook the required win32k syscalls
|
||||||
extern BOOL Dll_ElectronWorkaround;
|
extern BOOL Dll_ElectronWorkaround;
|
||||||
Dll_ElectronWorkaround = FALSE;
|
Dll_ElectronWorkaround = FALSE;
|
||||||
|
@ -325,11 +182,9 @@ _FX BOOLEAN Win32_Init(HMODULE hmodule)
|
||||||
|| SbieDll_GetSettingsForName_bool(NULL, Dll_ImageName, L"AlwaysUseWin32kHooks", FALSE)) {
|
|| SbieDll_GetSettingsForName_bool(NULL, Dll_ImageName, L"AlwaysUseWin32kHooks", FALSE)) {
|
||||||
|
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
#ifdef WOW64_EXPERIMEN
|
|
||||||
if (Dll_IsWow64)
|
if (Dll_IsWow64)
|
||||||
SbieDll_HookWoW64SysCalls(hmodule);
|
SbieDll_HookWoW64SysCalls();
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
SbieDll_HookWin32SysCalls(hmodule);
|
SbieDll_HookWin32SysCalls(hmodule);
|
||||||
}
|
}
|
||||||
|
@ -338,3 +193,212 @@ _FX BOOLEAN Win32_Init(HMODULE hmodule)
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HOOK_WIN32K
|
||||||
|
|
||||||
|
#ifndef _WIN64
|
||||||
|
|
||||||
|
//#include "../../common/wow64ext/wow64ext.h"
|
||||||
|
DWORD64 __cdecl X64Call(DWORD64 func, int argC, ...);
|
||||||
|
DWORD64 __cdecl GetModuleHandle64(const wchar_t* lpModuleName);
|
||||||
|
DWORD64 __cdecl getNTDLL64();
|
||||||
|
DWORD64 __cdecl GetProcAddress64(DWORD64 hModule, const char* funcName);
|
||||||
|
SIZE_T __cdecl VirtualQueryEx64(HANDLE hProcess, DWORD64 lpAddress, MEMORY_BASIC_INFORMATION64* lpBuffer, SIZE_T dwLength);
|
||||||
|
DWORD64 __cdecl VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
|
||||||
|
BOOL __cdecl VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD dwFreeType);
|
||||||
|
BOOL __cdecl VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect);
|
||||||
|
BOOL __cdecl ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead);
|
||||||
|
BOOL __cdecl WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten);
|
||||||
|
//BOOL __cdecl GetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext);
|
||||||
|
//BOOL __cdecl SetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext);
|
||||||
|
VOID __cdecl SetLastErrorFromX64Call(DWORD64 status);
|
||||||
|
|
||||||
|
|
||||||
|
ULONG Win32_WoW64_GetSysCallNumber(DWORD64 pos, UCHAR* dll_data)
|
||||||
|
{
|
||||||
|
// 4C 8B D1 - r10,rcx
|
||||||
|
if (!(dll_data[pos + 0] == 0x4c && dll_data[pos + 1] == 0x8b && dll_data[pos + 2] == 0xd1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// B8 XX XX XX XX - mov eax,0xXXXX
|
||||||
|
if (!(dll_data[pos + 3] == 0xb8))
|
||||||
|
return 0;
|
||||||
|
ULONG syscall_index = *(ULONG*)&dll_data[pos + 4];
|
||||||
|
|
||||||
|
// F6 04 25 08 03 FE 7F 01 - test BYTE PTR ds:0x7ffe0308,0x1
|
||||||
|
//
|
||||||
|
|
||||||
|
// 75 03 - jne 0x15 (label_1)
|
||||||
|
if (!(dll_data[pos + 16] == 0x75 && dll_data[pos + 17] == 0x03))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// 0F 05 - syscall
|
||||||
|
if (!(dll_data[pos + 18] == 0x0f && dll_data[pos + 19] == 0x05))
|
||||||
|
return 0;
|
||||||
|
// C3 - ret
|
||||||
|
if (!(dll_data[pos + 20] == 0xc3))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// label_1:
|
||||||
|
// CD 2E - int 0x2e
|
||||||
|
if (!(dll_data[pos + 21] == 0xcd && dll_data[pos + 22] == 0x2e))
|
||||||
|
return 0;
|
||||||
|
// C3 - ret
|
||||||
|
if (!(dll_data[pos + 23] == 0xc3))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// 0F 1F 84 00 00 00 00 00
|
||||||
|
//
|
||||||
|
|
||||||
|
return syscall_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
_FX BOOLEAN SbieDll_HookWoW64SysCalls()
|
||||||
|
{
|
||||||
|
BOOLEAN ok = FALSE;
|
||||||
|
UCHAR* dll_data = NULL;
|
||||||
|
UCHAR* syscall_data = NULL;
|
||||||
|
|
||||||
|
DWORD64 BaseAddress = GetModuleHandle64(L"wow64win.dll");
|
||||||
|
SIZE_T SizeOfImage = 0x00100000; // 1 MB should be more than enough
|
||||||
|
if (!BaseAddress)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
|
||||||
|
if (hProcess == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
dll_data = (UCHAR *)HeapAlloc(GetProcessHeap(), 0, (SIZE_T)SizeOfImage);
|
||||||
|
if (!dll_data)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
SIZE_T SizeRead;
|
||||||
|
if (!ReadProcessMemory64(hProcess, (PVOID64)BaseAddress, dll_data, SizeOfImage, &SizeRead))
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
DWORD64 FuncTable = 0;
|
||||||
|
|
||||||
|
for (DWORD64 pos = 0; pos < SizeRead-0x20; pos++) {
|
||||||
|
if (Win32_WoW64_GetSysCallNumber(pos, dll_data) != 0){
|
||||||
|
FuncTable = pos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FuncTable == 0)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
DWORD64 SystemServiceAsm;
|
||||||
|
UCHAR ZwXxxPtr[16];
|
||||||
|
ULONG *SyscallPtr;
|
||||||
|
ULONG SyscallNum;
|
||||||
|
DWORD64 RegionBase;
|
||||||
|
SIZE_T RegionSize;
|
||||||
|
ULONG OldProtect;
|
||||||
|
|
||||||
|
SBIELOW_DATA* data = SbieApi_data;
|
||||||
|
SystemServiceAsm = data->pSystemService;
|
||||||
|
|
||||||
|
syscall_data = (UCHAR *)HeapAlloc(GetProcessHeap(), 0, 16384); // enough room for over 2000 syscalls
|
||||||
|
if (!syscall_data)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(SbieApi_Call(API_QUERY_SYSCALLS, 2, (ULONG_PTR)syscall_data, 1))) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, syscall_data);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DWORD64 pos = FuncTable; pos < SizeRead - 0x20; )
|
||||||
|
{
|
||||||
|
ULONG syscall_index = Win32_WoW64_GetSysCallNumber(pos, dll_data);
|
||||||
|
if (syscall_index)
|
||||||
|
{
|
||||||
|
SyscallPtr = (ULONG *)(syscall_data + sizeof(ULONG)); // size of buffer
|
||||||
|
|
||||||
|
while (SyscallPtr[0] || SyscallPtr[1]) {
|
||||||
|
|
||||||
|
SyscallNum = SyscallPtr[0];
|
||||||
|
|
||||||
|
SyscallNum &= 0xFFFF; // clear the not needed param count
|
||||||
|
|
||||||
|
if (SyscallNum == syscall_index){
|
||||||
|
|
||||||
|
RegionBase = BaseAddress + pos;
|
||||||
|
// _WIN64
|
||||||
|
RegionSize = 14;
|
||||||
|
// ! _WIN64
|
||||||
|
|
||||||
|
if (!ReadProcessMemory64(hProcess, RegionBase, ZwXxxPtr, RegionSize, &SizeRead))
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
//
|
||||||
|
// overwrite the ZwXxx export to call our SystemServiceAsm,
|
||||||
|
// and then restore the original page protection
|
||||||
|
//
|
||||||
|
|
||||||
|
// _WIN64
|
||||||
|
ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
|
||||||
|
ZwXxxPtr[1] = 0xC7;
|
||||||
|
ZwXxxPtr[2] = 0xC2;
|
||||||
|
*(ULONG *)&ZwXxxPtr[3] = SyscallNum;
|
||||||
|
if (!data->flags.long_diff) {
|
||||||
|
|
||||||
|
if (data->flags.is_win10) {
|
||||||
|
ZwXxxPtr[7] = 0x48; // jmp SystemServiceAsm
|
||||||
|
ZwXxxPtr[8] = 0xE9; // jmp SystemServiceAsm
|
||||||
|
*(ULONG *)&ZwXxxPtr[9] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (RegionBase + 13));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ZwXxxPtr[7] = 0xe9; // jmp SystemServiceAsm
|
||||||
|
*(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (RegionBase + 12));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
ZwXxxPtr[7] = 0xB8; // mov eax, SystemServiceAsm
|
||||||
|
*(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)SystemServiceAsm;
|
||||||
|
*(USHORT *)&ZwXxxPtr[12] = 0xE0FF; // jmp rax
|
||||||
|
}
|
||||||
|
// ! _WIN64
|
||||||
|
|
||||||
|
|
||||||
|
if (!VirtualProtectEx64(hProcess, RegionBase, RegionSize, PAGE_EXECUTE_READWRITE, &OldProtect))
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
if (!WriteProcessMemory64(hProcess, RegionBase, ZwXxxPtr, RegionSize, &SizeRead))
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
if (!VirtualProtectEx64(hProcess, RegionBase, RegionSize, OldProtect, &OldProtect))
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
SyscallPtr += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 0x20;
|
||||||
|
}
|
||||||
|
else if (*((ULONG*)&dll_data[pos]) == 0xCCCCCCCC) { // int 3; int 3; int 3; int 3;
|
||||||
|
ok = TRUE;
|
||||||
|
break; // end of sys call function table
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
finish:
|
||||||
|
|
||||||
|
if(syscall_data)
|
||||||
|
HeapFree(GetProcessHeap(), 0, syscall_data);
|
||||||
|
|
||||||
|
if(dll_data)
|
||||||
|
HeapFree(GetProcessHeap(), 0, dll_data);
|
||||||
|
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -1659,17 +1659,22 @@ _FX LONG SbieApi_ProcessExemptionControl(
|
||||||
// SbieDll_GetSysFunction
|
// SbieDll_GetSysFunction
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
extern HANDLE SbieApi_DeviceHandle;
|
||||||
extern P_NtCreateFile __sys_NtCreateFile;
|
extern P_NtCreateFile __sys_NtCreateFile;
|
||||||
extern P_NtQueryDirectoryFile __sys_NtQueryDirectoryFile;
|
extern P_NtQueryDirectoryFile __sys_NtQueryDirectoryFile;
|
||||||
extern P_NtOpenKey __sys_NtOpenKey;
|
extern P_NtOpenKey __sys_NtOpenKey;
|
||||||
extern P_NtEnumerateValueKey __sys_NtEnumerateValueKey;
|
extern P_NtEnumerateValueKey __sys_NtEnumerateValueKey;
|
||||||
|
extern P_NtDeviceIoControlFile __sys_NtDeviceIoControlFile;
|
||||||
|
|
||||||
|
|
||||||
void* SbieDll_GetSysFunction(const WCHAR* name)
|
void* SbieDll_GetSysFunction(const WCHAR* name)
|
||||||
{
|
{
|
||||||
|
if (name == NULL) return SbieApi_DeviceHandle;
|
||||||
if (_wcsicmp(name, L"NtCreateFile") == 0) return __sys_NtCreateFile;
|
if (_wcsicmp(name, L"NtCreateFile") == 0) return __sys_NtCreateFile;
|
||||||
if (_wcsicmp(name, L"NtQueryDirectoryFile") == 0) return __sys_NtQueryDirectoryFile;
|
if (_wcsicmp(name, L"NtQueryDirectoryFile") == 0) return __sys_NtQueryDirectoryFile;
|
||||||
if (_wcsicmp(name, L"NtOpenKey") == 0) return __sys_NtOpenKey;
|
if (_wcsicmp(name, L"NtOpenKey") == 0) return __sys_NtOpenKey;
|
||||||
if (_wcsicmp(name, L"NtEnumerateValueKey") == 0) return __sys_NtEnumerateValueKey;
|
if (_wcsicmp(name, L"NtEnumerateValueKey") == 0) return __sys_NtEnumerateValueKey;
|
||||||
|
if (_wcsicmp(name, L"NtDeviceIoControlFile") == 0) return __sys_NtDeviceIoControlFile;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1092,10 +1092,10 @@ _FX NTSTATUS Syscall_Api_Query(PROCESS *proc, ULONG64 *parms)
|
||||||
while (entry) {
|
while (entry) {
|
||||||
|
|
||||||
ULONG syscall_index = (ULONG)entry->syscall_index;
|
ULONG syscall_index = (ULONG)entry->syscall_index;
|
||||||
//#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
ULONG param_count = (ULONG)entry->param_count;
|
ULONG param_count = (ULONG)entry->param_count;
|
||||||
syscall_index |= (param_count * 4) << 24;
|
syscall_index |= (param_count * 4) << 24;
|
||||||
//#endif ! _WIN64
|
#endif ! _WIN64
|
||||||
|
|
||||||
*ptr = syscall_index;
|
*ptr = syscall_index;
|
||||||
++ptr;
|
++ptr;
|
||||||
|
|
|
@ -475,6 +475,10 @@ _FX NTSTATUS Syscall_Api_Invoke32(PROCESS* proc, ULONG64* parms)
|
||||||
|
|
||||||
// todo: call KiConvertToGuiThread() or PsConvertToGuiThread()
|
// todo: call KiConvertToGuiThread() or PsConvertToGuiThread()
|
||||||
|
|
||||||
|
// note: once this is implemented the below check with MmIsAddressValid will be obsolete
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// if we have a handler for this service, invoke it
|
// if we have a handler for this service, invoke it
|
||||||
//
|
//
|
||||||
|
@ -523,6 +527,11 @@ _FX NTSTATUS Syscall_Api_Invoke32(PROCESS* proc, ULONG64* parms)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
//
|
||||||
|
// we must validate the address as an application without being switched to
|
||||||
|
// gui mode could still issue a syscall to a win32k and cause a BSOD otherwise
|
||||||
|
//
|
||||||
|
|
||||||
if (MmIsAddressValid(entry->ntos_func)) {
|
if (MmIsAddressValid(entry->ntos_func)) {
|
||||||
|
|
||||||
//DbgPrint(" SysCall32 %d -> %p\r\n", syscall_index, entry->ntos_func);
|
//DbgPrint(" SysCall32 %d -> %p\r\n", syscall_index, entry->ntos_func);
|
||||||
|
@ -627,10 +636,10 @@ _FX NTSTATUS Syscall_Api_Query32(PROCESS *proc, ULONG64 *parms)
|
||||||
while (entry) {
|
while (entry) {
|
||||||
|
|
||||||
ULONG syscall_index = (ULONG)entry->syscall_index | 0x1000;
|
ULONG syscall_index = (ULONG)entry->syscall_index | 0x1000;
|
||||||
//#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
ULONG param_count = (ULONG)entry->param_count;
|
ULONG param_count = (ULONG)entry->param_count;
|
||||||
syscall_index |= (param_count * 4) << 24;
|
syscall_index |= (param_count * 4) << 24;
|
||||||
//#endif ! _WIN64
|
#endif ! _WIN64
|
||||||
|
|
||||||
*ptr = syscall_index;
|
*ptr = syscall_index;
|
||||||
++ptr;
|
++ptr;
|
||||||
|
|
|
@ -234,11 +234,9 @@ ULONGLONG * findChromeTarget(unsigned char* addr)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
_FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
{
|
{
|
||||||
UCHAR *SystemServiceAsm, *ZwXxxPtr;
|
UCHAR *SystemServiceAsm;
|
||||||
ULONG *SyscallPtr;
|
|
||||||
ULONG SyscallNum;
|
|
||||||
void *RegionBase;
|
void *RegionBase;
|
||||||
SIZE_T RegionSize;
|
SIZE_T RegionSize;
|
||||||
ULONG OldProtect;
|
ULONG OldProtect;
|
||||||
|
@ -246,7 +244,6 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
const ULONG OFFSET_ULONG_PTR =
|
const ULONG OFFSET_ULONG_PTR =
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
2; // on 64-bit Windows, "mov rax, 0" instruction is two bytes
|
2; // on 64-bit Windows, "mov rax, 0" instruction is two bytes
|
||||||
ULONGLONG *chrome64Target = NULL;
|
|
||||||
#else
|
#else
|
||||||
1; // on 32-bit Windows, "mov edx, 0" instruction is one byte
|
1; // on 32-bit Windows, "mov edx, 0" instruction is one byte
|
||||||
#endif
|
#endif
|
||||||
|
@ -256,7 +253,6 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
// to include the data area pointer
|
// to include the data area pointer
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
SystemServiceAsm = (UCHAR *)SystemService;
|
SystemServiceAsm = (UCHAR *)SystemService;
|
||||||
RegionBase = (void *)(SystemServiceAsm + OFFSET_ULONG_PTR);
|
RegionBase = (void *)(SystemServiceAsm + OFFSET_ULONG_PTR);
|
||||||
RegionSize = sizeof(ULONG_PTR);
|
RegionSize = sizeof(ULONG_PTR);
|
||||||
|
@ -271,6 +267,23 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||||
OldProtect, &OldProtect);
|
OldProtect, &OldProtect);
|
||||||
|
|
||||||
|
data->pSystemService = (ULONG64)SystemServiceAsm;
|
||||||
|
}
|
||||||
|
|
||||||
|
_FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
|
{
|
||||||
|
UCHAR *SystemServiceAsm, *ZwXxxPtr;
|
||||||
|
ULONG *SyscallPtr;
|
||||||
|
ULONG SyscallNum;
|
||||||
|
void *RegionBase;
|
||||||
|
SIZE_T RegionSize;
|
||||||
|
ULONG OldProtect;
|
||||||
|
#ifdef _WIN64
|
||||||
|
ULONGLONG *chrome64Target = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SystemServiceAsm = (UCHAR *)SystemService;
|
||||||
|
|
||||||
//
|
//
|
||||||
// our syscall data area describes the ZwXxx functions in ntdll,
|
// our syscall data area describes the ZwXxx functions in ntdll,
|
||||||
// overwrite each export to jump to our assembly SystemService
|
// overwrite each export to jump to our assembly SystemService
|
||||||
|
@ -341,7 +354,7 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
RegionBase = ZwXxxPtr;
|
RegionBase = ZwXxxPtr;
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
RegionSize = 12;
|
RegionSize = 14;
|
||||||
if (!chrome64Target) {
|
if (!chrome64Target) {
|
||||||
chrome64Target = (ULONG_PTR*)ZwXxxPtr;
|
chrome64Target = (ULONG_PTR*)ZwXxxPtr;
|
||||||
}
|
}
|
||||||
|
@ -569,12 +582,13 @@ _FX ULONG_PTR EntrypointC(SBIELOW_DATA *data,void *ActivationContext, void *Syst
|
||||||
|
|
||||||
// WaitForDebugger(data);
|
// WaitForDebugger(data);
|
||||||
|
|
||||||
data->pSystemService = (ULONG64)SystemService;
|
PrepSyscalls(data, SystemService);
|
||||||
|
|
||||||
if(!data->flags.bHostInject && !data->flags.bNoSysHooks)
|
if(!data->flags.bHostInject && !data->flags.bNoSysHooks)
|
||||||
InitSyscalls(data, SystemService);
|
InitSyscalls(data, SystemService);
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
InitInject(data, ActivationContext, ActivationContext64);
|
InitInject(data, ActivationContext, ActivationContext64);
|
||||||
|
|
||||||
if (!data->flags.bNoConsole)
|
if (!data->flags.bNoConsole)
|
||||||
InitConsole(data);
|
InitConsole(data);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -88,11 +88,13 @@ typedef struct _SBIELOW_DATA {
|
||||||
__declspec(align(16))
|
__declspec(align(16))
|
||||||
UCHAR NtProtectVirtualMemory_code[32];
|
UCHAR NtProtectVirtualMemory_code[32];
|
||||||
ULONG64 RealNtDeviceIoControlFile;
|
ULONG64 RealNtDeviceIoControlFile;
|
||||||
|
|
||||||
|
ULONG64 pSystemService;
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
SBIELOW_J_TABLE * Sbie64bitJumpTable;
|
SBIELOW_J_TABLE * Sbie64bitJumpTable;
|
||||||
ULONG64 ntdll_wow64_base;
|
ULONG64 ntdll_wow64_base;
|
||||||
#endif
|
#endif
|
||||||
ULONG64 pSystemService;
|
|
||||||
} SBIELOW_DATA;
|
} SBIELOW_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#define VERSION_MJR 1
|
#define VERSION_MJR 1
|
||||||
#define VERSION_MIN 0
|
#define VERSION_MIN 0
|
||||||
#define VERSION_REV 3
|
#define VERSION_REV 4
|
||||||
#define VERSION_UPD 0
|
#define VERSION_UPD 0
|
||||||
|
|
||||||
#ifndef STR
|
#ifndef STR
|
||||||
|
|
Loading…
Reference in New Issue