mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 11:13:57 +00:00
Almost working registry support
This commit is contained in:
2
deps/windows-hive-parser
vendored
2
deps/windows-hive-parser
vendored
Submodule deps/windows-hive-parser updated: fdeabc39b1...df62310ec3
@@ -109,6 +109,33 @@ std::optional<registry_key> registry_manager::get_key(const std::filesystem::pat
|
||||
return {std::move(reg_key)};
|
||||
}
|
||||
|
||||
std::optional<registry_value> registry_manager::get_value(const registry_key& key, const std::string_view name)
|
||||
{
|
||||
const auto iterator = this->hives_.find(key.hive);
|
||||
if (iterator == this->hives_.end())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto entry = iterator->second->get_subkey(key.path.begin()->string(), key.path.generic_string());
|
||||
if (!entry)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto value = entry->get_key_value(name);
|
||||
if (!value)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
registry_value v{};
|
||||
v.type = value->first;
|
||||
v.data = value->second;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
registry_manager::hive_map::iterator registry_manager::find_hive(const std::filesystem::path& key)
|
||||
{
|
||||
for (auto i = this->hives_.begin(); i != this->hives_.end(); ++i)
|
||||
|
||||
@@ -23,6 +23,12 @@ struct registry_key
|
||||
}
|
||||
};
|
||||
|
||||
struct registry_value
|
||||
{
|
||||
uint32_t type;
|
||||
std::string_view data;
|
||||
};
|
||||
|
||||
class registry_manager
|
||||
{
|
||||
public:
|
||||
@@ -36,6 +42,7 @@ public:
|
||||
void deserialize(utils::buffer_deserializer& buffer);
|
||||
|
||||
std::optional<registry_key> get_key(const std::filesystem::path& key);
|
||||
std::optional<registry_value> get_value(const registry_key& key, const std::string_view name);
|
||||
|
||||
private:
|
||||
hive_map hives_{};
|
||||
|
||||
@@ -74,9 +74,62 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtOpenKeyEx()
|
||||
NTSTATUS handle_NtOpenKeyEx(const syscall_context& c, const emulator_object<uint64_t> key_handle,
|
||||
const ACCESS_MASK desired_access,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes,
|
||||
ULONG /*open_options*/)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
return handle_NtOpenKey(c, key_handle, desired_access, object_attributes);
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtQueryValueKey(const syscall_context& c, handle key_handle,
|
||||
const emulator_object<UNICODE_STRING> value_name,
|
||||
KEY_VALUE_INFORMATION_CLASS key_value_information_class,
|
||||
uint64_t key_value_information,
|
||||
ULONG length, const emulator_object<ULONG> result_length)
|
||||
{
|
||||
if (key_value_information_class != KeyValuePartialInformation)
|
||||
{
|
||||
c.win_emu.logger.print(color::gray, "Unsupported registry class: %X\n", key_value_information_class);
|
||||
c.emu.stop();
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const auto* key = c.proc.registry_keys.get(key_handle);
|
||||
if (!key)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
const auto wide_name = read_unicode_string(c.emu, value_name);
|
||||
const std::string name(wide_name.begin(), wide_name.end());
|
||||
|
||||
const auto value = c.proc.registry.get_value(*key, name);
|
||||
if (!value)
|
||||
{
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
const auto required_size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + value->data.size() - 1;
|
||||
result_length.write(static_cast<ULONG>(required_size));
|
||||
|
||||
if (required_size > length)
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
KEY_VALUE_PARTIAL_INFORMATION partial_info{};
|
||||
partial_info.TitleIndex = 0;
|
||||
partial_info.Type = value->type;
|
||||
partial_info.DataLength = static_cast<ULONG>(value->data.size());
|
||||
|
||||
const emulator_object<KEY_VALUE_PARTIAL_INFORMATION> partial_info_obj{c.emu, key_value_information};
|
||||
partial_info_obj.write(partial_info);
|
||||
|
||||
c.emu.write_memory(key_value_information + offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data), value->data.data(),
|
||||
value->data.size());
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtSetInformationThread(const syscall_context& c, const uint64_t thread_handle,
|
||||
@@ -165,6 +218,11 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (value.type == handle_types::registry && c.proc.registry_keys.erase(handle))
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@@ -2276,6 +2334,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
|
||||
add_handler(NtReadFile);
|
||||
add_handler(NtSetInformationFile);
|
||||
add_handler(NtUserRegisterWindowMessage);
|
||||
add_handler(NtQueryValueKey);
|
||||
|
||||
#undef add_handler
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user