Skip to content

Commit

Permalink
Prepare handle cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
momo5502 committed Sep 7, 2024
1 parent d7dd64f commit 9f43765
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 53 deletions.
7 changes: 3 additions & 4 deletions src/windows_emulator/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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);

Expand Down
74 changes: 39 additions & 35 deletions src/windows_emulator/syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,47 +224,48 @@ 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);
}
return STATUS_INVALID_HANDLE;
}

entry->second.signaled = true;
return STATUS_SUCCESS;
}
const auto entry = c.proc.events.find(value.id);
if (entry == c.proc.events.end())
{
return STATUS_INVALID_HANDLE;
}

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);
return STATUS_SUCCESS;
}
}

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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -384,7 +387,7 @@ namespace

if (filename == L"\\Windows\\SharedSection")
{
section_handle.write(SHARED_SECTION);
section_handle.write(SHARED_SECTION.bits);
return STATUS_SUCCESS;
}

Expand All @@ -395,7 +398,6 @@ namespace
return STATUS_NOT_SUPPORTED;
}


if (filename.starts_with(L"api-ms-"))
{
filename = L"C:\\WINDOWS\\System32\\downlevel\\" + filename;
Expand All @@ -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));

Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
}

Expand Down
88 changes: 74 additions & 14 deletions src/windows_emulator/syscalls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

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;

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;
struct handle_types
{
enum type : uint16_t
{
file,
event,
section,
symlink,
directory,
};
};

#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)

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);
Expand Down

0 comments on commit 9f43765

Please sign in to comment.