diff options
author | jmpoep <OriginalEntryPoint@qq.com> | 2023-12-07 16:51:07 +0800 |
---|---|---|
committer | jmpoep <OriginalEntryPoint@qq.com> | 2023-12-07 16:51:07 +0800 |
commit | 28008a746a31abb7909dd86cb0cd413ac8943b0b (patch) | |
tree | a30b74b8cad548048c3c1551d652828ab76fa9bd /runtime/registry_manager.h | |
download | vmprotect-3.5.1-master.tar vmprotect-3.5.1-master.tar.gz vmprotect-3.5.1-master.tar.bz2 vmprotect-3.5.1-master.zip |
Diffstat (limited to 'runtime/registry_manager.h')
-rw-r--r-- | runtime/registry_manager.h | 299 |
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 |