Prepare handle cleanup

This commit is contained in:
momo5502
2024-09-07 21:41:00 +02:00
parent d7dd64f896
commit 9f437657ad
3 changed files with 115 additions and 52 deletions

View File

@@ -344,9 +344,9 @@ namespace
proc_params.Length = sizeof(proc_params);
proc_params.Flags = 0x6001 | 0x80000000; // Prevent CsrClientConnectToServer
proc_params.ConsoleHandle = reinterpret_cast<HANDLE>(CONSOLE_HANDLE);
proc_params.StandardOutput = reinterpret_cast<HANDLE>(STDOUT_HANDLE);
proc_params.StandardInput = reinterpret_cast<HANDLE>(STDIN_HANDLE);
proc_params.ConsoleHandle = CONSOLE_HANDLE.h;
proc_params.StandardOutput = STDOUT_HANDLE.h;
proc_params.StandardInput = STDIN_HANDLE.h;
proc_params.StandardError = proc_params.StandardOutput;
gs.make_unicode_string(proc_params.CurrentDirectory.DosPath, L"C:\\Users\\mauri\\Desktop");
@@ -714,7 +714,6 @@ namespace
const auto allocation_size = combined_size + mach_frame_size;
const auto initial_sp = emu.reg(x64_register::rsp);
const auto new_sp = align_down(initial_sp - allocation_size, 0x100);

View File

