aboutsummaryrefslogtreecommitdiff
path: root/runtime/registry_manager.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/registry_manager.h')
-rw-r--r--runtime/registry_manager.h299
1 files changed, 299 insertions, 0 deletions
diff --git a/runtime/registry_manager.h b/runtime/registry_manager.h
new file mode 100644
index 0000000..c2a02fe
--- /dev/null
+++ b/runtime/registry_manager.h
@@ -0,0 +1,299 @@
+#ifndef REGISTRY_MANAGER_H
+#define REGISTRY_MANAGER_H
+
+struct REGISTRY_DIRECTORY {
+ uint32_t Reserved1;
+ uint32_t Reserved2;
+};
+
+typedef struct _KEY_VALUE_BASIC_INFORMATION {
+ ULONG TitleIndex;
+ ULONG Type;
+ ULONG NameLength;
+ WCHAR Name[1]; // Variable size
+} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;
+
+typedef struct _KEY_VALUE_FULL_INFORMATION {
+ ULONG TitleIndex;
+ ULONG Type;
+ ULONG DataOffset;
+ ULONG DataLength;
+ ULONG NameLength;
+ WCHAR Name[1]; // Variable size
+// Data[1]; // Variable size data not declared
+} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
+
+typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
+ ULONG TitleIndex;
+ ULONG Type;
+ ULONG DataLength;
+ UCHAR Data[1]; // Variable size
+} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
+
+typedef struct _KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 {
+ ULONG Type;
+ ULONG DataLength;
+ UCHAR Data[1]; // Variable size
+} KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, *PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64;
+
+typedef enum _KEY_VALUE_INFORMATION_CLASS {
+ KeyValueBasicInformation,
+ KeyValueFullInformation,
+ KeyValuePartialInformation,
+ KeyValueFullInformationAlign64,
+ KeyValuePartialInformationAlign64,
+ MaxKeyValueInfoClass // MaxKeyValueInfoClass should always be the last enum
+} KEY_VALUE_INFORMATION_CLASS;
+
+typedef struct _KEY_BASIC_INFORMATION {
+ LARGE_INTEGER LastWriteTime;
+ ULONG TitleIndex;
+ ULONG NameLength;
+ WCHAR Name[1]; // Variable length string
+} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
+
+typedef struct _KEY_NODE_INFORMATION {
+ LARGE_INTEGER LastWriteTime;
+ ULONG TitleIndex;
+ ULONG ClassOffset;
+ ULONG ClassLength;
+ ULONG NameLength;
+ WCHAR Name[1]; // Variable length string
+// Class[1]; // Variable length string not declared
+} KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION;
+
+typedef struct _KEY_FULL_INFORMATION {
+ LARGE_INTEGER LastWriteTime;
+ ULONG TitleIndex;
+ ULONG ClassOffset;
+ ULONG ClassLength;
+ ULONG SubKeys;
+ ULONG MaxNameLen;
+ ULONG MaxClassLen;
+ ULONG Values;
+ ULONG MaxValueNameLen;
+ ULONG MaxValueDataLen;
+ WCHAR Class[1]; // Variable length
+} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION;
+
+typedef struct _KEY_NAME_INFORMATION {
+ ULONG NameLength;
+ WCHAR Name[1]; // Variable length
+} KEY_NAME_INFORMATION, *PKEY_NAME_INFORMATION;
+
+typedef struct _KEY_CACHED_INFORMATION {
+ LARGE_INTEGER LastWriteTime;
+ ULONG TitleIndex;
+ ULONG SubKeys;
+ ULONG MaxNameLen;
+ ULONG Values;
+ ULONG MaxValueNameLen;
+ ULONG MaxValueDataLen;
+ ULONG NameLength;
+} KEY_CACHED_INFORMATION, *PKEY_CACHED_INFORMATION;
+
+typedef struct _KEY_HANDLE_TAGS_INFORMATION {
+ ULONG HandleTags;
+} KEY_HANDLE_TAGS_INFORMATION, *PKEY_HANDLE_TAGS_INFORMATION;
+
+typedef enum _KEY_INFORMATION_CLASS {
+ KeyBasicInformation,
+ KeyNodeInformation,
+ KeyFullInformation,
+ KeyNameInformation,
+ KeyCachedInformation,
+ KeyFlagsInformation,
+ KeyVirtualizationInformation,
+ KeyHandleTagsInformation,
+ MaxKeyInfoClass // MaxKeyInfoClass should always be the last enum
+} KEY_INFORMATION_CLASS;
+
+class RegistryValue
+{
+public:
+ RegistryValue(const wchar_t *name);
+ ~RegistryValue();
+ const wchar_t *name() const { return name_; }
+ uint32_t type() const { return type_; }
+ uint32_t size() const { return size_; }
+ void *data() const { return data_; }
+ void SetValue(uint32_t type, void *data, uint32_t size);
+private:
+ wchar_t *name_;
+ uint32_t type_;
+ uint8_t *data_;
+ uint32_t size_;
+
+ // no copy ctr or assignment op
+ RegistryValue(const RegistryValue &);
+ RegistryValue &operator =(const RegistryValue &);
+};
+
+class UnicodeString
+{
+public:
+ UnicodeString()
+ : data_(NULL), size_(0)
+ {
+ data_ = new wchar_t[size_ + 1];
+ data_[size_] = 0;
+ }
+ UnicodeString(const wchar_t *str)
+ : data_(NULL), size_(wcslen(str))
+ {
+ data_ = new wchar_t[size_ + 1];
+ memcpy(data_, str, size_ * sizeof(wchar_t));
+ data_[size_] = 0;
+ }
+ UnicodeString(const wchar_t *str, size_t size)
+ : data_(NULL), size_(size)
+ {
+ data_ = new wchar_t[size_ + 1];
+ memcpy(data_, str, size_ * sizeof(wchar_t));
+ data_[size_] = 0;
+ }
+ UnicodeString(const UnicodeString &str)
+ : data_(NULL), size_(str.size_)
+ {
+ data_ = new wchar_t[size_ + 1];
+ memcpy(data_, str.data_, size_ * sizeof(wchar_t));
+ data_[size_] = 0;
+ }
+ UnicodeString &operator=(const UnicodeString &src)
+ {
+ if (&src != this)
+ {
+ delete [] data_;
+ size_ = src.size();
+ data_ = new wchar_t[size_ + 1];
+ memcpy(data_, src.c_str(), size_ * sizeof(wchar_t));
+ data_[size_] = 0;
+ }
+ return *this;
+ }
+ ~UnicodeString()
+ {
+ delete [] data_;
+ }
+ size_t size() const { return size_; }
+ const wchar_t *c_str() const { return data_; }
+ UnicodeString &append(const wchar_t *str) { return append (str, wcslen(str)); }
+ UnicodeString &append(const wchar_t *str, size_t str_size)
+ {
+ size_t new_size = size_ + str_size;
+ wchar_t *new_data = new wchar_t[new_size + 1];
+ memcpy(new_data, data_, size_ * sizeof(wchar_t));
+ memcpy(new_data + size_, str, str_size * sizeof(wchar_t));
+ new_data[new_size] = 0;
+ delete [] data_;
+ data_ = new_data;
+ size_ = new_size;
+ return *this;
+ }
+ UnicodeString &operator + (wchar_t c) { return append(&c, 1); }
+ UnicodeString &operator + (const wchar_t *str) { return append(str, wcslen(str)); }
+ bool operator == (const wchar_t *str) const { return wcscmp(c_str(), str) == 0; }
+private:
+ wchar_t *data_;
+ size_t size_;
+};
+
+class RegistryKey
+{
+public:
+ RegistryKey();
+ RegistryKey(RegistryKey *owner, const wchar_t *name, bool is_real);
+ ~RegistryKey();
+ RegistryKey *GetKey(const wchar_t *name) const;
+ RegistryKey *AddKey(const wchar_t *name, bool is_real, bool *is_exists);
+ bool DeleteKey(RegistryKey *key);
+ const wchar_t *name() const { return name_; }
+ UnicodeString full_name() const;
+ void SetValue(wchar_t *name, uint32_t type, void *data, uint32_t size);
+ bool DeleteValue(wchar_t *name);
+ RegistryValue *GetValue(const wchar_t *name) const;
+ bool is_real() const { return is_real_; }
+ void set_is_wow(bool value) { is_wow_ = value; }
+ RegistryKey *owner() const { return owner_; }
+ RegistryKey *key(size_t index) const { return keys_[index]; }
+ size_t keys_size() const { return keys_.size(); }
+ RegistryValue *value(size_t index) const { return values_[index]; }
+ size_t values_size() const { return values_.size(); }
+ uint64_t last_write_time() const { return last_write_time_; }
+private:
+ RegistryKey *GetChild(const wchar_t *name) const;
+ RegistryKey *AddChild(const wchar_t *name, bool is_real, bool *is_exists);
+ RegistryValue *AddValue(wchar_t *value_name);
+ bool is_wow_node(const wchar_t *name) const;
+ wchar_t *name_;
+ RegistryKey *owner_;
+ bool is_real_;
+ bool is_wow_;
+ vector<RegistryKey *> keys_;
+ vector<RegistryValue *> values_;
+ uint64_t last_write_time_;
+
+ // no copy ctr or assignment op
+ RegistryKey(const RegistryKey &);
+ RegistryKey &operator =(const RegistryKey &);
+};
+
+class VirtualObjectList;
+class RegistryManager
+{
+public:
+ RegistryManager(const uint8_t *data, HMODULE instance, const uint8_t *key, VirtualObjectList *objects);
+ void HookAPIs(HookManager &hook_manager);
+ void UnhookAPIs(HookManager &hook_manager);
+ void BeginRegisterServer();
+ void EndRegisterServer();
+ NTSTATUS NtSetValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName, ULONG TitleIndex, ULONG Type, PVOID Data, ULONG DataSize);
+ NTSTATUS NtDeleteValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName);
+ NTSTATUS NtCreateKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG TitleIndex, PUNICODE_STRING Class, ULONG CreateOptions, PULONG Disposition);
+ NTSTATUS NtQueryValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength);
+ NTSTATUS NtOpenKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
+ NTSTATUS NtOpenKeyEx(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG OpenOptions);
+ NTSTATUS NtDeleteKey(HANDLE KeyHandle);
+ NTSTATUS NtQueryKey(HANDLE KeyHandle, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength);
+ NTSTATUS NtEnumerateValueKey(HANDLE KeyHandle, ULONG Index, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength);
+ NTSTATUS NtEnumerateKey(HANDLE KeyHandle, ULONG Index, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength);
+private:
+ NTSTATUS TrueNtSetValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName, ULONG TitleIndex, ULONG Type, PVOID Data, ULONG DataSize);
+ NTSTATUS TrueNtDeleteValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName);
+ NTSTATUS TrueNtCreateKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG TitleIndex, PUNICODE_STRING Class, ULONG CreateOptions, PULONG Disposition);
+ NTSTATUS TrueNtQueryValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength);
+ NTSTATUS TrueNtOpenKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
+ NTSTATUS TrueNtOpenKeyEx(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG OpenOptions);
+ NTSTATUS TrueNtDeleteKey(HANDLE KeyHandle);
+ NTSTATUS TrueNtQueryKey(HANDLE KeyHandle, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength);
+ NTSTATUS TrueNtEnumerateValueKey(HANDLE KeyHandle, ULONG Index, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength);
+ NTSTATUS TrueNtEnumerateKey(HANDLE KeyHandle, ULONG Index, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength);
+ NTSTATUS TrueNtQueryObject(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
+ REGISTRY_DIRECTORY DecryptDirectory(const REGISTRY_DIRECTORY *directory_enc) const;
+ RegistryKey *GetRootKey(HANDLE root, uint32_t *access, bool can_create);
+ NTSTATUS QueryValueKey(RegistryValue *value, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength);
+ NTSTATUS QueryKey(RegistryKey *key, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength);
+
+ HMODULE instance_;
+ const uint8_t *data_;
+ uint32_t key_;
+ void *nt_set_value_key_;
+ void *nt_delete_value_key_;
+ void *nt_create_key_;
+ void *nt_open_key_;
+ void *nt_open_key_ex_;
+ void *nt_query_value_key_;
+ void *nt_delete_key_;
+ void *nt_query_key_;
+ void *nt_enumerate_value_key_;
+ void *nt_enumerate_key_;
+ RegistryKey cache_;
+ VirtualObjectList *objects_;
+ bool append_mode_;
+
+ // no copy ctr or assignment op
+ RegistryManager(const RegistryManager &);
+ RegistryManager &operator =(const RegistryManager &);
+};
+
+#endif \ No newline at end of file