#ifndef FILE_MANAGER_H #define FILE_MANAGER_H #include "loader.h" #include "registry_manager.h" class CipherRC5; typedef struct _FILE_BASIC_INFORMATION { LARGE_INTEGER CreationTime; LARGE_INTEGER LastAccessTime; LARGE_INTEGER LastWriteTime; LARGE_INTEGER ChangeTime; ULONG FileAttributes; } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; typedef enum _SECTION_INFORMATION_CLASS { SectionBasicInformation, SectionImageInformation, SectionRelocationInformation } SECTION_INFORMATION_CLASS, *PSECTION_INFORMATION_CLASS; typedef struct _SECTION_BASIC_INFORMATION { ULONG BaseAddress; ULONG Attributes; LARGE_INTEGER Size; } SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION; typedef struct _SECTION_IMAGE_INFORMATION { PVOID EntryPoint; ULONG StackZeroBits; ULONG StackReserved; ULONG StackCommit; ULONG ImageSubsystem; WORD SubSystemVersionLow; WORD SubSystemVersionHigh; ULONG Unknown1; ULONG ImageCharacteristics; ULONG ImageMachineType; ULONG Unknown2[3]; } SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION; #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) #define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xC000007BL) #define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS)0xC0000045L) #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) #define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L) #define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L) #define STATUS_NO_MORE_ENTRIES ((NTSTATUS)0x8000001AL) #ifndef STATUS_INVALID_PARAMETER #define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL) #endif #define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS)0xC0000010L) #define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS)0xC0000020L) #define OBJ_HANDLE_TAGBITS 0x00000003L #define EXHANDLE(x) ((HANDLE)((ULONG_PTR)(x) &~ OBJ_HANDLE_TAGBITS)) #define FILE_SUPERSEDE 0x00000000 #define FILE_OPEN 0x00000001 #define FILE_CREATE 0x00000002 #define FILE_OPEN_IF 0x00000003 #define FILE_OVERWRITE 0x00000004 #define FILE_OVERWRITE_IF 0x00000005 #define FILE_MAXIMUM_DISPOSITION 0x00000005 #define FILE_SUPERSEDED 0x00000000 #define FILE_OPENED 0x00000001 #define FILE_CREATED 0x00000002 #define FILE_OVERWRITTEN 0x00000003 #define FILE_EXISTS 0x00000004 #define FILE_DOES_NOT_EXIST 0x00000005 #define FILE_USE_FILE_POINTER_POSITION 0xfffffffe #define IMAGE_FILE_MACHINE_I486 0x14D #define IMAGE_FILE_MACHINE_I586 0x14E #define FileBothDirectoryInformation (FILE_INFORMATION_CLASS)0x03 #define FileBasicInformation (FILE_INFORMATION_CLASS)0x04 #define FileStandardInformation (FILE_INFORMATION_CLASS)0x05 #define FileNameInformation (FILE_INFORMATION_CLASS)0x09 #define FilePositionInformation (FILE_INFORMATION_CLASS)0x0e #define FileIdBothDirectoryInformation (FILE_INFORMATION_CLASS)0x25 #define FileAllInformation (FILE_INFORMATION_CLASS)0x12 typedef struct _FILE_POSITION_INFORMATION { LARGE_INTEGER CurrentByteOffset; } FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; typedef struct _FILE_STANDARD_INFORMATION { LARGE_INTEGER AllocationSize; LARGE_INTEGER EndOfFile; ULONG NumberOfLinks; BOOLEAN DeletePending; BOOLEAN Directory; } FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; typedef struct _FILE_NAME_INFORMATION { ULONG FileNameLength; WCHAR FileName[1]; } FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; typedef struct _FILE_INTERNAL_INFORMATION { LARGE_INTEGER IndexNumber; } FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION; typedef struct _FILE_EA_INFORMATION { ULONG EaSize; } FILE_EA_INFORMATION, *PFILE_EA_INFORMATION; typedef struct _FILE_ACCESS_INFORMATION { ACCESS_MASK AccessFlags; } FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION; typedef struct _FILE_MODE_INFORMATION { ULONG Mode; } FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; typedef struct _FILE_ALIGNMENT_INFORMATION { ULONG AlignmentRequirement; } FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; typedef struct _FILE_ALL_INFORMATION { FILE_BASIC_INFORMATION BasicInformation; FILE_STANDARD_INFORMATION StandardInformation; FILE_INTERNAL_INFORMATION InternalInformation; FILE_EA_INFORMATION EaInformation; FILE_ACCESS_INFORMATION AccessInformation; FILE_POSITION_INFORMATION PositionInformation; FILE_MODE_INFORMATION ModeInformation; FILE_ALIGNMENT_INFORMATION AlignmentInformation; FILE_NAME_INFORMATION NameInformation; } FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; typedef struct _OBJECT_NAME_INFORMATION { UNICODE_STRING Name; } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; typedef enum _FSINFOCLASS { FileFsVolumeInformation = 1, FileFsLabelInformation, // 2 FileFsSizeInformation, // 3 FileFsDeviceInformation, // 4 FileFsAttributeInformation, // 5 FileFsControlInformation, // 6 FileFsFullSizeInformation, // 7 FileFsObjectIdInformation, // 8 FileFsDriverPathInformation, // 9 FileFsVolumeFlagsInformation,// 10 FileFsMaximumInformation } FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; typedef struct _FILE_FS_DEVICE_INFORMATION { DEVICE_TYPE DeviceType; ULONG Characteristics; } FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; typedef struct _FILE_FS_ATTRIBUTE_INFORMATION { ULONG FileSystemAttributes; LONG MaximumComponentNameLength; ULONG FileSystemNameLength; WCHAR FileSystemName[1]; } FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION; typedef struct _FILE_FS_VOLUME_INFORMATION { LARGE_INTEGER VolumeCreationTime; ULONG VolumeSerialNumber; ULONG VolumeLabelLength; BOOLEAN SupportsObjects; WCHAR VolumeLabel[1]; } FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; typedef struct _FILE_BOTH_DIR_INFORMATION { ULONG NextEntryOffset; ULONG FileIndex; LARGE_INTEGER CreationTime; LARGE_INTEGER LastAccessTime; LARGE_INTEGER LastWriteTime; LARGE_INTEGER ChangeTime; LARGE_INTEGER EndOfFile; LARGE_INTEGER AllocationSize; ULONG FileAttributes; ULONG FileNameLength; ULONG EaSize; CCHAR ShortNameLength; WCHAR ShortName[12]; WCHAR FileName[1]; } FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; typedef struct _FILE_ID_BOTH_DIR_INFORMATION { ULONG NextEntryOffset; ULONG FileIndex; LARGE_INTEGER CreationTime; LARGE_INTEGER LastAccessTime; LARGE_INTEGER LastWriteTime; LARGE_INTEGER ChangeTime; LARGE_INTEGER EndOfFile; LARGE_INTEGER AllocationSize; ULONG FileAttributes; ULONG FileNameLength; ULONG EaSize; CCHAR ShortNameLength; WCHAR ShortName[12]; LARGE_INTEGER FileId; WCHAR FileName[1]; } FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION; struct OBJECT_DIRECTORY { uint32_t NumberOfEntries; // OBJECT_ENTRY Entries[]; }; #define ObjectNameInformation (OBJECT_INFORMATION_CLASS)1 struct OBJECT_ENTRY { uint32_t NameOffset; uint32_t OffsetToData; uint32_t Size; uint32_t Options; }; class Path { public: Path(wchar_t *str) { const wchar_t *last = str; const wchar_t *cur = str; while (*cur) { if (*cur == '\\') { if (cur > last) list_.push_back(UnicodeString(last, cur - last)); last = cur + 1; } cur++; } if (cur > last) list_.push_back(UnicodeString(last, cur - last)); } UnicodeString Combine(wchar_t *str) { vector folder_list; for (size_t i = 0; i < list_.size(); i++) { folder_list.push_back(&list_[i]); } Path p(str); for (size_t i = 0; i < p.list_.size(); i++) { const UnicodeString &folder = p.list_[i]; if (folder == L".") continue; if (folder == L"..") folder_list.pop_back(); else folder_list.push_back(&folder); } UnicodeString res; for (size_t i = 0; i < folder_list.size(); i++) { if (i > 0) res.append(L"\\", 1); res.append(folder_list[i]->c_str()); } return res; } private: vector list_; }; class HookManager; class FileManager { public: FileManager(const uint8_t *data, HMODULE instance, const uint8_t *key, VirtualObjectList *objects); void HookAPIs(HookManager &hook_manager); void UnhookAPIs(HookManager &hook_manager); bool OpenFiles(RegistryManager ®istry_manager); NTSTATUS NtQueryAttributesFile(POBJECT_ATTRIBUTES ObjectAttributes, PFILE_BASIC_INFORMATION FileInformation); NTSTATUS NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength); NTSTATUS NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions); NTSTATUS NtQueryInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass); NTSTATUS NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass); NTSTATUS NtSetInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass); NTSTATUS NtQueryDirectoryFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry, PUNICODE_STRING FileName, BOOLEAN RestartScan); NTSTATUS NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key); NTSTATUS NtCreateSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle); NTSTATUS NtQuerySection(HANDLE SectionHandle, SECTION_INFORMATION_CLASS InformationClass, PVOID InformationBuffer, ULONG InformationBufferSize, PULONG ResultLength); NTSTATUS NtMapViewOfSection(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, SECTION_INHERIT InheritDisposition, ULONG AllocationType, ULONG Win32Protect); NTSTATUS NtUnmapViewOfSection(HANDLE ProcessHandle, PVOID BaseAddress); NTSTATUS NtQueryVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID Buffer, ULONG Length, PULONG ResultLength); private: NTSTATUS TrueNtQueryAttributesFile(POBJECT_ATTRIBUTES ObjectAttributes, PFILE_BASIC_INFORMATION FileInformation); NTSTATUS TrueNtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength); NTSTATUS TrueNtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions); NTSTATUS TrueNtQueryInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass); NTSTATUS TrueNtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass); NTSTATUS TrueNtSetInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass); NTSTATUS TrueNtQueryDirectoryFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry, PUNICODE_STRING FileName, BOOLEAN RestartScan); NTSTATUS TrueNtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key); NTSTATUS TrueNtCreateSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle); NTSTATUS TrueNtQuerySection(HANDLE SectionHandle, SECTION_INFORMATION_CLASS InformationClass, PVOID InformationBuffer, ULONG InformationBufferSize, PULONG ResultLength); NTSTATUS TrueNtMapViewOfSection(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, SECTION_INHERIT InheritDisposition, ULONG AllocationType, ULONG Win32Protect); NTSTATUS TrueNtUnmapViewOfSection(HANDLE ProcessHandle, PVOID BaseAddress); NTSTATUS TrueNtQueryVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID Buffer, ULONG Length, PULONG ResultLength); NTSTATUS TrueNtQueryObject(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength); OBJECT_DIRECTORY DecryptDirectory(const OBJECT_DIRECTORY *directory_enc) const; OBJECT_ENTRY DecryptEntry(const OBJECT_ENTRY *entry_enc) const; bool DecryptString(LPCWSTR str_enc, LPWSTR str, size_t max_size) const; const OBJECT_ENTRY *FindEntry(HANDLE directory, PUNICODE_STRING object_name); bool ReadFile(const OBJECT_ENTRY *entry, uint64_t offset, void *dst, size_t size) const; NTSTATUS ReadImageHeader(const OBJECT_ENTRY *entry, IMAGE_NT_HEADERS *header) const; NTSTATUS ReadImage(const OBJECT_ENTRY *entry, void *image_base) const; HMODULE instance_; uint32_t key_; VirtualObjectList *objects_; const uint8_t *data_; void *nt_query_attributes_file_; void *nt_create_file_; void *nt_open_file_; void *nt_read_file_; void *nt_query_information_file_; void *nt_query_volume_information_file_; void *nt_set_information_file_; void *nt_query_directory_file_; void *nt_close_; void *nt_create_section_; void *nt_query_section_; void *nt_map_view_of_section_; void *nt_unmap_view_of_section_; void *nt_query_virtual_memory_; vector file_name_list_; UnicodeString dos_root_; UnicodeString nt_root_; // no copy ctr or assignment op FileManager(const FileManager &); FileManager &operator =(const FileManager &); }; #endif