@@ -224,36 +224,38 @@ namespace
NTSTATUS handle_NtSetEvent(const syscall_context& c, const uint64_t handle,
const emulator_object<LONG> previous_state)
{
if (handle & EVENT_BIT)
const auto value = get_handle_value(handle);
if (value.type != handle_types::event)
{
const auto event_index = static_cast<uint32_t>(handle & ~EVENT_BIT);
const auto entry = c.proc.events.find(event_index);
if (entry != c.proc.events.end())
{
if (previous_state.value())
{
previous_state.write(entry->second.signaled ? 1ULL : 0ULL);
}
entry->second.signaled = true;
return STATUS_SUCCESS;
}
return STATUS_INVALID_HANDLE;
}
return STATUS_INVALID_HANDLE;
const auto entry = c.proc.events.find(value.id);
if (entry == c.proc.events.end())
{
return STATUS_INVALID_HANDLE;
}
if (previous_state.value())
{
previous_state.write(entry->second.signaled ? 1ULL : 0ULL);
}
entry->second.signaled = true;
return STATUS_SUCCESS;
}
NTSTATUS handle_NtClose(const syscall_context& c, const uint64_t handle)
{
if (handle & PSEUDO_BIT)
const auto value = get_handle_value(handle);
if (value.is_pseudo)
{
return STATUS_SUCCESS;
}
if (handle & EVENT_BIT)
if (value.type == handle_types::event)
{
const auto event_index = static_cast<uint32_t>(handle & ~EVENT_BIT);
const auto entry = c.proc.events.find(event_index);
const auto entry = c.proc.events.find(value.id);
if (entry != c.proc.events.end())
{
c.proc.events.erase(entry);
@@ -261,10 +263,9 @@ namespace
}
}
if (handle & FILE_BIT)
if (value.type == handle_types::file)
{
const auto event_index = static_cast<uint32_t>(handle & ~FILE_BIT);
const auto entry = c.proc.files.find(event_index);
const auto entry = c.proc.files.find(value.id);
if (entry != c.proc.files.end())
{
c.proc.files.erase(entry);
@@ -305,7 +306,8 @@ namespace
}
}
event_handle.write(index | EVENT_BIT);
const auto h = make_handle(index, handle_types::event, false);
event_handle.write(h.bits);
c.proc.events.try_emplace(index, initial_state != FALSE, event_type);
@@ -354,7 +356,8 @@ namespace
}
}
file_handle.write(index | FILE_BIT);
const auto h = make_handle(index, handle_types::file, false);
file_handle.write(h.bits);
auto status = STATUS_SUCCESS;
object_attributes.access([&](const OBJECT_ATTRIBUTES& attributes)
@@ -384,7 +387,7 @@ namespace
if (filename == L"\\Windows\\SharedSection")
{
section_handle.write(SHARED_SECTION);
section_handle.write(SHARED_SECTION.bits);
return STATUS_SUCCESS;
}
@@ -395,7 +398,6 @@ namespace
return STATUS_NOT_SUPPORTED;
}
if (filename.starts_with(L"api-ms-"))
{
filename = L"C:\\WINDOWS\\System32\\downlevel\\" + filename;
@@ -419,7 +421,8 @@ namespace
}
}
section_handle.write(index | FILE_BIT);
const auto h = make_handle(index, handle_types::file, false);
section_handle.write(h.bits);
c.proc.files.try_emplace(index, std::move(filename));
@@ -438,13 +441,13 @@ namespace
return STATUS_INVALID_HANDLE;
}
if (!(section_handle & FILE_BIT))
const auto value = get_handle_value(section_handle);
if (value.type != handle_types::file)
{
return STATUS_INVALID_HANDLE;
}
const auto section_index = static_cast<uint32_t>(section_handle & ~FILE_BIT);
const auto section_entry = c.proc.files.find(section_index);
const auto section_entry = c.proc.files.find(value.id);
if (section_entry == c.proc.files.end())
{
return STATUS_INVALID_HANDLE;
@@ -870,7 +873,7 @@ namespace
if (object_name == L"\\KnownDlls")
{
directory_handle.write(KNOWN_DLLS_DIRECTORY);
directory_handle.write(KNOWN_DLLS_DIRECTORY.bits);
return STATUS_SUCCESS;
}
@@ -886,7 +889,7 @@ namespace
if (object_name == L"KnownDllPath")
{
link_handle.write(KNOWN_DLLS_SYMLINK);
link_handle.write(KNOWN_DLLS_SYMLINK.bits);
return STATUS_SUCCESS;
}
@@ -1023,7 +1026,7 @@ namespace
puts("NtCreateSection not supported");
c.emu.stop();
section_handle.write(SHARED_SECTION);
section_handle.write(SHARED_SECTION.bits);
/*
maximum_size.access([](LARGE_INTEGER& large_int)
{
@@ -1139,14 +1142,15 @@ namespace
if (filename == L"\\Device\\ConDrv\\Server")
{
file_handle.write(CONSOLE_SERVER);
file_handle.write(CONSOLE_SERVER.bits);
return STATUS_SUCCESS;
}
const auto root_handle = reinterpret_cast<uint64_t>(attributes.RootDirectory);
if ((root_handle & PSEUDO_BIT) && (filename == L"\\Reference" || filename == L"\\Connect"))
handle root_handle{};
root_handle.bits = reinterpret_cast<uint64_t>(attributes.RootDirectory);
if (root_handle.value.is_pseudo && (filename == L"\\Reference" || filename == L"\\Connect"))
{
file_handle.write(root_handle);
file_handle.write(root_handle.bits);
return STATUS_SUCCESS;
}

View File

@@ -3,20 +3,80 @@
#include <x64_emulator.hpp>
#include "process_context.hpp"
constexpr uint64_t PSEUDO_BIT = 1ULL << 63ULL;
constexpr uint64_t EVENT_BIT = 1ULL << 62ULL;
constexpr uint64_t DIRECTORY_BIT = 1ULL << 61ULL;
constexpr uint64_t SYMLINK_BIT = 1ULL << 60ULL;
constexpr uint64_t FILE_BIT = 1ULL << 59ULL;
struct handle_types
{
enum type : uint16_t
{
file,
event,
section,
symlink,
directory,
};
};
constexpr uint64_t KNOWN_DLLS_DIRECTORY = DIRECTORY_BIT | PSEUDO_BIT | 0x1337;
constexpr uint64_t KNOWN_DLLS_SYMLINK = SYMLINK_BIT | PSEUDO_BIT | 0x1337;
constexpr uint64_t SHARED_SECTION = FILE_BIT | PSEUDO_BIT | 0x1337;
constexpr uint64_t CONSOLE_SERVER = FILE_BIT | PSEUDO_BIT | 0x1338;
#pragma pack(push)
#pragma pack(1)
struct handle_value
{
uint64_t id : 32;
uint64_t type : 16;
uint64_t padding : 15;
uint64_t is_pseudo : 1;
};
#pragma pack(pop)
constexpr uint64_t CONSOLE_HANDLE = FILE_BIT | PSEUDO_BIT | 0x01;
constexpr uint64_t STDOUT_HANDLE = FILE_BIT | PSEUDO_BIT | 0x02;
constexpr uint64_t STDIN_HANDLE = FILE_BIT | PSEUDO_BIT | 0x03;
static_assert(sizeof(handle_value) == 8);
union handle
{
handle_value value;
uint64_t bits;
HANDLE h;
};
inline bool operator==(const handle& h1, const handle& h2)
{
return h1.bits == h2.bits;
}
inline bool operator==(const handle& h1, const uint64_t& h2)
{
return h1.bits == h2;
}
inline handle_value get_handle_value(const uint64_t h)
{
handle hh{};
hh.bits = h;
return hh.value;
}
constexpr handle make_handle(const uint32_t id, const handle_types::type type, const bool is_pseudo)
{
handle_value value{};
value.padding = 0;
value.id = id;
value.type = type;
value.is_pseudo = is_pseudo;
return {value};
}
constexpr handle make_pseudo_handle(const uint32_t id, const handle_types::type type)
{
return make_handle(id, type, true);
}
constexpr auto KNOWN_DLLS_DIRECTORY = make_pseudo_handle(0x1337, handle_types::directory);
constexpr auto KNOWN_DLLS_SYMLINK = make_pseudo_handle(0x1337, handle_types::symlink);
constexpr auto SHARED_SECTION = make_pseudo_handle(0x1337, handle_types::section);
constexpr auto CONSOLE_SERVER = make_pseudo_handle(0x1337, handle_types::section);
constexpr auto CONSOLE_HANDLE = make_pseudo_handle(0x1, handle_types::file);
constexpr auto STDOUT_HANDLE = make_pseudo_handle(0x2, handle_types::file);
constexpr auto STDIN_HANDLE = make_pseudo_handle(0x3, handle_types::file);
struct syscall_context;
using syscall_handler = void(*)(const syscall_context& c);