Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebase user dll VAs from host to remote. #158

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion InjectorCLI/CliMain.cpp
Original file line number Diff line number Diff line change
@@ -58,7 +58,6 @@ int wmain(int argc, wchar_t* argv[])
g_log.SetLogCb(scl::Logger::Info, LogCallback);
g_log.SetLogCb(scl::Logger::Error, LogCallback);

ReadNtApiInformation(&g_hdd);
SetDebugPrivileges();
//ChangeBadWindowText();
g_settings.Load(g_scyllaHideIniPath.c_str());
@@ -102,6 +101,7 @@ int wmain(int argc, wchar_t* argv[])

if (targetPid && dllPath)
{
ReadNtApiInformation(&g_hdd, targetPid);
wprintf(L"\nPID\t: %d 0x%X\nDLL Path: %s\n\n", targetPid, targetPid, dllPath);
if (!startInjection(targetPid, dllPath))
result = 1; // failure
4 changes: 2 additions & 2 deletions PluginGeneric/Injector.cpp
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ BYTE* RemoteBreakinPatch;
BYTE OllyRemoteBreakInReplacement[8];
HANDLE hDebuggee;

void ReadNtApiInformation(HOOK_DLL_DATA *hdd)
void ReadNtApiInformation(HOOK_DLL_DATA *hdd, DWORD targetPid)
{
scl::User32Loader user32Loader;
if (!user32Loader.FindSyscalls({
@@ -37,7 +37,7 @@ void ReadNtApiInformation(HOOK_DLL_DATA *hdd)
"NtUserGetForegroundWindow",
"NtUserGetClassName",
"NtUserInternalGetWindowText",
"NtUserGetThreadState" }))
"NtUserGetThreadState" }, targetPid))
{
g_log.LogError(L"Failed to find user32.dll/win32u.dll syscalls!");
return;
2 changes: 1 addition & 1 deletion PluginGeneric/Injector.h
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ typedef struct _PROCESS_SUSPEND_INFO
PTHREAD_SUSPEND_INFO ThreadSuspendInfo; // THREAD_SUSPEND_INFO[NumThreads]
} PROCESS_SUSPEND_INFO, *PPROCESS_SUSPEND_INFO;

void ReadNtApiInformation(HOOK_DLL_DATA *hdd);
void ReadNtApiInformation(HOOK_DLL_DATA *hdd, DWORD ProcessId);

void InstallAntiAttachHook();
void startInjectionProcess(HANDLE hProcess, HOOK_DLL_DATA *hdd, BYTE * dllMemory, bool newProcess);
18 changes: 14 additions & 4 deletions Scylla/User32Loader.cpp
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
#include "Win32kSyscalls.h"
#include "Scylla/OsInfo.h"
#include "Scylla/Logger.h"
#include "InjectorCLI/DynamicMapping.h"

extern scl::Logger g_log;

@@ -21,7 +22,7 @@ scl::User32Loader::~User32Loader()
}

// Finds the requested user32/win32u syscalls by name for later retrieval with GetUserSyscallVa
bool scl::User32Loader::FindSyscalls(const std::vector<std::string>& syscallNames)
bool scl::User32Loader::FindSyscalls(const std::vector<std::string>& syscallNames, DWORD targetPid)
{
if (Win32kUserDll == nullptr) // Failed to load user32.dll or win32u.dll
return false;
@@ -30,10 +31,15 @@ bool scl::User32Loader::FindSyscalls(const std::vector<std::string>& syscallName

if (OsBuildNumber >= 14393)
{

HANDLE hProcess = OpenProcess(PROCESS_SUSPEND_RESUME | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION, 0, targetPid);
HMODULE remoteBase = GetModuleBaseRemote(hProcess, L"win32u.dll");
CloseHandle(hProcess);

// On >= 10.0.14393.0 we can simply get the VAs from win32u.dll
for (const auto& syscallName : syscallNames)
{
const ULONG_PTR syscallAddress = (ULONG_PTR)GetProcAddress((HMODULE)Win32kUserDll, syscallName.c_str());
const ULONG_PTR syscallAddress = (ULONG_PTR)GetProcAddress((HMODULE)Win32kUserDll, syscallName.c_str()) - (ULONG_PTR)Win32kUserDll + (ULONG_PTR)remoteBase;
if (syscallAddress == 0)
return false;
FunctionNamesAndVas[syscallName] = syscallAddress;
@@ -51,11 +57,15 @@ bool scl::User32Loader::FindSyscalls(const std::vector<std::string>& syscallName
functionNamesAndSyscallNums[syscallName] = (ULONG_PTR)syscallNum;
}

HANDLE hProcess = OpenProcess(PROCESS_SUSPEND_RESUME | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION, 0, targetPid);
HMODULE remoteBase = GetModuleBaseRemote(hProcess, L"user32.dll");
CloseHandle(hProcess);

// Find the VAs of the functions we want
for (const auto& function : functionNamesAndSyscallNums)
{
const std::string syscallName = function.first;
const ULONG_PTR syscallAddress = FindSyscallByIndex((ULONG)function.second);
const ULONG_PTR syscallAddress = FindSyscallByIndex((ULONG)function.second) - (ULONG_PTR)Win32kUserDll + (ULONG_PTR)remoteBase;
if (syscallAddress != 0)
{
FunctionNamesAndVas[syscallName] = syscallAddress;
@@ -69,7 +79,7 @@ bool scl::User32Loader::FindSyscalls(const std::vector<std::string>& syscallName
}

// Sanity check the NtUserBlockInput VA as this is an exported syscall
const ULONG_PTR BlockInputVa = (ULONG_PTR)GetProcAddress((HMODULE)Win32kUserDll, "BlockInput");
const ULONG_PTR BlockInputVa = (ULONG_PTR)GetProcAddress((HMODULE)Win32kUserDll, "BlockInput") - (ULONG_PTR)Win32kUserDll + (ULONG_PTR)remoteBase;
if (BlockInputVa == 0)
return false;
const bool check = GetUserSyscallVa("NtUserBlockInput") == BlockInputVa;
2 changes: 1 addition & 1 deletion Scylla/User32Loader.h
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ namespace scl
User32Loader();
~User32Loader();

bool FindSyscalls(const std::vector<std::string>& syscallNames);
bool FindSyscalls(const std::vector<std::string>& syscallNames, DWORD targetPid);

ULONG_PTR GetUserSyscallVa(const std::string& functionName) const { return FunctionNamesAndVas.at(functionName); }
LONG GetUserSyscallIndex(const std::string& functionName) const;
2 changes: 1 addition & 1 deletion ScyllaHideGenericPlugin/ScyllaHideGenericPlugin.cpp
Original file line number Diff line number Diff line change
@@ -111,7 +111,7 @@ DLL_EXPORT void ScyllaHideDebugLoop(const DEBUG_EVENT* DebugEvent)
{
if (!status.bHooked)
{
ReadNtApiInformation(&g_hdd);
ReadNtApiInformation(&g_hdd, status.ProcessId);

status.bHooked = true;
startInjection(status.ProcessId, &g_hdd, g_scyllaHideDllPath.c_str(), true);
2 changes: 1 addition & 1 deletion ScyllaHideOlly1Plugin/ScyllaHideOlly1Plugin.cpp
Original file line number Diff line number Diff line change
@@ -487,7 +487,7 @@ extern "C" void DLL_EXPORT _ODBG_Pluginmainloop(DEBUG_EVENT *debugevent)
{
if (!bHooked)
{
ReadNtApiInformation(&g_hdd);
ReadNtApiInformation(&g_hdd,ProcessId);

bHooked = true;
startInjection(ProcessId, &g_hdd, g_scyllaHideDllPath.c_str(), true);
2 changes: 1 addition & 1 deletion ScyllaHideOlly2Plugin/ScyllaHideOlly2Plugin.cpp
Original file line number Diff line number Diff line change
@@ -397,7 +397,7 @@ extc void ODBG2_Pluginmainloop(DEBUG_EVENT *debugevent)
{
if (!bHooked)
{
ReadNtApiInformation(&g_hdd);
ReadNtApiInformation(&g_hdd,ProcessId);

bHooked = true;
startInjection(ProcessId, &g_hdd, g_scyllaHideDllPath.c_str(), true);
2 changes: 1 addition & 1 deletion ScyllaHideTEPlugin/ScyllaHideTEPlugin.cpp
Original file line number Diff line number Diff line change
@@ -85,7 +85,7 @@ extern "C" DLL_EXPORT void TitanDebuggingCallBack(LPDEBUG_EVENT debugEvent, int
{
if (!bHooked)
{
ReadNtApiInformation(&g_hdd);
ReadNtApiInformation(&g_hdd, ProcessId);

bHooked = true;
startInjection(ProcessId, &g_hdd, g_scyllaHideDllPath.c_str(), true);
4 changes: 2 additions & 2 deletions ScyllaHideX64DBGPlugin/ScyllaHideX64DBGPlugin.cpp
Original file line number Diff line number Diff line change
@@ -167,7 +167,7 @@ static void cbDebugloop(CBTYPE cbType, void* callbackInfo)
//In newest x64dbg version the auto break on attach was removed so ScyllaHide would never inject.
if (!bHooked)
{
ReadNtApiInformation(&g_hdd);
ReadNtApiInformation(&g_hdd, ProcessId);

bHooked = true;
startInjection(ProcessId, &g_hdd, g_scyllaHideDllPath.c_str(), true);
@@ -192,7 +192,7 @@ static void cbDebugloop(CBTYPE cbType, void* callbackInfo)
{
if (!bHooked)
{
ReadNtApiInformation(&g_hdd);
ReadNtApiInformation(&g_hdd, ProcessId);

bHooked = true;
startInjection(ProcessId, &g_hdd, g_scyllaHideDllPath.c_str(), true);