Multi Platform Support - Linux & macOS Compilation (#47)

This is part of ongoing work for multi platform support

This PR brings Linux x86_x64 compilation

* windows structures are now controlled by us
* most structures have the basic foundations for future 32bit
abstractions
* explicit 16bit unicode support (Linux is 32bit Unicode)
* update of all syscall code to use the new structures and unicode
system

runtime support of the emulator under linux is still ongoing.
This commit is contained in:
Maurice Heumann
2025-01-06 09:47:18 +01:00
committed by GitHub
83 changed files with 4220 additions and 916 deletions

View File

@@ -53,3 +53,116 @@ jobs:
- name: CMake Test
run: cd build/${{matrix.preset}} && ctest --verbose
build-linux-gcc:
name: Build Linux GCC
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
configuration:
- Debug
- Release
include:
- configuration: Debug
preset: debug
- configuration: Release
preset: release
steps:
- name: Checkout Source
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Ninja
uses: seanmiddleditch/gha-setup-ninja@v5
- name: CMake Build
run: cmake --workflow --preset=${{matrix.preset}}
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: Linux GCC ${{matrix.configuration}} Artifacts
path: |
build/${{matrix.preset}}/artifacts/*
build-linux-clang:
name: Build Linux Clang
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
configuration:
- Debug
- Release
include:
- configuration: Debug
preset: debug
- configuration: Release
preset: release
steps:
- name: Checkout Source
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Ninja
uses: seanmiddleditch/gha-setup-ninja@v5
- name: Install Clang
run: |
sudo apt update
sudo apt install -y wget gnupg software-properties-common
wget https://apt.llvm.org/llvm-snapshot.gpg.key -O- | sudo gpg --dearmor -o /usr/share/keyrings/llvm-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/llvm-archive-keyring.gpg] https://apt.llvm.org/$(lsb_release -sc)/ llvm-toolchain-$(lsb_release -sc)-18 main" | sudo tee /etc/apt/sources.list.d/llvm.list
sudo apt update
sudo apt install -y clang-18 lld-18
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang-18 100
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-18 100
sudo update-alternatives --set cc /usr/bin/clang-18
sudo update-alternatives --set c++ /usr/bin/clang++-18
- name: CMake Build
run: cmake --workflow --preset=${{matrix.preset}}
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: Linux Clang ${{matrix.configuration}} Artifacts
path: |
build/${{matrix.preset}}/artifacts/*
build-mac:
name: Build macOS
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
configuration:
- Debug
- Release
include:
- configuration: Debug
preset: debug
- configuration: Release
preset: release
steps:
- name: Checkout Source
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Dependencies
run: |
brew install ninja
- name: CMake Build
run: cmake --workflow --preset=${{matrix.preset}}
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: macOS ${{matrix.configuration}} Artifacts
path: |
build/${{matrix.preset}}/artifacts/*

4
.gitmodules vendored
View File

@@ -3,10 +3,6 @@
url = ../unicorn.git
shallow = true
branch = dev
[submodule "deps/phnt"]
path = deps/phnt
url = ../phnt.git
shallow = true
[submodule "deps/reflect"]
path = deps/reflect
url = https://github.com/qlibs/reflect.git

View File

@@ -209,7 +209,9 @@ function(momo_target_set_warnings_as_errors target)
return()
endif()
set(compile_options)
set(compile_options -Wall -Wextra
#-Wconversion
-pedantic -Werror -Wno-comment)
if(MSVC)
set(compile_options /W4 /WX)
@@ -315,6 +317,8 @@ function(momo_strip_target target)
endif()
if(NOT MSVC)
# TODO: detect LLVM IR bitcode and abort
return()
if(NOT DEFINED STRIP_COMMAND)
set(STRIP_COMMAND strip)
endif()

1
deps/CMakeLists.txt vendored
View File

@@ -1,7 +1,6 @@
set(UNICORN_ARCH "x86" CACHE STRING "")
add_subdirectory(unicorn)
add_subdirectory(phnt)
##########################################

1
deps/phnt vendored

Submodule deps/phnt deleted from a218107e7a

View File

@@ -5,6 +5,8 @@ add_subdirectory(windows-emulator)
add_subdirectory(analyzer)
add_subdirectory(fuzzing-engine)
add_subdirectory(fuzzer)
add_subdirectory(bad-sample)
add_subdirectory(test-sample)
if(WIN32)
add_subdirectory(bad-sample)
add_subdirectory(test-sample)
endif()
add_subdirectory(windows-emulator-test)

View File

@@ -15,20 +15,25 @@ namespace
void watch_system_objects(windows_emulator& win_emu, const bool cache_logging)
{
(void)win_emu;
(void)cache_logging;
#ifdef OS_WINDOWS
watch_object(win_emu, *win_emu.current_thread().teb, cache_logging);
watch_object(win_emu, win_emu.process().peb, cache_logging);
watch_object(win_emu, emulator_object<KUSER_SHARED_DATA>{win_emu.emu(), kusd_mmio::address()}, cache_logging);
watch_object(win_emu, emulator_object<KUSER_SHARED_DATA64>{win_emu.emu(), kusd_mmio::address()}, cache_logging);
auto* params_hook = watch_object(win_emu, win_emu.process().process_params, cache_logging);
win_emu.emu().hook_memory_write(win_emu.process().peb.value() + offsetof(PEB, ProcessParameters), 0x8,
win_emu.emu().hook_memory_write(win_emu.process().peb.value() + offsetof(PEB64, ProcessParameters), 0x8,
[&, cache_logging](const uint64_t address, size_t, const uint64_t value)
{
const auto target_address = win_emu.process().peb.value() + offsetof(
PEB, ProcessParameters);
PEB64, ProcessParameters);
if (address == target_address)
{
const emulator_object<RTL_USER_PROCESS_PARAMETERS> obj{
const emulator_object<RTL_USER_PROCESS_PARAMETERS64> obj{
win_emu.emu(), value
};
@@ -36,6 +41,7 @@ namespace
params_hook = watch_object(win_emu, obj, cache_logging);
}
});
#endif
}
void run_emulation(windows_emulator& win_emu, const analysis_options& options)
@@ -57,13 +63,14 @@ namespace
}
catch (const std::exception& e)
{
win_emu.log.print(color::red, "Emulation failed at: 0x%llX - %s\n",
win_emu.emu().read_instruction_pointer(), e.what());
win_emu.log.print(color::red, "Emulation failed at: 0x%" PRIx64 " - %s\n",
win_emu.emu().read_instruction_pointer(), e.what());
throw;
}
catch (...)
{
win_emu.log.print(color::red, "Emulation failed at: 0x%llX\n", win_emu.emu().read_instruction_pointer());
win_emu.log.print(color::red, "Emulation failed at: 0x%" PRIx64 "\n",
win_emu.emu().read_instruction_pointer());
throw;
}
@@ -78,9 +85,9 @@ namespace
}
}
std::vector<std::wstring> parse_arguments(const std::span<const std::string_view> args)
std::vector<std::u16string> parse_arguments(const std::span<const std::string_view> args)
{
std::vector<std::wstring> wide_args{};
std::vector<std::u16string> wide_args{};
wide_args.reserve(args.size() - 1);
for (size_t i = 1; i < args.size(); ++i)
@@ -140,7 +147,7 @@ namespace
win_emu.log.print(
color::green,
"Reading from executable section %s at 0x%llX via 0x%llX\n",
"Reading from executable section %s at 0x%" PRIx64 " via 0x%" PRIx64 "\n",
section.name.c_str(), address, rip);
};
@@ -161,7 +168,7 @@ namespace
win_emu.log.print(
color::blue,
"Writing to executable section %s at 0x%llX via 0x%llX\n",
"Writing to executable section %s at 0x%" PRIx64 " via 0x%" PRIx64 "\n",
section.name.c_str(), address, rip);
};

View File

@@ -31,10 +31,10 @@ emulator_hook* watch_object(windows_emulator& emu, emulator_object<T> object, co
const auto offset = address - object.value();
emu.log.print(is_main_access ? color::green : color::dark_gray,
"Object access: %s - 0x%llX (%s) at 0x%llX (%s)\n",
i.get_type_name().c_str(),
offset,
i.get_member_name(offset).c_str(), rip,
mod ? mod->name.c_str() : "<N/A>");
"Object access: %s - 0x%llX (%s) at 0x%llX (%s)\n",
i.get_type_name().c_str(),
offset,
i.get_member_name(offset).c_str(), rip,
mod ? mod->name.c_str() : "<N/A>");
});
}

View File

@@ -1,8 +1,17 @@
#pragma once
#ifndef OS_WINDOWS
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#endif
#include "reflect_extension.hpp"
#include <reflect>
#ifndef OS_WINDOWS
#pragma GCC diagnostic pop
#endif
template <typename T>
class reflect_type_info
{

View File

@@ -1,37 +1,5 @@
#pragma once
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4005)
#pragma warning(disable: 4127)
#pragma warning(disable: 4201)
#pragma warning(disable: 4244)
#pragma warning(disable: 4245)
#pragma warning(disable: 4324)
#pragma warning(disable: 4458)
#pragma warning(disable: 4471)
#pragma warning(disable: 4505)
#pragma warning(disable: 4702)
#pragma warning(disable: 4996)
#pragma warning(disable: 5054)
#pragma warning(disable: 6011)
#pragma warning(disable: 6297)
#pragma warning(disable: 6385)
#pragma warning(disable: 6386)
#pragma warning(disable: 6387)
#pragma warning(disable: 26110)
#pragma warning(disable: 26451)
#pragma warning(disable: 26444)
#pragma warning(disable: 26451)
#pragma warning(disable: 26489)
#pragma warning(disable: 26495)
#pragma warning(disable: 26498)
#pragma warning(disable: 26812)
#pragma warning(disable: 28020)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <map>
#include <set>
#include <list>
@@ -57,23 +25,6 @@
#include <cassert>
#define NTDDI_WIN11_GE 0
#define PHNT_VERSION PHNT_WIN11
#include <phnt_windows.h>
#include <phnt.h>
#include <ntgdi.h>
#ifdef _WIN32
#pragma warning(pop)
#endif
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
#endif
#include <platform/platform.hpp>
using namespace std::literals;

View File

@@ -7,5 +7,6 @@ file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS
list(SORT SRC_FILES)
add_executable(bad-sample ${SRC_FILES})
target_link_libraries(bad-sample PRIVATE common)
momo_assign_source_group(${SRC_FILES})

View File

@@ -1,10 +1,11 @@
#include <cstdint>
#include <cstdio>
#include <Windows.h>
#include <cstring>
#include <platform/compiler.hpp>
#define THE_SIZE 30
extern "C" __declspec(noinline) __declspec(dllexport)
extern "C" NO_INLINE EXPORT_SYMBOL
void vulnerable(const uint8_t* data, const size_t size)
{
if (size < 10)

View File

@@ -57,7 +57,7 @@ namespace network
this->address4_ = addr;
}
address::address(const sockaddr* addr, const int length)
address::address(const sockaddr* addr, const socklen_t length)
: address()
{
this->set_address(addr, length);
@@ -109,7 +109,7 @@ namespace network
this->address6_.sin6_addr = addr;
}
void address::set_address(const sockaddr* addr, const int length)
void address::set_address(const sockaddr* addr, const socklen_t length)
{
if (static_cast<size_t>(length) >= sizeof(sockaddr_in) && addr->sa_family == AF_INET)
{
@@ -250,29 +250,29 @@ namespace network
return this->address6_;
}
int address::get_size() const
socklen_t address::get_size() const
{
switch (this->address_.sa_family)
{
case AF_INET:
return static_cast<int>(sizeof(this->address4_));
return static_cast<socklen_t>(sizeof(this->address4_));
case AF_INET6:
return static_cast<int>(sizeof(this->address6_));
return static_cast<socklen_t>(sizeof(this->address6_));
default:
return static_cast<int>(sizeof(this->address_));
return static_cast<socklen_t>(sizeof(this->address_));
}
}
int address::get_max_size() const
socklen_t address::get_max_size() const
{
const auto s = sizeof(this->address_);
const auto s4 = sizeof(this->address4_);
const auto s6 = sizeof(this->address6_);
const auto sstore = sizeof(this->storage_);
const auto max_size = std::max(sstore, std::max(s, std::max(s4, s6)));
constexpr auto s = sizeof(this->address_);
constexpr auto s4 = sizeof(this->address4_);
constexpr auto s6 = sizeof(this->address6_);
constexpr auto sstore = sizeof(this->storage_);
constexpr auto max_size = std::max(sstore, std::max(s, std::max(s4, s6)));
static_assert(max_size == sstore);
return max_size;
return static_cast<socklen_t>(max_size);
}
bool address::is_ipv4() const
@@ -339,7 +339,7 @@ namespace network
addrinfo* result = nullptr;
if (!getaddrinfo(hostname.data(), nullptr, nullptr, &result))
{
const auto _2 = utils::finally([&result]()
const auto _2 = utils::finally([&result]
{
freeaddrinfo(result);
});
@@ -349,7 +349,7 @@ namespace network
if (i->ai_family == AF_INET || i->ai_family == AF_INET6)
{
address a{};
a.set_address(i->ai_addr, static_cast<int>(i->ai_addrlen));
a.set_address(i->ai_addr, static_cast<socklen_t>(i->ai_addrlen));
results.emplace_back(std::move(a));
}
}

View File

@@ -30,6 +30,7 @@
#include <optional>
#ifdef _WIN32
using socklen_t = int;
#pragma comment(lib, "ws2_32.lib")
#endif
@@ -44,12 +45,12 @@ namespace network
address(const std::string& addr, const std::optional<int>& family = {});
address(const sockaddr_in& addr);
address(const sockaddr_in6& addr);
address(const sockaddr* addr, int length);
address(const sockaddr* addr, socklen_t length);
void set_ipv4(uint32_t ip);
void set_ipv4(const in_addr& addr);
void set_ipv6(const in6_addr& addr);
void set_address(const sockaddr* addr, int length);
void set_address(const sockaddr* addr, socklen_t length);
void set_port(unsigned short port);
[[nodiscard]] unsigned short get_port() const;
@@ -62,8 +63,8 @@ namespace network
const sockaddr_in& get_in_addr() const;
const sockaddr_in6& get_in6_addr() const;
int get_size() const;
int get_max_size() const;
socklen_t get_size() const;
socklen_t get_max_size() const;
bool is_ipv4() const;
bool is_ipv6() const;

View File

@@ -68,10 +68,10 @@ namespace network
bool socket::send(const address& target, const void* data, const size_t size) const
{
const int res = sendto(this->socket_, static_cast<const char*>(data), static_cast<int>(size), 0,
&target.get_addr(),
target.get_size());
return res == static_cast<int>(size);
const auto res = sendto(this->socket_, static_cast<const char*>(data), static_cast<send_size>(size), 0,
&target.get_addr(),
target.get_size());
return static_cast<size_t>(res) == size;
}
bool socket::send(const address& target, const std::string& data) const
@@ -82,7 +82,7 @@ namespace network
bool socket::receive(address& source, std::string& data) const
{
char buffer[0x2000];
socklen_t len = source.get_max_size();
auto len = source.get_max_size();
const auto result = recvfrom(this->socket_, buffer, static_cast<int>(sizeof(buffer)), 0, &source.get_addr(),
&len);

View File

@@ -6,12 +6,13 @@
#include <chrono>
#ifdef _WIN32
using socklen_t = int;
using send_size = int;
#define GET_SOCKET_ERROR() (WSAGetLastError())
#define poll WSAPoll
#define SOCK_WOULDBLOCK WSAEWOULDBLOCK
#else
using SOCKET = int;
using send_size = size_t;
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
#define GET_SOCKET_ERROR() (errno)

View File

@@ -0,0 +1,44 @@
#pragma once
#if defined(_WIN32) || defined(_WIN64)
#define OS_WINDOWS
#elif defined(__APPLE__) || defined(__MACH__)
#define OS_MAC
#elif defined(__linux__)
#define OS_LINUX
#else
#error "Unsupported platform"
#endif
#ifdef OS_WINDOWS
#define EXPORT_SYMBOL __declspec(dllexport)
#define IMPORT_SYMBOL __declspec(dllimport)
#define NO_INLINE __declspec(noinline)
#define DECLSPEC_ALIGN(n) __declspec(align(n))
#define RESTRICTED_POINTER
#else
#include <cstddef>
#define EXPORT_SYMBOL __attribute__((visibility("default")))
#define IMPORT_SYMBOL
#define NO_INLINE __attribute__((noinline))
#define DECLSPEC_ALIGN(n) alignas(n)
#define fopen_s fopen
#define RESTRICTED_POINTER __restrict
#ifdef OS_MAC
#define _fseeki64 fseeko
#define _ftelli64 ftello
#define _stat64 stat
#else
#define _fseeki64 fseeko64
#define _ftelli64 ftello64
#define _stat64 stat64
#endif
#endif

View File

@@ -0,0 +1,383 @@
#pragma once
#define ACCESS_MASK DWORD
#define DEVICE_TYPE DWORD
#define FILE_DEVICE_DISK 0x00000007
#define FILE_DEVICE_CONSOLE 0x00000050
#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
#ifndef OS_WINDOWS
#define GENERIC_READ 0x80000000
#define GENERIC_WRITE 0x40000000
#define GENERIC_EXECUTE 0x20000000
#define GENERIC_ALL 0x10000000
#undef DELETE
#define DELETE 0x00010000
#define READ_CONTROL 0x00020000
#define WRITE_DAC 0x00040000
#define WRITE_OWNER 0x00080000
#define SYNCHRONIZE 0x00100000
#define STANDARD_RIGHTS_REQUIRED 0x000f0000
#define FILE_READ_DATA 0x0001 /* file & pipe */
#define FILE_LIST_DIRECTORY 0x0001 /* directory */
#define FILE_WRITE_DATA 0x0002 /* file & pipe */
#define FILE_ADD_FILE 0x0002 /* directory */
#define FILE_APPEND_DATA 0x0004 /* file */
#define FILE_ADD_SUBDIRECTORY 0x0004 /* directory */
#define FILE_CREATE_PIPE_INSTANCE 0x0004 /* named pipe */
#define FILE_READ_EA 0x0008 /* file & directory */
#define FILE_READ_PROPERTIES FILE_READ_EA
#define FILE_WRITE_EA 0x0010 /* file & directory */
#define FILE_WRITE_PROPERTIES FILE_WRITE_EA
#define FILE_EXECUTE 0x0020 /* file */
#define FILE_TRAVERSE 0x0020 /* directory */
#define FILE_DELETE_CHILD 0x0040 /* directory */
#define FILE_READ_ATTRIBUTES 0x0080 /* all */
#define FILE_WRITE_ATTRIBUTES 0x0100 /* all */
#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1ff)
#endif
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_WRITE_THROUGH 0x00000002
#define FILE_SEQUENTIAL_ONLY 0x00000004
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_CREATE_TREE_CONNECTION 0x00000080
#define FILE_ATTRIBUTE_NORMAL 0x00000080
#define PS_ATTRIBUTE_NUMBER_MASK 0x0000ffff
#define PS_ATTRIBUTE_THREAD 0x00010000 // may be used with thread creation
#define PS_ATTRIBUTE_INPUT 0x00020000 // input only
#define PS_ATTRIBUTE_ADDITIVE 0x00040000 // "accumulated" e.g. bitmasks, counters, etc.
#define SL_RESTART_SCAN 0x01
#define SL_RETURN_SINGLE_ENTRY 0x02
#define SL_NO_CURSOR_UPDATE 0x10
#define SEC_IMAGE 0x01000000
typedef enum _FSINFOCLASS
{
FileFsVolumeInformation = 1, // q: FILE_FS_VOLUME_INFORMATION
FileFsLabelInformation, // s: FILE_FS_LABEL_INFORMATION (requires FILE_WRITE_DATA to volume)
FileFsSizeInformation, // q: FILE_FS_SIZE_INFORMATION
FileFsDeviceInformation, // q: FILE_FS_DEVICE_INFORMATION
FileFsAttributeInformation, // q: FILE_FS_ATTRIBUTE_INFORMATION
FileFsControlInformation,
// q, s: FILE_FS_CONTROL_INFORMATION (q: requires FILE_READ_DATA; s: requires FILE_WRITE_DATA to volume)
FileFsFullSizeInformation, // q: FILE_FS_FULL_SIZE_INFORMATION
FileFsObjectIdInformation, // q; s: FILE_FS_OBJECTID_INFORMATION (s: requires FILE_WRITE_DATA to volume)
FileFsDriverPathInformation, // q: FILE_FS_DRIVER_PATH_INFORMATION
FileFsVolumeFlagsInformation,
// q; s: FILE_FS_VOLUME_FLAGS_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES to volume) // 10
FileFsSectorSizeInformation, // q: FILE_FS_SECTOR_SIZE_INFORMATION // since WIN8
FileFsDataCopyInformation, // q: FILE_FS_DATA_COPY_INFORMATION
FileFsMetadataSizeInformation, // q: FILE_FS_METADATA_SIZE_INFORMATION // since THRESHOLD
FileFsFullSizeInformationEx, // q: FILE_FS_FULL_SIZE_INFORMATION_EX // since REDSTONE5
FileFsGuidInformation, // q: FILE_FS_GUID_INFORMATION // since 23H2
FileFsMaximumInformation
} FSINFOCLASS, *PFSINFOCLASS;
typedef enum _FSINFOCLASS FS_INFORMATION_CLASS;
typedef enum _FILE_INFORMATION_CLASS
{
FileDirectoryInformation = 1,
// q: FILE_DIRECTORY_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileFullDirectoryInformation,
// q: FILE_FULL_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileBothDirectoryInformation,
// q: FILE_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileBasicInformation,
// q; s: FILE_BASIC_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileStandardInformation, // q: FILE_STANDARD_INFORMATION, FILE_STANDARD_INFORMATION_EX
FileInternalInformation, // q: FILE_INTERNAL_INFORMATION
FileEaInformation, // q: FILE_EA_INFORMATION
FileAccessInformation, // q: FILE_ACCESS_INFORMATION
FileNameInformation, // q: FILE_NAME_INFORMATION
FileRenameInformation, // s: FILE_RENAME_INFORMATION (requires DELETE) // 10
FileLinkInformation, // s: FILE_LINK_INFORMATION
FileNamesInformation, // q: FILE_NAMES_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileDispositionInformation, // s: FILE_DISPOSITION_INFORMATION (requires DELETE)
FilePositionInformation, // q; s: FILE_POSITION_INFORMATION
FileFullEaInformation, // FILE_FULL_EA_INFORMATION
FileModeInformation, // q; s: FILE_MODE_INFORMATION
FileAlignmentInformation, // q: FILE_ALIGNMENT_INFORMATION
FileAllInformation, // q: FILE_ALL_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileAllocationInformation, // s: FILE_ALLOCATION_INFORMATION (requires FILE_WRITE_DATA)
FileEndOfFileInformation, // s: FILE_END_OF_FILE_INFORMATION (requires FILE_WRITE_DATA) // 20
FileAlternateNameInformation, // q: FILE_NAME_INFORMATION
FileStreamInformation, // q: FILE_STREAM_INFORMATION
FilePipeInformation,
// q; s: FILE_PIPE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FilePipeLocalInformation, // q: FILE_PIPE_LOCAL_INFORMATION (requires FILE_READ_ATTRIBUTES)
FilePipeRemoteInformation,
// q; s: FILE_PIPE_REMOTE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileMailslotQueryInformation, // q: FILE_MAILSLOT_QUERY_INFORMATION
FileMailslotSetInformation, // s: FILE_MAILSLOT_SET_INFORMATION
FileCompressionInformation, // q: FILE_COMPRESSION_INFORMATION
FileObjectIdInformation, // q: FILE_OBJECTID_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileCompletionInformation, // s: FILE_COMPLETION_INFORMATION // 30
FileMoveClusterInformation, // s: FILE_MOVE_CLUSTER_INFORMATION (requires FILE_WRITE_DATA)
FileQuotaInformation, // q: FILE_QUOTA_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileReparsePointInformation,
// q: FILE_REPARSE_POINT_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileNetworkOpenInformation, // q: FILE_NETWORK_OPEN_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileAttributeTagInformation, // q: FILE_ATTRIBUTE_TAG_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileTrackingInformation, // s: FILE_TRACKING_INFORMATION (requires FILE_WRITE_DATA)
FileIdBothDirectoryInformation,
// q: FILE_ID_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileIdFullDirectoryInformation,
// q: FILE_ID_FULL_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileValidDataLengthInformation,
// s: FILE_VALID_DATA_LENGTH_INFORMATION (requires FILE_WRITE_DATA and/or SeManageVolumePrivilege)
FileShortNameInformation, // s: FILE_NAME_INFORMATION (requires DELETE) // 40
FileIoCompletionNotificationInformation,
// q; s: FILE_IO_COMPLETION_NOTIFICATION_INFORMATION (q: requires FILE_READ_ATTRIBUTES) // since VISTA
FileIoStatusBlockRangeInformation, // s: FILE_IOSTATUSBLOCK_RANGE_INFORMATION (requires SeLockMemoryPrivilege)
FileIoPriorityHintInformation,
// q; s: FILE_IO_PRIORITY_HINT_INFORMATION, FILE_IO_PRIORITY_HINT_INFORMATION_EX (q: requires FILE_READ_DATA)
FileSfioReserveInformation, // q; s: FILE_SFIO_RESERVE_INFORMATION (q: requires FILE_READ_DATA)
FileSfioVolumeInformation, // q: FILE_SFIO_VOLUME_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileHardLinkInformation, // q: FILE_LINKS_INFORMATION
FileProcessIdsUsingFileInformation, // q: FILE_PROCESS_IDS_USING_FILE_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileNormalizedNameInformation, // q: FILE_NAME_INFORMATION
FileNetworkPhysicalNameInformation, // q: FILE_NETWORK_PHYSICAL_NAME_INFORMATION
FileIdGlobalTxDirectoryInformation,
// q: FILE_ID_GLOBAL_TX_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // since WIN7 // 50
FileIsRemoteDeviceInformation, // q: FILE_IS_REMOTE_DEVICE_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileUnusedInformation,
FileNumaNodeInformation, // q: FILE_NUMA_NODE_INFORMATION
FileStandardLinkInformation, // q: FILE_STANDARD_LINK_INFORMATION
FileRemoteProtocolInformation, // q: FILE_REMOTE_PROTOCOL_INFORMATION
FileRenameInformationBypassAccessCheck, // (kernel-mode only); s: FILE_RENAME_INFORMATION // since WIN8
FileLinkInformationBypassAccessCheck, // (kernel-mode only); s: FILE_LINK_INFORMATION
FileVolumeNameInformation, // q: FILE_VOLUME_NAME_INFORMATION
FileIdInformation, // q: FILE_ID_INFORMATION
FileIdExtdDirectoryInformation,
// q: FILE_ID_EXTD_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // 60
FileReplaceCompletionInformation, // s: FILE_COMPLETION_INFORMATION // since WINBLUE
FileHardLinkFullIdInformation, // q: FILE_LINK_ENTRY_FULL_ID_INFORMATION // FILE_LINKS_FULL_ID_INFORMATION
FileIdExtdBothDirectoryInformation,
// q: FILE_ID_EXTD_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // since THRESHOLD
FileDispositionInformationEx, // s: FILE_DISPOSITION_INFO_EX (requires DELETE) // since REDSTONE
FileRenameInformationEx, // s: FILE_RENAME_INFORMATION_EX
FileRenameInformationExBypassAccessCheck, // (kernel-mode only); s: FILE_RENAME_INFORMATION_EX
FileDesiredStorageClassInformation,
// q; s: FILE_DESIRED_STORAGE_CLASS_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES) // since REDSTONE2
FileStatInformation, // q: FILE_STAT_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileMemoryPartitionInformation, // s: FILE_MEMORY_PARTITION_INFORMATION // since REDSTONE3
FileStatLxInformation,
// q: FILE_STAT_LX_INFORMATION (requires FILE_READ_ATTRIBUTES and FILE_READ_EA) // since REDSTONE4 // 70
FileCaseSensitiveInformation,
// q; s: FILE_CASE_SENSITIVE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileLinkInformationEx, // s: FILE_LINK_INFORMATION_EX // since REDSTONE5
FileLinkInformationExBypassAccessCheck, // (kernel-mode only); s: FILE_LINK_INFORMATION_EX
FileStorageReserveIdInformation,
// q; s: FILE_STORAGE_RESERVE_ID_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileCaseSensitiveInformationForceAccessCheck, // q; s: FILE_CASE_SENSITIVE_INFORMATION
FileKnownFolderInformation,
// q; s: FILE_KNOWN_FOLDER_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES) // since WIN11
FileStatBasicInformation, // since 23H2
FileId64ExtdDirectoryInformation, // FILE_ID_64_EXTD_DIR_INFORMATION
FileId64ExtdBothDirectoryInformation, // FILE_ID_64_EXTD_BOTH_DIR_INFORMATION
FileIdAllExtdDirectoryInformation, // FILE_ID_ALL_EXTD_DIR_INFORMATION
FileIdAllExtdBothDirectoryInformation, // FILE_ID_ALL_EXTD_BOTH_DIR_INFORMATION
FileStreamReservationInformation, // FILE_STREAM_RESERVATION_INFORMATION // since 24H2
FileMupProviderInfo, // MUP_PROVIDER_INFORMATION
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef enum _OBJECT_INFORMATION_CLASS
{
ObjectBasicInformation, // q: OBJECT_BASIC_INFORMATION
ObjectNameInformation, // q: OBJECT_NAME_INFORMATION
ObjectTypeInformation, // q: OBJECT_TYPE_INFORMATION
ObjectTypesInformation, // q: OBJECT_TYPES_INFORMATION
ObjectHandleFlagInformation, // qs: OBJECT_HANDLE_FLAG_INFORMATION
ObjectSessionInformation, // s: void // change object session // (requires SeTcbPrivilege)
ObjectSessionObjectInformation, // s: void // change object session // (requires SeTcbPrivilege)
MaxObjectInfoClass
} OBJECT_INFORMATION_CLASS;
typedef enum _HARDERROR_RESPONSE_OPTION
{
OptionAbortRetryIgnore,
OptionOk,
OptionOkCancel,
OptionRetryCancel,
OptionYesNo,
OptionYesNoCancel,
OptionShutdownSystem,
OptionOkNoWait,
OptionCancelTryContinue
} HARDERROR_RESPONSE_OPTION;
typedef enum _HARDERROR_RESPONSE
{
ResponseReturnToCaller,
ResponseNotHandled,
ResponseAbort,
ResponseCancel,
ResponseIgnore,
ResponseNo,
ResponseOk,
ResponseRetry,
ResponseYes,
ResponseTryAgain,
ResponseContinue
} HARDERROR_RESPONSE;
typedef USHORT RTL_ATOM;
template <typename Traits>
struct IO_STATUS_BLOCK
{
union
{
NTSTATUS Status;
typename Traits::PVOID Pointer;
};
typename Traits::ULONG_PTR Information;
};
template <typename Traits>
struct OBJECT_ATTRIBUTES
{
ULONG Length;
typename Traits::HANDLE RootDirectory;
EMULATOR_CAST(typename Traits::PVOID, UNICODE_STRING*) ObjectName;
ULONG Attributes;
typename Traits::PVOID SecurityDescriptor; // PSECURITY_DESCRIPTOR;
typename Traits::PVOID SecurityQualityOfService; // PSECURITY_QUALITY_OF_SERVICE
};
typedef struct _FILE_FS_DEVICE_INFORMATION
{
DEVICE_TYPE DeviceType;
ULONG Characteristics;
} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
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;
char16_t FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
typedef struct _FILE_BASIC_INFORMATION
{
LARGE_INTEGER CreationTime; // Specifies the time that the file was created.
LARGE_INTEGER LastAccessTime; // Specifies the time that the file was last accessed.
LARGE_INTEGER LastWriteTime; // Specifies the time that the file was last written to.
LARGE_INTEGER ChangeTime; // Specifies the last time the file was changed.
ULONG FileAttributes; // Specifies one or more FILE_ATTRIBUTE_XXX flags.
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
typedef struct _FILE_DIRECTORY_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;
char16_t FileName[1];
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
typedef struct _FILE_FULL_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;
char16_t FileName[1];
} FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_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;
char ShortNameLength;
char16_t ShortName[12];
char16_t FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
#ifndef OS_WINDOWS
typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE,
* PSECURITY_CONTEXT_TRACKING_MODE;
typedef struct _SECURITY_QUALITY_OF_SERVICE
{
DWORD Length;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
BOOLEAN EffectiveOnly;
} SECURITY_QUALITY_OF_SERVICE, *P_SECURITY_QUALITY_OF_SERVICE;
#endif
typedef struct _PORT_VIEW64
{
ULONG Length;
EMULATOR_CAST(std::uint64_t, HANDLE) SectionHandle;
ULONG SectionOffset;
EMULATOR_CAST(std::int64_t, SIZE_T) ViewSize;
EmulatorTraits<Emu64>::PVOID ViewBase;
EmulatorTraits<Emu64>::PVOID ViewRemoteBase;
} PORT_VIEW64, *PPORT_VIEW64;
typedef struct _REMOTE_PORT_VIEW64
{
ULONG Length;
EMULATOR_CAST(std::int64_t, SIZE_T) ViewSize;
EmulatorTraits<Emu64>::PVOID ViewBase;
} REMOTE_PORT_VIEW64, *PREMOTE_PORT_VIEW64;

View File

@@ -0,0 +1,886 @@
#pragma once
#include <cstdint>
#define PROCESSOR_FEATURE_MAX 64
#define GDI_HANDLE_BUFFER_SIZE64 60
#define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_RELEASE_ON_DEACTIVATION 0x00000001
#define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_NO_DEACTIVATE 0x00000002
#define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_ON_FREE_LIST 0x00000004
#define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_HEAP_ALLOCATED 0x00000008
#define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_NOT_REALLY_ACTIVATED 0x00000010
#define ACTIVATION_CONTEXT_STACK_FLAG_QUERIES_DISABLED 0x00000001
#define GDI_BATCH_BUFFER_SIZE 310
#define WIN32_CLIENT_INFO_LENGTH 62
#define STATIC_UNICODE_BUFFER_LENGTH 261
#define TLS_MINIMUM_AVAILABLE 64
typedef struct _EMU_NT_TIB64
{
struct _EXCEPTION_REGISTRATION_RECORD* ExceptionList;
std::uint64_t* StackBase;
std::uint64_t* StackLimit;
std::uint64_t* SubSystemTib;
std::uint64_t* FibreData;
std::uint64_t* ArbitraryUserPointer;
struct _EMU_NT_TIB64* Self;
} EMU_NT_TIB64;
typedef EMU_NT_TIB64* PEMU_NT_TIB64;
union PEB_BITFIELD_UNION
{
BOOLEAN BitField;
struct
{
BOOLEAN ImageUsesLargePages : 1;
BOOLEAN IsProtectedProcess : 1;
BOOLEAN IsImageDynamicallyRelocated : 1;
BOOLEAN SkipPatchingUser32Forwarders : 1;
BOOLEAN IsPackagedProcess : 1;
BOOLEAN IsAppContainer : 1;
BOOLEAN IsProtectedProcessLight : 1;
BOOLEAN IsLongPathAwareProcess : 1;
};
};
#ifndef OS_WINDOWS
typedef struct _LIST_ENTRY64
{
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY64, *PLIST_ENTRY64, *RESTRICTED_POINTER PRLIST_ENTRY64;
#endif
typedef struct _PEB_LDR_DATA64
{
ULONG Length;
BOOLEAN Initialized;
EmulatorTraits<Emu64>::HANDLE SsHandle;
LIST_ENTRY64 InLoadOrderModuleList;
LIST_ENTRY64 InMemoryOrderModuleList;
LIST_ENTRY64 InInitializationOrderModuleList;
std::uint64_t* EntryInProgress;
BOOLEAN ShutdownInProgress;
EmulatorTraits<Emu64>::HANDLE ShutdownThreadId;
} PEB_LDR_DATA64, *PPEB_LDR_DATA64;
typedef struct _STRING64
{
USHORT Length;
USHORT MaximumLength;
char16_t* Buffer;
} STRING64, *PSTRING64, ANSI_STRING64, *PANSI_STRING64, OEM_STRING64, *POEM_STRING64;
typedef struct _RTL_DRIVE_LETTER_CURDIR64
{
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
STRING64 DosPath;
} RTL_DRIVE_LETTER_CURDIR64, *PRTL_DRIVE_LETTER_CURDIR64;
#define RTL_MAX_DRIVE_LETTERS 32
#define RTL_DRIVE_LETTER_VALID (USHORT)0x0001
template <typename T, size_t Size>
struct ARRAY_CONTAINER
{
T arr[Size];
};
typedef struct _CURDIR64
{
UNICODE_STRING<EmulatorTraits<Emu64>> DosPath;
EmulatorTraits<Emu64>::HANDLE Handle;
} CURDIR64, *PCURDIR64;
typedef struct _RTL_USER_PROCESS_PARAMETERS64
{
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
EmulatorTraits<Emu64>::HANDLE ConsoleHandle;
ULONG ConsoleFlags;
EmulatorTraits<Emu64>::HANDLE StandardInput;
EmulatorTraits<Emu64>::HANDLE StandardOutput;
EmulatorTraits<Emu64>::HANDLE StandardError;
CURDIR64 CurrentDirectory;
UNICODE_STRING<EmulatorTraits<Emu64>> DllPath;
UNICODE_STRING<EmulatorTraits<Emu64>> ImagePathName;
UNICODE_STRING<EmulatorTraits<Emu64>> CommandLine;
std::uint64_t* Environment;
ULONG StartingX;
ULONG StartingY;
ULONG CountX;
ULONG CountY;
ULONG CountCharsX;
ULONG CountCharsY;
ULONG FillAttribute;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING<EmulatorTraits<Emu64>> WindowTitle;
UNICODE_STRING<EmulatorTraits<Emu64>> DesktopInfo;
UNICODE_STRING<EmulatorTraits<Emu64>> ShellInfo;
UNICODE_STRING<EmulatorTraits<Emu64>> RuntimeData;
ARRAY_CONTAINER<RTL_DRIVE_LETTER_CURDIR64, RTL_MAX_DRIVE_LETTERS> CurrentDirectories;
std::uint64_t* EnvironmentSize;
std::uint64_t* EnvironmentVersion;
std::uint64_t* PackageDependencyData;
ULONG ProcessGroupId;
ULONG LoaderThreads;
UNICODE_STRING<EmulatorTraits<Emu64>> RedirectionDllName; // REDSTONE4
UNICODE_STRING<EmulatorTraits<Emu64>> HeapPartitionName; // 19H1
std::uint64_t* DefaultThreadpoolCpuSetMasks;
ULONG DefaultThreadpoolCpuSetMaskCount;
ULONG DefaultThreadpoolThreadMaximum;
ULONG HeapMemoryTypeMask; // WIN11
} RTL_USER_PROCESS_PARAMETERS64, *PRTL_USER_PROCESS_PARAMETERS64;
union PEB_CROSS_PROCESS_FLAGS_UNION
{
ULONG CrossProcessFlags;
struct
{
ULONG ProcessInJob : 1;
ULONG ProcessInitializing : 1;
ULONG ProcessUsingVEH : 1;
ULONG ProcessUsingVCH : 1;
ULONG ProcessUsingFTH : 1;
ULONG ProcessPreviouslyThrottled : 1;
ULONG ProcessCurrentlyThrottled : 1;
ULONG ProcessImagesHotPatched : 1; // REDSTONE5
ULONG ReservedBits0 : 24;
};
};
union PEB_KERNEL_CALLBACK_TABLE_UNION64
{
void* KernelCallbackTable;
void* UserSharedInfoPtr;
};
typedef struct _API_SET_NAMESPACE
{
ULONG Version;
ULONG Size;
ULONG Flags;
ULONG Count;
ULONG EntryOffset;
ULONG HashOffset;
ULONG HashFactor;
} API_SET_NAMESPACE, *PAPI_SET_NAMESPACE;
union PEB_CONTEXT_DATA_UNION64
{
void* pContextData; // WIN7
void* pUnused; // WIN10
void* EcCodeBitMap; // WIN11
};
union PEB_TRACING_FLAGS_UNION
{
ULONG TracingFlags;
struct
{
ULONG HeapTracingEnabled : 1;
ULONG CritSecTracingEnabled : 1;
ULONG LibLoaderTracingEnabled : 1;
ULONG SpareTracingBits : 29;
};
};
union PEB_LEAP_SECONDS_FLAG_UNION
{
ULONG LeapSecondFlags;
struct
{
ULONG SixtySecondEnabled : 1;
ULONG Reserved : 31;
};
};
typedef struct _PEB64
{
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
PEB_BITFIELD_UNION BitField;
EmulatorTraits<Emu64>::HANDLE Mutant;
std::uint64_t* ImageBaseAddress;
PPEB_LDR_DATA64 Ldr;
PRTL_USER_PROCESS_PARAMETERS64 ProcessParameters;
std::uint64_t* SubSystemData;
std::uint64_t* ProcessHeap;
EMULATOR_CAST(void*, PRTL_CRITICAL_SECTION) FastPebLock;
EMULATOR_CAST(void*, PSLIST_HEADER) AtlThunkSListPtr;
std::uint64_t* IFEOKey;
PEB_CROSS_PROCESS_FLAGS_UNION CrossProcessFlags;
PEB_KERNEL_CALLBACK_TABLE_UNION64 KernelCallbackTable;
ULONG SystemReserved;
ULONG AtlThunkSListPtr32;
PAPI_SET_NAMESPACE ApiSetMap;
ULONG TlsExpansionCounter;
EMULATOR_CAST(void*, PRTL_BITMAP) TlsBitmap;
ARRAY_CONTAINER<ULONG, 2> TlsBitmapBits; // TLS_MINIMUM_AVAILABLE
void* ReadOnlySharedMemoryBase;
EMULATOR_CAST(void*, PSILO_USER_SHARED_DATA) SharedData; // HotpatchInformation
std::uint64_t** ReadOnlyStaticServerData;
std::uint64_t* AnsiCodePageData; // PCPTABLEINFO
std::uint64_t* OemCodePageData; // PCPTABLEINFO
std::uint64_t* UnicodeCaseTableData; // PNLSTABLEINFO
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
ULARGE_INTEGER CriticalSectionTimeout;
EMULATOR_CAST(std::int64_t, SIZE_T) HeapSegmentReserve;
EMULATOR_CAST(std::int64_t, SIZE_T) HeapSegmentCommit;
EMULATOR_CAST(std::int64_t, SIZE_T) HeapDeCommitTotalFreeThreshold;
EMULATOR_CAST(std::int64_t, SIZE_T) HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
std::uint64_t** ProcessHeaps; // PHEAP
std::uint64_t* GdiSharedHandleTable; // PGDI_SHARED_MEMORY
std::uint64_t* ProcessStarterHelper;
ULONG GdiDCAttributeList;
EMULATOR_CAST(void*, PRTL_CRITICAL_SECTION) LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
USHORT OSBuildNumber;
USHORT OSCSDVersion;
ULONG OSPlatformId;
ULONG ImageSubsystem;
ULONG ImageSubsystemMajorVersion;
ULONG ImageSubsystemMinorVersion;
EMULATOR_CAST(std::uint64_t, KAFFINITY) ActiveProcessAffinityMask;
ARRAY_CONTAINER<ULONG, GDI_HANDLE_BUFFER_SIZE64> GdiHandleBuffer;
std::uint64_t* PostProcessInitRoutine;
EMULATOR_CAST(void*, PRTL_BITMAP) TlsExpansionBitmap;
ARRAY_CONTAINER<ULONG, 32> TlsExpansionBitmapBits; // TLS_EXPANSION_SLOTS
ULONG SessionId;
ULARGE_INTEGER AppCompatFlags; // KACF_*
ULARGE_INTEGER AppCompatFlagsUser;
std::uint64_t* pShimData;
std::uint64_t* AppCompatInfo; // APPCOMPAT_EXE_DATA
UNICODE_STRING<EmulatorTraits<Emu64>> CSDVersion;
EMULATOR_CAST(void*, PACTIVATION_CONTEXT_DATA) ActivationContextData;
EMULATOR_CAST(void*, PASSEMBLY_STORAGE_MAP) ProcessAssemblyStorageMap;
EMULATOR_CAST(void*, PACTIVATION_CONTEXT_DATA) SystemDefaultActivationContextData;
EMULATOR_CAST(void*, PASSEMBLY_STORAGE_MAP) SystemAssemblyStorageMap;
EMULATOR_CAST(std::int64_t, SIZE_T) MinimumStackCommit;
ARRAY_CONTAINER<std::uint64_t*, 2> SparePointers; // 19H1 (previously FlsCallback to FlsHighIndex)
std::uint64_t* PatchLoaderData;
std::uint64_t* ChpeV2ProcessInfo; // _CHPEV2_PROCESS_INFO
ULONG AppModelFeatureState;
ARRAY_CONTAINER<ULONG, 2> SpareUlongs;
USHORT ActiveCodePage;
USHORT OemCodePage;
USHORT UseCaseMapping;
USHORT UnusedNlsField;
std::uint64_t* WerRegistrationData;
std::uint64_t* WerShipAssertPtr;
PEB_CONTEXT_DATA_UNION64 ContextData;
std::uint64_t* pImageHeaderHash;
PEB_TRACING_FLAGS_UNION TracingFlags;
ULONGLONG CsrServerReadOnlySharedMemoryBase;
EMULATOR_CAST(void*, PRTL_CRITICAL_SECTION) TppWorkerpListLock;
LIST_ENTRY64 TppWorkerpList;
ARRAY_CONTAINER<std::uint64_t*, 128> WaitOnAddressHashTable;
EMULATOR_CAST(void*, PTELEMETRY_COVERAGE_HEADER) TelemetryCoverageHeader; // REDSTONE3
ULONG CloudFileFlags;
ULONG CloudFileDiagFlags; // REDSTONE4
CHAR PlaceholderCompatibilityMode;
ARRAY_CONTAINER<CHAR, 7> PlaceholderCompatibilityModeReserved;
EMULATOR_CAST(void*, PLEAP_SECOND_DATA) LeapSecondData; // REDSTONE5
PEB_LEAP_SECONDS_FLAG_UNION LeapSecondFlags;
ULONG NtGlobalFlag2;
ULONGLONG ExtendedFeatureDisableMask; // since WIN11
} PEB64, *PPEB64;
typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME64
{
struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME* Previous;
EMULATOR_CAST(void*, ACTIVATION_CONTEXT) ActivationContext;
ULONG Flags; // RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_*
} RTL_ACTIVATION_CONTEXT_STACK_FRAME64, *PRTL_ACTIVATION_CONTEXT_STACK_FRAME64;
typedef struct _ACTIVATION_CONTEXT_STACK64
{
PRTL_ACTIVATION_CONTEXT_STACK_FRAME64 ActiveFrame;
LIST_ENTRY64 FrameListCache;
ULONG Flags; // ACTIVATION_CONTEXT_STACK_FLAG_*
ULONG NextCookieSequenceNumber;
ULONG StackId;
} ACTIVATION_CONTEXT_STACK64, *PACTIVATION_CONTEXT_STACK64;
typedef struct _GDI_TEB_BATCH64
{
ULONG Offset;
std::uint64_t* HDC;
ULONG Buffer[GDI_BATCH_BUFFER_SIZE];
} GDI_TEB_BATCH64, *PGDI_TEB_BATCH64;
#ifndef OS_WINDOWS
typedef struct _GUID
{
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
typedef struct _PROCESSOR_NUMBER
{
WORD Group;
BYTE Number;
BYTE Reserved;
} PROCESSOR_NUMBER, *PPROCESSOR_NUMBER;
#endif
union TEB_CURRENT_IDEAL_PROCESSOR_UNION
{
PROCESSOR_NUMBER CurrentIdealProcessor;
ULONG IdealProcessorValue;
struct
{
UCHAR ReservedPad0;
UCHAR ReservedPad1;
UCHAR ReservedPad2;
UCHAR IdealProcessor;
};
};
union TEB_CROSS_TEB_FLAGS_UNION
{
USHORT CrossTebFlags;
USHORT SpareCrossTebBits : 16;
};
union TEB_SAME_TEB_FLAGS_UNION
{
USHORT SameTebFlags;
struct
{
USHORT SafeThunkCall : 1;
USHORT InDebugPrint : 1;
USHORT HasFiberData : 1;
USHORT SkipThreadAttach : 1;
USHORT WerInShipAssertCode : 1;
USHORT RanProcessInit : 1;
USHORT ClonedThread : 1;
USHORT SuppressDebugMsg : 1;
USHORT DisableUserStackWalk : 1;
USHORT RtlExceptionAttached : 1;
USHORT InitialThread : 1;
USHORT SessionAware : 1;
USHORT LoadOwner : 1;
USHORT LoaderWorker : 1;
USHORT SkipLoaderInit : 1;
USHORT SkipFileAPIBrokering : 1;
};
};
#ifndef OS_WINDOWS
using LCID = DWORD;
#endif
typedef struct _TEB64
{
EMU_NT_TIB64 NtTib;
std::uint64_t* EnvironmentPointer;
CLIENT_ID64 ClientId;
std::uint64_t* ActiveRpcHandle;
std::uint64_t* ThreadLocalStoragePointer;
PPEB64 ProcessEnvironmentBlock;
ULONG LastErrorValue;
ULONG CountOfOwnedCriticalSections;
std::uint64_t* CsrClientThread;
std::uint64_t* Win32ThreadInfo;
ARRAY_CONTAINER<ULONG, 26> User32Reserved;
ARRAY_CONTAINER<ULONG, 5> UserReserved;
std::uint64_t* WOW32Reserved;
LCID CurrentLocale;
ULONG FpSoftwareStatusRegister;
ARRAY_CONTAINER<void*, 16> ReservedForDebuggerInstrumentation;
ARRAY_CONTAINER<void*, 25> SystemReserved1;
std::uint64_t* HeapFlsData;
ARRAY_CONTAINER<std::uint64_t*, 4> RngState;
CHAR PlaceholderCompatibilityMode;
BOOLEAN PlaceholderHydrationAlwaysExplicit;
ARRAY_CONTAINER<CHAR, 10> PlaceholderReserved;
ULONG ProxiedProcessId;
ACTIVATION_CONTEXT_STACK64 ActivationStack;
ARRAY_CONTAINER<UCHAR, 8> WorkingOnBehalfTicket;
NTSTATUS ExceptionCode;
PACTIVATION_CONTEXT_STACK64 ActivationContextStackPointer;
std::uint64_t* InstrumentationCallbackSp;
std::uint64_t* InstrumentationCallbackPreviousPc;
std::uint64_t* InstrumentationCallbackPreviousSp;
ULONG TxFsContext;
BOOLEAN InstrumentationCallbackDisabled;
BOOLEAN UnalignedLoadStoreExceptions;
GDI_TEB_BATCH64 GdiTebBatch;
CLIENT_ID64 RealClientId;
EmulatorTraits<Emu64>::HANDLE GdiCachedProcessHandle;
ULONG GdiClientPID;
ULONG GdiClientTID;
std::uint64_t* GdiThreadLocalInfo;
ARRAY_CONTAINER<std::uint64_t*, WIN32_CLIENT_INFO_LENGTH> Win32ClientInfo;
ARRAY_CONTAINER<void*, 233> glDispatchTable;
ARRAY_CONTAINER<std::uint64_t*, 29> glReserved1;
std::uint64_t* glReserved2;
std::uint64_t* glSectionInfo;
std::uint64_t* glSection;
std::uint64_t* glTable;
std::uint64_t* glCurrentRC;
std::uint64_t* glContext;
NTSTATUS LastStatusValue;
UNICODE_STRING<EmulatorTraits<Emu64>> StaticUnicodeString;
ARRAY_CONTAINER<char16_t, STATIC_UNICODE_BUFFER_LENGTH> StaticUnicodeBuffer;
std::uint64_t* DeallocationStack;
ARRAY_CONTAINER<std::uint64_t*, TLS_MINIMUM_AVAILABLE> TlsSlots;
LIST_ENTRY64 TlsLinks;
std::uint64_t* Vdm;
std::uint64_t* ReservedForNtRpc;
ARRAY_CONTAINER<void*, 2> DbgSsReserved;
ULONG HardErrorMode;
ARRAY_CONTAINER<void*, 11> Instrumentation;
GUID ActivityId;
std::uint64_t* SubProcessTag;
std::uint64_t* PerflibData;
std::uint64_t* EtwTraceData;
std::uint64_t* WinSockData;
ULONG GdiBatchCount;
TEB_CURRENT_IDEAL_PROCESSOR_UNION CurrentIdealProcessor;
ULONG GuaranteedStackBytes;
std::uint64_t* ReservedForPerf;
std::uint64_t* ReservedForOle; // tagSOleTlsData
ULONG WaitingOnLoaderLock;
std::uint64_t* SavedPriorityState;
std::uint64_t* ReservedForCodeCoverage;
std::uint64_t* ThreadPoolData;
std::uint64_t** TlsExpansionSlots;
std::uint64_t* ChpeV2CpuAreaInfo; // CHPEV2_CPUAREA_INFO // previously DeallocationBStore
std::uint64_t* Unused; // previously BStoreLimit
ULONG MuiGeneration;
ULONG IsImpersonating;
std::uint64_t* NlsCache;
std::uint64_t* pShimData;
ULONG HeapData;
EmulatorTraits<Emu64>::HANDLE CurrentTransactionHandle;
EMULATOR_CAST(void*, PTEB_ACTIVE_FRAME) ActiveFrame;
std::uint64_t* FlsData;
std::uint64_t* PreferredLanguages;
std::uint64_t* UserPrefLanguages;
std::uint64_t* MergedPrefLanguages;
ULONG MuiImpersonation;
TEB_CROSS_TEB_FLAGS_UNION CrossTebFlags;
TEB_SAME_TEB_FLAGS_UNION SameTebFlags;
std::uint64_t* TxnScopeEnterCallback;
std::uint64_t* TxnScopeExitCallback;
std::uint64_t* TxnScopeContext;
ULONG LockCount;
LONG WowTebOffset;
std::uint64_t* ResourceRetValue;
std::uint64_t* ReservedForWdf;
ULONGLONG ReservedForCrt;
GUID EffectiveContainerId;
ULONGLONG LastSleepCounter; // Win11
ULONG SpinCallCount;
ULONGLONG ExtendedFeatureDisableMask;
std::uint64_t* SchedulerSharedDataSlot; // 24H2
std::uint64_t* HeapWalkContext;
EMU_GROUP_AFFINITY64 PrimaryGroupAffinity;
ARRAY_CONTAINER<ULONG, 2> Rcu;
} TEB64, *PTEB64;
#ifdef OS_WINDOWS
inline TEB64* NtCurrentTeb64(VOID)
{
return (TEB64*)__readgsqword(FIELD_OFFSET(EMU_NT_TIB64, Self));
}
#endif
#pragma pack(push, 4)
typedef struct _KSYSTEM_TIME
{
ULONG LowPart;
LONG High1Time;
LONG High2Time;
} KSYSTEM_TIME, *PKSYSTEM_TIME;
#pragma pack(pop)
typedef enum _NT_PRODUCT_TYPE
{
NtProductWinNt = 1,
NtProductLanManNt,
NtProductServer
} NT_PRODUCT_TYPE, *PNT_PRODUCT_TYPE;
typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
{
StandardDesign,
NEC98x86,
EndAlternatives
} ALTERNATIVE_ARCHITECTURE_TYPE;
union KUSD_SHARED_DATA_FLAGS_UNION
{
ULONG SharedDataFlags;
struct
{
//
// The following bit fields are for the debugger only. Do not use.
// Use the bit definitions instead.
//
ULONG DbgErrorPortPresent : 1;
ULONG DbgElevationEnabled : 1;
ULONG DbgVirtEnabled : 1;
ULONG DbgInstallerDetectEnabled : 1;
ULONG DbgLkgEnabled : 1;
ULONG DbgDynProcessorEnabled : 1;
ULONG DbgConsoleBrokerEnabled : 1;
ULONG DbgSecureBootEnabled : 1;
ULONG DbgMultiSessionSku : 1;
ULONG DbgMultiUsersInSessionSku : 1;
ULONG DbgStateSeparationEnabled : 1;
ULONG DbgSplitTokenEnabled : 1;
ULONG DbgShadowAdminEnabled : 1;
ULONG SpareBits : 19;
};
};
union KUSD_TICK_COUNT_UNION
{
volatile KSYSTEM_TIME TickCount;
volatile std::uint64_t TickCountQuad;
struct
{
ULONG ReservedTickCountOverlay[3];
ULONG TickCountPad[1];
};
};
union KUSD_VIRTUALIZATION_FLAGS_UNION
{
UCHAR VirtualizationFlags;
};
union KUSD_MITIGATION_POLICIES_UNION
{
UCHAR MitigationPolicies;
struct
{
UCHAR NXSupportPolicy : 2;
UCHAR SEHValidationPolicy : 2;
UCHAR CurDirDevicesSkippedForDlls : 2;
UCHAR Reserved : 2;
};
};
union KUSD_QPC_DATA_UNION
{
USHORT QpcData;
struct
{
volatile UCHAR QpcBypassEnabled;
UCHAR QpcReserved;
};
};
#ifndef OS_WINDOWS
#define MAXIMUM_XSTATE_FEATURES 64
typedef struct _XSTATE_FEATURE {
ULONG Offset;
ULONG Size;
} XSTATE_FEATURE;
typedef struct _XSTATE_CONFIGURATION {
std::uint64_t EnabledFeatures;
std::uint64_t EnabledVolatileFeatures;
ULONG Size;
union {
ULONG ControlFlags;
struct {
ULONG OptimizedSave : 1;
ULONG CompactionEnabled : 1;
ULONG Reserved1 : 30;
};
};
XSTATE_FEATURE Features[MAXIMUM_XSTATE_FEATURES];
std::uint64_t EnabledSupervisorFeatures;
std::uint64_t AlignedFeatures;
std::uint64_t AllFeatureSize;
ULONG AllFeatures[MAXIMUM_XSTATE_FEATURES];
} XSTATE_CONFIGURATION, *PXSTATE_CONFIGURATION;
#endif
typedef struct _KUSER_SHARED_DATA64
{
ULONG TickCountLowDeprecated;
ULONG TickCountMultiplier;
volatile KSYSTEM_TIME InterruptTime;
volatile KSYSTEM_TIME SystemTime;
volatile KSYSTEM_TIME TimeZoneBias;
USHORT ImageNumberLow;
USHORT ImageNumberHigh;
ARRAY_CONTAINER<char16_t, 260> NtSystemRoot;
ULONG MaxStackTraceDepth;
ULONG CryptoExponent;
ULONG TimeZoneId;
ULONG LargePageMinimum;
ULONG AitSamplingValue;
ULONG AppCompatFlag;
ULONGLONG RNGSeedVersion;
ULONG GlobalValidationRunlevel;
volatile LONG TimeZoneBiasStamp;
ULONG NtBuildNumber;
NT_PRODUCT_TYPE NtProductType;
BOOLEAN ProductTypeIsValid;
BOOLEAN Reserved0;
USHORT NativeProcessorArchitecture;
ULONG NtMajorVersion;
ULONG NtMinorVersion;
ARRAY_CONTAINER<BOOLEAN, PROCESSOR_FEATURE_MAX> ProcessorFeatures;
ULONG Reserved1;
ULONG Reserved3;
volatile ULONG TimeSlip;
ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
ULONG BootId;
LARGE_INTEGER SystemExpirationDate;
ULONG SuiteMask;
BOOLEAN KdDebuggerEnabled;
KUSD_MITIGATION_POLICIES_UNION MitigationPolicies;
USHORT CyclesPerYield;
volatile ULONG ActiveConsoleId;
volatile ULONG DismountCount;
ULONG ComPlusPackage;
ULONG LastSystemRITEventTickCount;
ULONG NumberOfPhysicalPages;
BOOLEAN SafeBootMode;
KUSD_VIRTUALIZATION_FLAGS_UNION VirtualizationFlags;
ARRAY_CONTAINER<UCHAR, 2> Reserved12;
KUSD_SHARED_DATA_FLAGS_UNION SharedDataFlags;
ULONG DataFlagsPad;
ULONGLONG TestRetInstruction;
LONGLONG QpcFrequency;
ULONG SystemCall;
ULONG Reserved2;
ULONGLONG FullNumberOfPhysicalPages;
ULONGLONG SystemCallPad;
KUSD_TICK_COUNT_UNION TickCount;
ULONG Cookie;
ULONG CookiePad;
LONGLONG ConsoleSessionForegroundProcessId;
ULONGLONG TimeUpdateLock;
ULONGLONG BaselineSystemTimeQpc;
ULONGLONG BaselineInterruptTimeQpc;
ULONGLONG QpcSystemTimeIncrement;
ULONGLONG QpcInterruptTimeIncrement;
UCHAR QpcSystemTimeIncrementShift;
UCHAR QpcInterruptTimeIncrementShift;
USHORT UnparkedProcessorCount;
ARRAY_CONTAINER<ULONG, 4> EnclaveFeatureMask;
ULONG TelemetryCoverageRound;
ARRAY_CONTAINER<USHORT, 16> UserModeGlobalLogger;
ULONG ImageFileExecutionOptions;
ULONG LangGenerationCount;
ULONGLONG Reserved4;
volatile ULONGLONG InterruptTimeBias;
volatile ULONGLONG QpcBias;
ULONG ActiveProcessorCount;
volatile UCHAR ActiveGroupCount;
UCHAR Reserved9;
KUSD_QPC_DATA_UNION QpcData;
LARGE_INTEGER TimeZoneBiasEffectiveStart;
LARGE_INTEGER TimeZoneBiasEffectiveEnd;
XSTATE_CONFIGURATION XState;
KSYSTEM_TIME FeatureConfigurationChangeStamp;
ULONG Spare;
std::uint64_t UserPointerAuthMask;
ARRAY_CONTAINER<ULONG, 210> Reserved10;
} KUSER_SHARED_DATA64, *PKUSER_SHARED_DATA64;
typedef struct _API_SET_NAMESPACE_ENTRY
{
ULONG Flags;
ULONG NameOffset;
ULONG NameLength;
ULONG HashedLength;
ULONG ValueOffset;
ULONG ValueCount;
} API_SET_NAMESPACE_ENTRY, *PAPI_SET_NAMESPACE_ENTRY;
typedef struct _API_SET_HASH_ENTRY
{
ULONG Hash;
ULONG Index;
} API_SET_HASH_ENTRY, *PAPI_SET_HASH_ENTRY;
typedef struct _API_SET_VALUE_ENTRY
{
ULONG Flags;
ULONG NameOffset;
ULONG NameLength;
ULONG ValueOffset;
ULONG ValueLength;
} API_SET_VALUE_ENTRY, *PAPI_SET_VALUE_ENTRY;
template <typename Traits>
struct PS_ATTRIBUTE
{
typename Traits::ULONG_PTR Attribute;
typename Traits::SIZE_T Size;
union
{
typename Traits::ULONG_PTR Value;
typename Traits::PVOID ValuePtr;
};
typename Traits::SIZE_T* ReturnLength;
};
template <typename Traits>
struct PS_ATTRIBUTE_LIST
{
typename Traits::SIZE_T TotalLength;
PS_ATTRIBUTE<Traits> Attributes[1];
};
typedef struct _SYSTEM_TIMEOFDAY_INFORMATION64
{
LARGE_INTEGER BootTime;
LARGE_INTEGER CurrentTime;
LARGE_INTEGER TimeZoneBias;
ULONG TimeZoneId;
ULONG Reserved;
ULONGLONG BootTimeBias;
ULONGLONG SleepTimeBias;
} SYSTEM_TIMEOFDAY_INFORMATION64, *PSYSTEM_TIMEOFDAY_INFORMATION64;
typedef struct _PROCESS_BASIC_INFORMATION64
{
NTSTATUS ExitStatus;
PPEB64 PebBaseAddress;
EMULATOR_CAST(std::uint64_t, KAFFINITY) AffinityMask;
EMULATOR_CAST(std::uint32_t, KPRIORITY) BasePriority;
EMULATOR_CAST(std::uint64_t, HANDLE) UniqueProcessId;
EMULATOR_CAST(std::uint64_t, HANDLE) InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION64, *PPROCESS_BASIC_INFORMATION64;
typedef struct _KERNEL_USER_TIMES
{
LARGE_INTEGER CreateTime;
LARGE_INTEGER ExitTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES;
struct THREAD_TLS_INFO
{
ULONG Flags;
union
{
EmulatorTraits<Emu64>::PVOID* TlsVector;
EmulatorTraits<Emu64>::PVOID TlsModulePointer;
};
EMULATOR_CAST(std::uint64_t, ULONG_PTR) ThreadId;
};
static_assert(sizeof(THREAD_TLS_INFO) == 0x18);
typedef enum _PROCESS_TLS_INFORMATION_TYPE
{
ProcessTlsReplaceIndex,
ProcessTlsReplaceVector,
MaxProcessTlsOperation
} PROCESS_TLS_INFORMATION_TYPE, *PPROCESS_TLS_INFORMATION_TYPE;
struct PROCESS_TLS_INFO
{
ULONG Unknown;
PROCESS_TLS_INFORMATION_TYPE TlsRequest;
ULONG ThreadDataCount;
union
{
ULONG TlsIndex;
ULONG TlsVectorLength;
};
THREAD_TLS_INFO ThreadData[1];
};
static_assert(sizeof(PROCESS_TLS_INFO) - sizeof(THREAD_TLS_INFO) == 0x10);

View File

@@ -0,0 +1,131 @@
#pragma once
#define PAGE_EXECUTE 0x10
#define PAGE_EXECUTE_READ 0x20
#define PAGE_EXECUTE_READWRITE 0x40
#define PAGE_EXECUTE_WRITECOPY 0x80
#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02
#define PAGE_READWRITE 0x04
#define PAGE_WRITECOPY 0x08
#define PAGE_TARGETS_INVALID 0x40000000
#define PAGE_TARGETS_NO_UPDATE 0x40000000
#define PAGE_GUARD 0x100
#define PAGE_NOCACHE 0x200
#define PAGE_WRITECOMBINE 0x400
#define MEM_COMMIT 0x00001000
#define MEM_RESERVE 0x00002000
#define MEM_DECOMMIT 0x00004000
#define MEM_RELEASE 0x00008000
#define MEM_FREE 0x00010000
#define MEM_PRIVATE 0x00020000
#define MEM_MAPPED 0x00040000
#define MEM_RESET 0x00080000
#define MEM_TOP_DOWN 0x00100000
#define MEM_WRITE_WATCH 0x00200000
#define MEM_PHYSICAL 0x00400000
#define MEM_ROTATE 0x00800000
#define MEM_DIFFERENT_IMAGE_BASE_OK 0x00800000
#define MEM_RESET_UNDO 0x01000000
#define MEM_LARGE_PAGES 0x20000000
#define MEM_DOS_LIM 0x40000000
#define MEM_4MB_PAGES 0x80000000
#define MEM_64K_PAGES (MEM_LARGE_PAGES | MEM_PHYSICAL)
typedef enum _MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation, // q: MEMORY_BASIC_INFORMATION
MemoryWorkingSetInformation, // q: MEMORY_WORKING_SET_INFORMATION
MemoryMappedFilenameInformation, // q: UNICODE_STRING
MemoryRegionInformation, // q: MEMORY_REGION_INFORMATION
MemoryWorkingSetExInformation, // q: MEMORY_WORKING_SET_EX_INFORMATION // since VISTA
MemorySharedCommitInformation, // q: MEMORY_SHARED_COMMIT_INFORMATION // since WIN8
MemoryImageInformation, // q: MEMORY_IMAGE_INFORMATION
MemoryRegionInformationEx, // MEMORY_REGION_INFORMATION
MemoryPrivilegedBasicInformation, // MEMORY_BASIC_INFORMATION
MemoryEnclaveImageInformation, // MEMORY_ENCLAVE_IMAGE_INFORMATION // since REDSTONE3
MemoryBasicInformationCapped, // 10
MemoryPhysicalContiguityInformation, // MEMORY_PHYSICAL_CONTIGUITY_INFORMATION // since 20H1
MemoryBadInformation, // since WIN11
MemoryBadInformationAllProcesses, // since 22H1
MemoryImageExtensionInformation, // since 24H2
MaxMemoryInfoClass
} MEMORY_INFORMATION_CLASS;
typedef enum _SECTION_INHERIT
{
ViewShare = 1,
ViewUnmap = 2
} SECTION_INHERIT;
typedef struct DECLSPEC_ALIGN(16) _EMU_MEMORY_BASIC_INFORMATION64
{
void* BaseAddress;
void* AllocationBase;
DWORD AllocationProtect;
WORD PartitionId;
std::int64_t RegionSize;
DWORD State;
DWORD Protect;
DWORD Type;
} EMU_MEMORY_BASIC_INFORMATION64, *PEMU_MEMORY_BASIC_INFORMATION64;
typedef struct _MEMORY_IMAGE_INFORMATION64
{
void* ImageBase;
std::int64_t SizeOfImage;
union
{
ULONG ImageFlags;
struct
{
ULONG ImagePartialMap : 1;
ULONG ImageNotExecutable : 1;
ULONG ImageSigningLevel : 4; // REDSTONE3
ULONG ImageExtensionPresent : 1; // since 24H2
ULONG Reserved : 25;
};
};
} MEMORY_IMAGE_INFORMATION64, *PMEMORY_IMAGE_INFORMATION64;
typedef struct _MEMORY_REGION_INFORMATION
{
void* AllocationBase;
ULONG AllocationProtect;
union
{
ULONG RegionType;
struct
{
ULONG Private : 1;
ULONG MappedDataFile : 1;
ULONG MappedImage : 1;
ULONG MappedPageFile : 1;
ULONG MappedPhysical : 1;
ULONG DirectMapped : 1;
ULONG SoftwareEnclave : 1; // REDSTONE3
ULONG PageSize64K : 1;
ULONG PlaceholderReservation : 1; // REDSTONE4
ULONG MappedAwe : 1; // 21H1
ULONG MappedWriteWatch : 1;
ULONG PageSizeLarge : 1;
ULONG PageSizeHuge : 1;
ULONG Reserved : 19;
};
};
std::int64_t RegionSize;
std::int64_t CommitSize;
DWORD64 PartitionId; // 19H1
DWORD64 NodePreference; // 20H1
} MEMORY_REGION_INFORMATION64, *PMEMORY_REGION_INFORMATION64;

View File

@@ -0,0 +1,8 @@
#pragma once
template <typename Traits>
struct EMU_WSABUF
{
ULONG len;
EMULATOR_CAST(typename Traits::PVOID, CHAR*) buf;
};

View File

@@ -0,0 +1,46 @@
#pragma once
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4201) // nameless struct/union
#pragma warning(disable: 4702) // unreachable code
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#include "compiler.hpp"
#include "primitives.hpp"
#include "traits.hpp"
#include "unicode.hpp"
#include "status.hpp"
#include "process.hpp"
#include "kernel_mapped.hpp"
#include "memory.hpp"
#include "file_management.hpp"
#include "win_pefile.hpp"
#include "synchronisation.hpp"
#include "registry.hpp"
#include "network.hpp"
#include "threading.hpp"
#ifdef OS_WINDOWS
#pragma comment(lib, "ntdll")
extern "C" {
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQuerySystemInformationEx(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
_In_ ULONG InputBufferLength,
_Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
);
}
#pragma warning(pop)
#else
#pragma GCC diagnostic pop
#endif

View File

@@ -0,0 +1,62 @@
#pragma once
#include <cstdint>
#ifdef OS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#include "winnt.h"
#else
#define DWORD std::uint32_t
using LONG = std::int32_t;
using ULONG = DWORD;
using DWORD64 = std::uint64_t;
using ULONGLONG = DWORD64;
using LONGLONG = std::int64_t;
typedef union _ULARGE_INTEGER
{
struct
{
DWORD LowPart;
DWORD HighPart;
};
ULONGLONG QuadPart;
} ULARGE_INTEGER;
typedef union _LARGE_INTEGER
{
struct
{
DWORD LowPart;
LONG HighPart;
};
LONGLONG QuadPart;
} LARGE_INTEGER;
using BYTE = std::uint8_t;
#define CHAR BYTE
#endif
using WORD = std::uint16_t;
#define UCHAR unsigned char
#define BOOLEAN bool
using CSHORT = short;
using USHORT = WORD;
#define DUMMYSTRUCTNAME
#ifndef TRUE
#define TRUE true
#define FALSE false
#endif

View File

@@ -0,0 +1,890 @@
#pragma once
#define CONTEXT_X86_MAIN 0x00010000
#define CONTEXT_AMD64_MAIN 0x100000
#define CONTEXT_CONTROL_32 (CONTEXT_X86_MAIN | 0x1L)
#define CONTEXT_CONTROL_64 (CONTEXT_AMD64_MAIN | 0x1L)
#define CONTEXT_INTEGER_32 (CONTEXT_X86_MAIN | 0x2L)
#define CONTEXT_INTEGER_64 (CONTEXT_AMD64_MAIN | 0x2L)
#define CONTEXT_SEGMENTS_32 (CONTEXT_X86_MAIN | 0x4L)
#define CONTEXT_SEGMENTS_64 (CONTEXT_AMD64_MAIN | 0x4L)
#define CONTEXT_FLOATING_POINT_32 (CONTEXT_X86_MAIN | 0x8L)
#define CONTEXT_FLOATING_POINT_64 (CONTEXT_AMD64_MAIN | 0x8L)
#define CONTEXT_DEBUG_REGISTERS_32 (CONTEXT_X86_MAIN | 0x10L)
#define CONTEXT_DEBUG_REGISTERS_64 (CONTEXT_AMD64_MAIN | 0x10L)
#define CONTEXT_XSTATE_32 (CONTEXT_X86_MAIN | 0x20L)
#define CONTEXT_XSTATE_64 (CONTEXT_AMD64_MAIN | 0x20L)
#define CONTEXT64_ALL (CONTEXT_CONTROL_64 | CONTEXT_INTEGER_64 | CONTEXT_SEGMENTS_64 | \
CONTEXT_FLOATING_POINT_64 | CONTEXT_DEBUG_REGISTERS_64)
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation, // q: SYSTEM_BASIC_INFORMATION
SystemProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION
SystemPerformanceInformation, // q: SYSTEM_PERFORMANCE_INFORMATION
SystemTimeOfDayInformation, // q: SYSTEM_TIMEOFDAY_INFORMATION
SystemPathInformation, // not implemented
SystemProcessInformation, // q: SYSTEM_PROCESS_INFORMATION
SystemCallCountInformation, // q: SYSTEM_CALL_COUNT_INFORMATION
SystemDeviceInformation, // q: SYSTEM_DEVICE_INFORMATION
SystemProcessorPerformanceInformation, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION (EX in: USHORT ProcessorGroup)
SystemFlagsInformation, // q: SYSTEM_FLAGS_INFORMATION
SystemCallTimeInformation, // not implemented // SYSTEM_CALL_TIME_INFORMATION // 10
SystemModuleInformation, // q: RTL_PROCESS_MODULES
SystemLocksInformation, // q: RTL_PROCESS_LOCKS
SystemStackTraceInformation, // q: RTL_PROCESS_BACKTRACES
SystemPagedPoolInformation, // not implemented
SystemNonPagedPoolInformation, // not implemented
SystemHandleInformation, // q: SYSTEM_HANDLE_INFORMATION
SystemObjectInformation, // q: SYSTEM_OBJECTTYPE_INFORMATION mixed with SYSTEM_OBJECT_INFORMATION
SystemPageFileInformation, // q: SYSTEM_PAGEFILE_INFORMATION
SystemVdmInstemulInformation, // q: SYSTEM_VDM_INSTEMUL_INFO
SystemVdmBopInformation, // not implemented // 20
SystemFileCacheInformation,
// q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemCache)
SystemPoolTagInformation, // q: SYSTEM_POOLTAG_INFORMATION
SystemInterruptInformation, // q: SYSTEM_INTERRUPT_INFORMATION (EX in: USHORT ProcessorGroup)
SystemDpcBehaviorInformation,
// q: SYSTEM_DPC_BEHAVIOR_INFORMATION; s: SYSTEM_DPC_BEHAVIOR_INFORMATION (requires SeLoadDriverPrivilege)
SystemFullMemoryInformation, // not implemented // SYSTEM_MEMORY_USAGE_INFORMATION
SystemLoadGdiDriverInformation, // s (kernel-mode only)
SystemUnloadGdiDriverInformation, // s (kernel-mode only)
SystemTimeAdjustmentInformation,
// q: SYSTEM_QUERY_TIME_ADJUST_INFORMATION; s: SYSTEM_SET_TIME_ADJUST_INFORMATION (requires SeSystemtimePrivilege)
SystemSummaryMemoryInformation, // not implemented // SYSTEM_MEMORY_USAGE_INFORMATION
SystemMirrorMemoryInformation,
// s (requires license value "Kernel-MemoryMirroringSupported") (requires SeShutdownPrivilege) // 30
SystemPerformanceTraceInformation, // q; s: (type depends on EVENT_TRACE_INFORMATION_CLASS)
SystemObsolete0, // not implemented
SystemExceptionInformation, // q: SYSTEM_EXCEPTION_INFORMATION
SystemCrashDumpStateInformation, // s: SYSTEM_CRASH_DUMP_STATE_INFORMATION (requires SeDebugPrivilege)
SystemKernelDebuggerInformation, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION
SystemContextSwitchInformation, // q: SYSTEM_CONTEXT_SWITCH_INFORMATION
SystemRegistryQuotaInformation, // q: SYSTEM_REGISTRY_QUOTA_INFORMATION; s (requires SeIncreaseQuotaPrivilege)
SystemExtendServiceTableInformation, // s (requires SeLoadDriverPrivilege) // loads win32k only
SystemPrioritySeperation, // s (requires SeTcbPrivilege)
SystemVerifierAddDriverInformation, // s (requires SeDebugPrivilege) // 40
SystemVerifierRemoveDriverInformation, // s (requires SeDebugPrivilege)
SystemProcessorIdleInformation, // q: SYSTEM_PROCESSOR_IDLE_INFORMATION (EX in: USHORT ProcessorGroup)
SystemLegacyDriverInformation, // q: SYSTEM_LEGACY_DRIVER_INFORMATION
SystemCurrentTimeZoneInformation, // q; s: RTL_TIME_ZONE_INFORMATION
SystemLookasideInformation, // q: SYSTEM_LOOKASIDE_INFORMATION
SystemTimeSlipNotification, // s: HANDLE (NtCreateEvent) (requires SeSystemtimePrivilege)
SystemSessionCreate, // not implemented
SystemSessionDetach, // not implemented
SystemSessionInformation, // not implemented (SYSTEM_SESSION_INFORMATION)
SystemRangeStartInformation, // q: SYSTEM_RANGE_START_INFORMATION // 50
SystemVerifierInformation, // q: SYSTEM_VERIFIER_INFORMATION; s (requires SeDebugPrivilege)
SystemVerifierThunkExtend, // s (kernel-mode only)
SystemSessionProcessInformation, // q: SYSTEM_SESSION_PROCESS_INFORMATION
SystemLoadGdiDriverInSystemSpace,
// s: SYSTEM_GDI_DRIVER_INFORMATION (kernel-mode only) (same as SystemLoadGdiDriverInformation)
SystemNumaProcessorMap, // q: SYSTEM_NUMA_INFORMATION
SystemPrefetcherInformation, // q; s: PREFETCHER_INFORMATION // PfSnQueryPrefetcherInformation
SystemExtendedProcessInformation, // q: SYSTEM_PROCESS_INFORMATION
SystemRecommendedSharedDataAlignment, // q: ULONG // KeGetRecommendedSharedDataAlignment
SystemComPlusPackage, // q; s: ULONG
SystemNumaAvailableMemory, // q: SYSTEM_NUMA_INFORMATION // 60
SystemProcessorPowerInformation, // q: SYSTEM_PROCESSOR_POWER_INFORMATION (EX in: USHORT ProcessorGroup)
SystemEmulationBasicInformation, // q: SYSTEM_BASIC_INFORMATION
SystemEmulationProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION
SystemExtendedHandleInformation, // q: SYSTEM_HANDLE_INFORMATION_EX
SystemLostDelayedWriteInformation, // q: ULONG
SystemBigPoolInformation, // q: SYSTEM_BIGPOOL_INFORMATION
SystemSessionPoolTagInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION
SystemSessionMappedViewInformation, // q: SYSTEM_SESSION_MAPPED_VIEW_INFORMATION
SystemHotpatchInformation, // q; s: SYSTEM_HOTPATCH_CODE_INFORMATION
SystemObjectSecurityMode, // q: ULONG // 70
SystemWatchdogTimerHandler, // s: SYSTEM_WATCHDOG_HANDLER_INFORMATION // (kernel-mode only)
SystemWatchdogTimerInformation, // q: SYSTEM_WATCHDOG_TIMER_INFORMATION // (kernel-mode only)
SystemLogicalProcessorInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION (EX in: USHORT ProcessorGroup)
SystemWow64SharedInformationObsolete, // not implemented
SystemRegisterFirmwareTableInformationHandler, // s: SYSTEM_FIRMWARE_TABLE_HANDLER // (kernel-mode only)
SystemFirmwareTableInformation, // SYSTEM_FIRMWARE_TABLE_INFORMATION
SystemModuleInformationEx, // q: RTL_PROCESS_MODULE_INFORMATION_EX
SystemVerifierTriageInformation, // not implemented
SystemSuperfetchInformation, // q; s: SUPERFETCH_INFORMATION // PfQuerySuperfetchInformation
SystemMemoryListInformation,
// q: SYSTEM_MEMORY_LIST_INFORMATION; s: SYSTEM_MEMORY_LIST_COMMAND (requires SeProfileSingleProcessPrivilege) // 80
SystemFileCacheInformationEx,
// q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (same as SystemFileCacheInformation)
SystemThreadPriorityClientIdInformation,
// s: SYSTEM_THREAD_CID_PRIORITY_INFORMATION (requires SeIncreaseBasePriorityPrivilege)
SystemProcessorIdleCycleTimeInformation,
// q: SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION[] (EX in: USHORT ProcessorGroup)
SystemVerifierCancellationInformation,
// SYSTEM_VERIFIER_CANCELLATION_INFORMATION // name:wow64:whNT32QuerySystemVerifierCancellationInformation
SystemProcessorPowerInformationEx, // not implemented
SystemRefTraceInformation, // q; s: SYSTEM_REF_TRACE_INFORMATION // ObQueryRefTraceInformation
SystemSpecialPoolInformation,
// q; s: SYSTEM_SPECIAL_POOL_INFORMATION (requires SeDebugPrivilege) // MmSpecialPoolTag, then MmSpecialPoolCatchOverruns != 0
SystemProcessIdInformation, // q: SYSTEM_PROCESS_ID_INFORMATION
SystemErrorPortInformation, // s (requires SeTcbPrivilege)
SystemBootEnvironmentInformation, // q: SYSTEM_BOOT_ENVIRONMENT_INFORMATION // 90
SystemHypervisorInformation, // q: SYSTEM_HYPERVISOR_QUERY_INFORMATION
SystemVerifierInformationEx, // q; s: SYSTEM_VERIFIER_INFORMATION_EX
SystemTimeZoneInformation, // q; s: RTL_TIME_ZONE_INFORMATION (requires SeTimeZonePrivilege)
SystemImageFileExecutionOptionsInformation,
// s: SYSTEM_IMAGE_FILE_EXECUTION_OPTIONS_INFORMATION (requires SeTcbPrivilege)
SystemCoverageInformation,
// q: COVERAGE_MODULES s: COVERAGE_MODULE_REQUEST // ExpCovQueryInformation (requires SeDebugPrivilege)
SystemPrefetchPatchInformation, // SYSTEM_PREFETCH_PATCH_INFORMATION
SystemVerifierFaultsInformation, // s: SYSTEM_VERIFIER_FAULTS_INFORMATION (requires SeDebugPrivilege)
SystemSystemPartitionInformation, // q: SYSTEM_SYSTEM_PARTITION_INFORMATION
SystemSystemDiskInformation, // q: SYSTEM_SYSTEM_DISK_INFORMATION
SystemProcessorPerformanceDistribution,
// q: SYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION (EX in: USHORT ProcessorGroup) // 100
SystemNumaProximityNodeInformation, // q; s: SYSTEM_NUMA_PROXIMITY_MAP
SystemDynamicTimeZoneInformation, // q; s: RTL_DYNAMIC_TIME_ZONE_INFORMATION (requires SeTimeZonePrivilege)
SystemCodeIntegrityInformation, // q: SYSTEM_CODEINTEGRITY_INFORMATION // SeCodeIntegrityQueryInformation
SystemProcessorMicrocodeUpdateInformation, // s: SYSTEM_PROCESSOR_MICROCODE_UPDATE_INFORMATION
SystemProcessorBrandString, // q: CHAR[] // HaliQuerySystemInformation -> HalpGetProcessorBrandString, info class 23
SystemVirtualAddressInformation,
// q: SYSTEM_VA_LIST_INFORMATION[]; s: SYSTEM_VA_LIST_INFORMATION[] (requires SeIncreaseQuotaPrivilege) // MmQuerySystemVaInformation
SystemLogicalProcessorAndGroupInformation,
// q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX (EX in: LOGICAL_PROCESSOR_RELATIONSHIP RelationshipType) // since WIN7 // KeQueryLogicalProcessorRelationship
SystemProcessorCycleTimeInformation, // q: SYSTEM_PROCESSOR_CYCLE_TIME_INFORMATION[] (EX in: USHORT ProcessorGroup)
SystemStoreInformation,
// q; s: SYSTEM_STORE_INFORMATION (requires SeProfileSingleProcessPrivilege) // SmQueryStoreInformation
SystemRegistryAppendString, // s: SYSTEM_REGISTRY_APPEND_STRING_PARAMETERS // 110
SystemAitSamplingValue, // s: ULONG (requires SeProfileSingleProcessPrivilege)
SystemVhdBootInformation, // q: SYSTEM_VHD_BOOT_INFORMATION
SystemCpuQuotaInformation, // q; s: PS_CPU_QUOTA_QUERY_INFORMATION
SystemNativeBasicInformation, // q: SYSTEM_BASIC_INFORMATION
SystemErrorPortTimeouts, // SYSTEM_ERROR_PORT_TIMEOUTS
SystemLowPriorityIoInformation, // q: SYSTEM_LOW_PRIORITY_IO_INFORMATION
SystemTpmBootEntropyInformation, // q: TPM_BOOT_ENTROPY_NT_RESULT // ExQueryTpmBootEntropyInformation
SystemVerifierCountersInformation, // q: SYSTEM_VERIFIER_COUNTERS_INFORMATION
SystemPagedPoolInformationEx,
// q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypePagedPool)
SystemSystemPtesInformationEx,
// q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemPtes) // 120
SystemNodeDistanceInformation, // q: USHORT[4*NumaNodes] // (EX in: USHORT NodeNumber)
SystemAcpiAuditInformation,
// q: SYSTEM_ACPI_AUDIT_INFORMATION // HaliQuerySystemInformation -> HalpAuditQueryResults, info class 26
SystemBasicPerformanceInformation,
// q: SYSTEM_BASIC_PERFORMANCE_INFORMATION // name:wow64:whNtQuerySystemInformation_SystemBasicPerformanceInformation
SystemQueryPerformanceCounterInformation, // q: SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION // since WIN7 SP1
SystemSessionBigPoolInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION // since WIN8
SystemBootGraphicsInformation, // q; s: SYSTEM_BOOT_GRAPHICS_INFORMATION (kernel-mode only)
SystemScrubPhysicalMemoryInformation, // q; s: MEMORY_SCRUB_INFORMATION
SystemBadPageInformation, // SYSTEM_BAD_PAGE_INFORMATION
SystemProcessorProfileControlArea, // q; s: SYSTEM_PROCESSOR_PROFILE_CONTROL_AREA
SystemCombinePhysicalMemoryInformation,
// s: MEMORY_COMBINE_INFORMATION, MEMORY_COMBINE_INFORMATION_EX, MEMORY_COMBINE_INFORMATION_EX2 // 130
SystemEntropyInterruptTimingInformation, // q; s: SYSTEM_ENTROPY_TIMING_INFORMATION
SystemConsoleInformation, // q; s: SYSTEM_CONSOLE_INFORMATION
SystemPlatformBinaryInformation, // q: SYSTEM_PLATFORM_BINARY_INFORMATION (requires SeTcbPrivilege)
SystemPolicyInformation, // q: SYSTEM_POLICY_INFORMATION (Warbird/Encrypt/Decrypt/Execute)
SystemHypervisorProcessorCountInformation, // q: SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION
SystemDeviceDataInformation, // q: SYSTEM_DEVICE_DATA_INFORMATION
SystemDeviceDataEnumerationInformation, // q: SYSTEM_DEVICE_DATA_INFORMATION
SystemMemoryTopologyInformation, // q: SYSTEM_MEMORY_TOPOLOGY_INFORMATION
SystemMemoryChannelInformation, // q: SYSTEM_MEMORY_CHANNEL_INFORMATION
SystemBootLogoInformation, // q: SYSTEM_BOOT_LOGO_INFORMATION // 140
SystemProcessorPerformanceInformationEx,
// q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_EX // (EX in: USHORT ProcessorGroup) // since WINBLUE
SystemCriticalProcessErrorLogInformation,
SystemSecureBootPolicyInformation, // q: SYSTEM_SECUREBOOT_POLICY_INFORMATION
SystemPageFileInformationEx, // q: SYSTEM_PAGEFILE_INFORMATION_EX
SystemSecureBootInformation, // q: SYSTEM_SECUREBOOT_INFORMATION
SystemEntropyInterruptTimingRawInformation,
SystemPortableWorkspaceEfiLauncherInformation, // q: SYSTEM_PORTABLE_WORKSPACE_EFI_LAUNCHER_INFORMATION
SystemFullProcessInformation,
// q: SYSTEM_PROCESS_INFORMATION with SYSTEM_PROCESS_INFORMATION_EXTENSION (requires admin)
SystemKernelDebuggerInformationEx, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX
SystemBootMetadataInformation, // 150
SystemSoftRebootInformation, // q: ULONG
SystemElamCertificateInformation, // s: SYSTEM_ELAM_CERTIFICATE_INFORMATION
SystemOfflineDumpConfigInformation, // q: OFFLINE_CRASHDUMP_CONFIGURATION_TABLE_V2
SystemProcessorFeaturesInformation, // q: SYSTEM_PROCESSOR_FEATURES_INFORMATION
SystemRegistryReconciliationInformation, // s: NULL (requires admin) (flushes registry hives)
SystemEdidInformation, // q: SYSTEM_EDID_INFORMATION
SystemManufacturingInformation, // q: SYSTEM_MANUFACTURING_INFORMATION // since THRESHOLD
SystemEnergyEstimationConfigInformation, // q: SYSTEM_ENERGY_ESTIMATION_CONFIG_INFORMATION
SystemHypervisorDetailInformation, // q: SYSTEM_HYPERVISOR_DETAIL_INFORMATION
SystemProcessorCycleStatsInformation,
// q: SYSTEM_PROCESSOR_CYCLE_STATS_INFORMATION (EX in: USHORT ProcessorGroup) // 160
SystemVmGenerationCountInformation,
SystemTrustedPlatformModuleInformation, // q: SYSTEM_TPM_INFORMATION
SystemKernelDebuggerFlags, // SYSTEM_KERNEL_DEBUGGER_FLAGS
SystemCodeIntegrityPolicyInformation, // q; s: SYSTEM_CODEINTEGRITYPOLICY_INFORMATION
SystemIsolatedUserModeInformation, // q: SYSTEM_ISOLATED_USER_MODE_INFORMATION
SystemHardwareSecurityTestInterfaceResultsInformation,
SystemSingleModuleInformation, // q: SYSTEM_SINGLE_MODULE_INFORMATION
SystemAllowedCpuSetsInformation, // s: SYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION
SystemVsmProtectionInformation, // q: SYSTEM_VSM_PROTECTION_INFORMATION (previously SystemDmaProtectionInformation)
SystemInterruptCpuSetsInformation, // q: SYSTEM_INTERRUPT_CPU_SET_INFORMATION // 170
SystemSecureBootPolicyFullInformation, // q: SYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION
SystemCodeIntegrityPolicyFullInformation,
SystemAffinitizedInterruptProcessorInformation, // (requires SeIncreaseBasePriorityPrivilege)
SystemRootSiloInformation, // q: SYSTEM_ROOT_SILO_INFORMATION
SystemCpuSetInformation, // q: SYSTEM_CPU_SET_INFORMATION // since THRESHOLD2
SystemCpuSetTagInformation, // q: SYSTEM_CPU_SET_TAG_INFORMATION
SystemWin32WerStartCallout,
SystemSecureKernelProfileInformation, // q: SYSTEM_SECURE_KERNEL_HYPERGUARD_PROFILE_INFORMATION
SystemCodeIntegrityPlatformManifestInformation,
// q: SYSTEM_SECUREBOOT_PLATFORM_MANIFEST_INFORMATION // since REDSTONE
SystemInterruptSteeringInformation,
// q: in: SYSTEM_INTERRUPT_STEERING_INFORMATION_INPUT, out: SYSTEM_INTERRUPT_STEERING_INFORMATION_OUTPUT // NtQuerySystemInformationEx // 180
SystemSupportedProcessorArchitectures,
// p: in opt: HANDLE, out: SYSTEM_SUPPORTED_PROCESSOR_ARCHITECTURES_INFORMATION[] // NtQuerySystemInformationEx
SystemMemoryUsageInformation, // q: SYSTEM_MEMORY_USAGE_INFORMATION
SystemCodeIntegrityCertificateInformation, // q: SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION
SystemPhysicalMemoryInformation, // q: SYSTEM_PHYSICAL_MEMORY_INFORMATION // since REDSTONE2
SystemControlFlowTransition, // (Warbird/Encrypt/Decrypt/Execute)
SystemKernelDebuggingAllowed, // s: ULONG
SystemActivityModerationExeState, // SYSTEM_ACTIVITY_MODERATION_EXE_STATE
SystemActivityModerationUserSettings, // SYSTEM_ACTIVITY_MODERATION_USER_SETTINGS
SystemCodeIntegrityPoliciesFullInformation,
SystemCodeIntegrityUnlockInformation, // SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION // 190
SystemIntegrityQuotaInformation,
SystemFlushInformation, // q: SYSTEM_FLUSH_INFORMATION
SystemProcessorIdleMaskInformation, // q: ULONG_PTR[ActiveGroupCount] // since REDSTONE3
SystemSecureDumpEncryptionInformation,
SystemWriteConstraintInformation, // SYSTEM_WRITE_CONSTRAINT_INFORMATION
SystemKernelVaShadowInformation, // SYSTEM_KERNEL_VA_SHADOW_INFORMATION
SystemHypervisorSharedPageInformation, // SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION // since REDSTONE4
SystemFirmwareBootPerformanceInformation,
SystemCodeIntegrityVerificationInformation, // SYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION
SystemFirmwarePartitionInformation, // SYSTEM_FIRMWARE_PARTITION_INFORMATION // 200
SystemSpeculationControlInformation,
// SYSTEM_SPECULATION_CONTROL_INFORMATION // (CVE-2017-5715) REDSTONE3 and above.
SystemDmaGuardPolicyInformation, // SYSTEM_DMA_GUARD_POLICY_INFORMATION
SystemEnclaveLaunchControlInformation, // SYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION
SystemWorkloadAllowedCpuSetsInformation, // SYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION // since REDSTONE5
SystemCodeIntegrityUnlockModeInformation, // SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION
SystemLeapSecondInformation, // SYSTEM_LEAP_SECOND_INFORMATION
SystemFlags2Information, // q: SYSTEM_FLAGS_INFORMATION
SystemSecurityModelInformation, // SYSTEM_SECURITY_MODEL_INFORMATION // since 19H1
SystemCodeIntegritySyntheticCacheInformation,
SystemFeatureConfigurationInformation,
// q: in: SYSTEM_FEATURE_CONFIGURATION_QUERY, out: SYSTEM_FEATURE_CONFIGURATION_INFORMATION; s: SYSTEM_FEATURE_CONFIGURATION_UPDATE // NtQuerySystemInformationEx // since 20H1 // 210
SystemFeatureConfigurationSectionInformation,
// q: in: SYSTEM_FEATURE_CONFIGURATION_SECTIONS_REQUEST, out: SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION // NtQuerySystemInformationEx
SystemFeatureUsageSubscriptionInformation,
// q: SYSTEM_FEATURE_USAGE_SUBSCRIPTION_DETAILS; s: SYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE
SystemSecureSpeculationControlInformation, // SECURE_SPECULATION_CONTROL_INFORMATION
SystemSpacesBootInformation, // since 20H2
SystemFwRamdiskInformation, // SYSTEM_FIRMWARE_RAMDISK_INFORMATION
SystemWheaIpmiHardwareInformation,
SystemDifSetRuleClassInformation, // SYSTEM_DIF_VOLATILE_INFORMATION
SystemDifClearRuleClassInformation,
SystemDifApplyPluginVerificationOnDriver, // SYSTEM_DIF_PLUGIN_DRIVER_INFORMATION
SystemDifRemovePluginVerificationOnDriver, // SYSTEM_DIF_PLUGIN_DRIVER_INFORMATION // 220
SystemShadowStackInformation, // SYSTEM_SHADOW_STACK_INFORMATION
SystemBuildVersionInformation,
// q: in: ULONG (LayerNumber), out: SYSTEM_BUILD_VERSION_INFORMATION // NtQuerySystemInformationEx // 222
SystemPoolLimitInformation, // SYSTEM_POOL_LIMIT_INFORMATION (requires SeIncreaseQuotaPrivilege)
SystemCodeIntegrityAddDynamicStore,
SystemCodeIntegrityClearDynamicStores,
SystemDifPoolTrackingInformation,
SystemPoolZeroingInformation, // q: SYSTEM_POOL_ZEROING_INFORMATION
SystemDpcWatchdogInformation, // q; s: SYSTEM_DPC_WATCHDOG_CONFIGURATION_INFORMATION
SystemDpcWatchdogInformation2, // q; s: SYSTEM_DPC_WATCHDOG_CONFIGURATION_INFORMATION_V2
SystemSupportedProcessorArchitectures2,
// q: in opt: HANDLE, out: SYSTEM_SUPPORTED_PROCESSOR_ARCHITECTURES_INFORMATION[] // NtQuerySystemInformationEx // 230
SystemSingleProcessorRelationshipInformation,
// q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX // (EX in: PROCESSOR_NUMBER Processor)
SystemXfgCheckFailureInformation, // q: SYSTEM_XFG_FAILURE_INFORMATION
SystemIommuStateInformation, // SYSTEM_IOMMU_STATE_INFORMATION // since 22H1
SystemHypervisorMinrootInformation, // SYSTEM_HYPERVISOR_MINROOT_INFORMATION
SystemHypervisorBootPagesInformation, // SYSTEM_HYPERVISOR_BOOT_PAGES_INFORMATION
SystemPointerAuthInformation, // SYSTEM_POINTER_AUTH_INFORMATION
SystemSecureKernelDebuggerInformation,
SystemOriginalImageFeatureInformation,
// q: in: SYSTEM_ORIGINAL_IMAGE_FEATURE_INFORMATION_INPUT, out: SYSTEM_ORIGINAL_IMAGE_FEATURE_INFORMATION_OUTPUT // NtQuerySystemInformationEx
SystemMemoryNumaInformation, // SYSTEM_MEMORY_NUMA_INFORMATION_INPUT, SYSTEM_MEMORY_NUMA_INFORMATION_OUTPUT
SystemMemoryNumaPerformanceInformation,
// SYSTEM_MEMORY_NUMA_PERFORMANCE_INFORMATION_INPUTSYSTEM_MEMORY_NUMA_PERFORMANCE_INFORMATION_INPUT, SYSTEM_MEMORY_NUMA_PERFORMANCE_INFORMATION_OUTPUT // since 24H2 // 240
SystemCodeIntegritySignedPoliciesFullInformation,
SystemSecureSecretsInformation,
SystemTrustedAppsRuntimeInformation, // SYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION
SystemBadPageInformationEx, // SYSTEM_BAD_PAGE_INFORMATION
SystemResourceDeadlockTimeout, // ULONG
SystemBreakOnContextUnwindFailureInformation, // ULONG (requires SeDebugPrivilege)
SystemOslRamdiskInformation, // SYSTEM_OSL_RAMDISK_INFORMATION
MaxSystemInfoClass
} SYSTEM_INFORMATION_CLASS;
#ifndef OS_WINDOWS
typedef enum _TOKEN_INFORMATION_CLASS
{
TokenUser = 1, // q: TOKEN_USER, SE_TOKEN_USER
TokenGroups, // q: TOKEN_GROUPS
TokenPrivileges, // q: TOKEN_PRIVILEGES
TokenOwner, // q; s: TOKEN_OWNER
TokenPrimaryGroup, // q; s: TOKEN_PRIMARY_GROUP
TokenDefaultDacl, // q; s: TOKEN_DEFAULT_DACL
TokenSource, // q: TOKEN_SOURCE
TokenType, // q: TOKEN_TYPE
TokenImpersonationLevel, // q: SECURITY_IMPERSONATION_LEVEL
TokenStatistics, // q: TOKEN_STATISTICS // 10
TokenRestrictedSids, // q: TOKEN_GROUPS
TokenSessionId, // q; s: ULONG (requires SeTcbPrivilege)
TokenGroupsAndPrivileges, // q: TOKEN_GROUPS_AND_PRIVILEGES
TokenSessionReference, // s: ULONG (requires SeTcbPrivilege)
TokenSandBoxInert, // q: ULONG
TokenAuditPolicy, // q; s: TOKEN_AUDIT_POLICY (requires SeSecurityPrivilege/SeTcbPrivilege)
TokenOrigin, // q; s: TOKEN_ORIGIN (requires SeTcbPrivilege)
TokenElevationType, // q: TOKEN_ELEVATION_TYPE
TokenLinkedToken, // q; s: TOKEN_LINKED_TOKEN (requires SeCreateTokenPrivilege)
TokenElevation, // q: TOKEN_ELEVATION // 20
TokenHasRestrictions, // q: ULONG
TokenAccessInformation, // q: TOKEN_ACCESS_INFORMATION
TokenVirtualizationAllowed, // q; s: ULONG (requires SeCreateTokenPrivilege)
TokenVirtualizationEnabled, // q; s: ULONG
TokenIntegrityLevel, // q; s: TOKEN_MANDATORY_LABEL
TokenUIAccess, // q; s: ULONG (requires SeTcbPrivilege)
TokenMandatoryPolicy, // q; s: TOKEN_MANDATORY_POLICY (requires SeTcbPrivilege)
TokenLogonSid, // q: TOKEN_GROUPS
TokenIsAppContainer, // q: ULONG // since WIN8
TokenCapabilities, // q: TOKEN_GROUPS // 30
TokenAppContainerSid, // q: TOKEN_APPCONTAINER_INFORMATION
TokenAppContainerNumber, // q: ULONG
TokenUserClaimAttributes, // q: CLAIM_SECURITY_ATTRIBUTES_INFORMATION
TokenDeviceClaimAttributes, // q: CLAIM_SECURITY_ATTRIBUTES_INFORMATION
TokenRestrictedUserClaimAttributes, // q: CLAIM_SECURITY_ATTRIBUTES_INFORMATION
TokenRestrictedDeviceClaimAttributes, // q: CLAIM_SECURITY_ATTRIBUTES_INFORMATION
TokenDeviceGroups, // q: TOKEN_GROUPS
TokenRestrictedDeviceGroups, // q: TOKEN_GROUPS
TokenSecurityAttributes, // q; s: TOKEN_SECURITY_ATTRIBUTES_[AND_OPERATION_]INFORMATION (requires SeTcbPrivilege)
TokenIsRestricted, // q: ULONG // 40
TokenProcessTrustLevel, // q: TOKEN_PROCESS_TRUST_LEVEL // since WINBLUE
TokenPrivateNameSpace, // q; s: ULONG (requires SeTcbPrivilege) // since THRESHOLD
TokenSingletonAttributes, // q: TOKEN_SECURITY_ATTRIBUTES_INFORMATION // since REDSTONE
TokenBnoIsolation, // q: TOKEN_BNO_ISOLATION_INFORMATION // since REDSTONE2
TokenChildProcessFlags, // s: ULONG (requires SeTcbPrivilege) // since REDSTONE3
TokenIsLessPrivilegedAppContainer, // q: ULONG // since REDSTONE5
TokenIsSandboxed, // q: ULONG // since 19H1
TokenIsAppSilo, // q: ULONG // since WIN11 22H2 // previously TokenOriginatingProcessTrustLevel // q: TOKEN_PROCESS_TRUST_LEVEL
TokenLoggingInformation, // TOKEN_LOGGING_INFORMATION // since 24H2
MaxTokenInfoClass
} TOKEN_INFORMATION_CLASS, *PTOKEN_INFORMATION_CLASS;
#endif
typedef enum _PROCESSINFOCLASS
{
ProcessBasicInformation, // q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
ProcessIoCounters, // q: IO_COUNTERS
ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX, VM_COUNTERS_EX2
ProcessTimes, // q: KERNEL_USER_TIMES
ProcessBasePriority, // s: KPRIORITY
ProcessRaisePriority, // s: ULONG
ProcessDebugPort, // q: HANDLE
ProcessExceptionPort, // s: PROCESS_EXCEPTION_PORT (requires SeTcbPrivilege)
ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
ProcessLdtInformation, // qs: PROCESS_LDT_INFORMATION // 10
ProcessLdtSize, // s: PROCESS_LDT_SIZE
ProcessDefaultHardErrorMode, // qs: ULONG
ProcessIoPortHandlers, // (kernel-mode only) // s: PROCESS_IO_PORT_HANDLER_INFORMATION
ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
ProcessUserModeIOPL, // qs: ULONG (requires SeTcbPrivilege)
ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
ProcessWx86Information, // qs: ULONG (requires SeTcbPrivilege) (VdmAllowed)
ProcessHandleCount, // q: ULONG, PROCESS_HANDLE_INFORMATION // 20
ProcessAffinityMask, // (q >WIN7)s: KAFFINITY, qs: GROUP_AFFINITY
ProcessPriorityBoost, // qs: ULONG
ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
ProcessWow64Information, // q: ULONG_PTR
ProcessImageFileName, // q: UNICODE_STRING
ProcessLUIDDeviceMapsEnabled, // q: ULONG
ProcessBreakOnTermination, // qs: ULONG
ProcessDebugObjectHandle, // q: HANDLE // 30
ProcessDebugFlags, // qs: ULONG
ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: PROCESS_HANDLE_TRACING_ENABLE[_EX] or void to disable
ProcessIoPriority, // qs: IO_PRIORITY_HINT
ProcessExecuteFlags, // qs: ULONG (MEM_EXECUTE_OPTION_*)
ProcessTlsInformation, // PROCESS_TLS_INFORMATION // ProcessResourceManagement
ProcessCookie, // q: ULONG
ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA
ProcessPagePriority, // qs: PAGE_PRIORITY_INFORMATION
ProcessInstrumentationCallback, // s: PVOID or PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION // 40
ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]; s: void
ProcessImageFileNameWin32, // q: UNICODE_STRING
ProcessImageFileMapping, // q: HANDLE (input)
ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
ProcessGroupInformation, // q: USHORT[]
ProcessTokenVirtualizationEnabled, // s: ULONG
ProcessConsoleHostProcess, // qs: ULONG_PTR // ProcessOwnerInformation
ProcessWindowInformation, // q: PROCESS_WINDOW_INFORMATION // 50
ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
ProcessDynamicFunctionTableInformation, // s: PROCESS_DYNAMIC_FUNCTION_TABLE_INFORMATION
ProcessHandleCheckingMode, // qs: ULONG; s: 0 disables, otherwise enables
ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
ProcessWorkingSetControl, // s: PROCESS_WORKING_SET_CONTROL (requires SeDebugPrivilege)
ProcessHandleTable, // q: ULONG[] // since WINBLUE
ProcessCheckStackExtentsMode, // qs: ULONG // KPROCESS->CheckStackExtents (CFG)
ProcessCommandLineInformation, // q: UNICODE_STRING // 60
ProcessProtectionInformation, // q: PS_PROTECTION
ProcessMemoryExhaustion, // s: PROCESS_MEMORY_EXHAUSTION_INFO // since THRESHOLD
ProcessFaultInformation, // s: PROCESS_FAULT_INFORMATION
ProcessTelemetryIdInformation, // q: PROCESS_TELEMETRY_ID_INFORMATION
ProcessCommitReleaseInformation, // qs: PROCESS_COMMIT_RELEASE_INFORMATION
ProcessDefaultCpuSetsInformation, // qs: SYSTEM_CPU_SET_INFORMATION[5]
ProcessAllowedCpuSetsInformation, // qs: SYSTEM_CPU_SET_INFORMATION[5]
ProcessSubsystemProcess,
ProcessJobMemoryInformation, // q: PROCESS_JOB_MEMORY_INFO
ProcessInPrivate, // q: BOOLEAN; s: void // ETW // since THRESHOLD2 // 70
ProcessRaiseUMExceptionOnInvalidHandleClose, // qs: ULONG; s: 0 disables, otherwise enables
ProcessIumChallengeResponse,
ProcessChildProcessInformation, // q: PROCESS_CHILD_PROCESS_INFORMATION
ProcessHighGraphicsPriorityInformation, // qs: BOOLEAN (requires SeTcbPrivilege)
ProcessSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
ProcessEnergyValues, // q: PROCESS_ENERGY_VALUES, PROCESS_EXTENDED_ENERGY_VALUES
ProcessPowerThrottlingState, // qs: POWER_THROTTLING_PROCESS_STATE
ProcessReserved3Information, // ProcessActivityThrottlePolicy // PROCESS_ACTIVITY_THROTTLE_POLICY
ProcessWin32kSyscallFilterInformation, // q: WIN32K_SYSCALL_FILTER
ProcessDisableSystemAllowedCpuSets, // s: BOOLEAN // 80
ProcessWakeInformation, // q: PROCESS_WAKE_INFORMATION
ProcessEnergyTrackingState, // qs: PROCESS_ENERGY_TRACKING_STATE
ProcessManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
ProcessCaptureTrustletLiveDump,
ProcessTelemetryCoverage, // q: TELEMETRY_COVERAGE_HEADER; s: TELEMETRY_COVERAGE_POINT
ProcessEnclaveInformation,
ProcessEnableReadWriteVmLogging, // qs: PROCESS_READWRITEVM_LOGGING_INFORMATION
ProcessUptimeInformation, // q: PROCESS_UPTIME_INFORMATION
ProcessImageSection, // q: HANDLE
ProcessDebugAuthInformation, // since REDSTONE4 // 90
ProcessSystemResourceManagement, // s: PROCESS_SYSTEM_RESOURCE_MANAGEMENT
ProcessSequenceNumber, // q: ULONGLONG
ProcessLoaderDetour, // since REDSTONE5
ProcessSecurityDomainInformation, // q: PROCESS_SECURITY_DOMAIN_INFORMATION
ProcessCombineSecurityDomainsInformation, // s: PROCESS_COMBINE_SECURITY_DOMAINS_INFORMATION
ProcessEnableLogging, // qs: PROCESS_LOGGING_INFORMATION
ProcessLeapSecondInformation, // qs: PROCESS_LEAP_SECOND_INFORMATION
ProcessFiberShadowStackAllocation, // s: PROCESS_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION // since 19H1
ProcessFreeFiberShadowStackAllocation, // s: PROCESS_FREE_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION
ProcessAltSystemCallInformation, // s: PROCESS_SYSCALL_PROVIDER_INFORMATION // since 20H1 // 100
ProcessDynamicEHContinuationTargets, // s: PROCESS_DYNAMIC_EH_CONTINUATION_TARGETS_INFORMATION
ProcessDynamicEnforcedCetCompatibleRanges, // s: PROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGE_INFORMATION // since 20H2
ProcessCreateStateChange, // since WIN11
ProcessApplyStateChange,
ProcessEnableOptionalXStateFeatures, // s: ULONG64 // optional XState feature bitmask
ProcessAltPrefetchParam, // qs: OVERRIDE_PREFETCH_PARAMETER // App Launch Prefetch (ALPF) // since 22H1
ProcessAssignCpuPartitions,
ProcessPriorityClassEx, // s: PROCESS_PRIORITY_CLASS_EX
ProcessMembershipInformation, // q: PROCESS_MEMBERSHIP_INFORMATION
ProcessEffectiveIoPriority, // q: IO_PRIORITY_HINT // 110
ProcessEffectivePagePriority, // q: ULONG
ProcessSchedulerSharedData, // since 24H2
ProcessSlistRollbackInformation,
ProcessNetworkIoCounters, // q: PROCESS_NETWORK_COUNTERS
ProcessFindFirstThreadByTebValue, // PROCESS_TEB_VALUE_INFORMATION
MaxProcessInfoClass
} PROCESSINFOCLASS;
typedef enum _PS_ATTRIBUTE_NUM
{
PsAttributeParentProcess, // in HANDLE
PsAttributeDebugObject, // in HANDLE
PsAttributeToken, // in HANDLE
PsAttributeClientId, // out PCLIENT_ID
PsAttributeTebAddress, // out PTEB *
PsAttributeImageName, // in PWSTR
PsAttributeImageInfo, // out PSECTION_IMAGE_INFORMATION
PsAttributeMemoryReserve, // in PPS_MEMORY_RESERVE
PsAttributePriorityClass, // in UCHAR
PsAttributeErrorMode, // in ULONG
PsAttributeStdHandleInfo, // 10, in PPS_STD_HANDLE_INFO
PsAttributeHandleList, // in HANDLE[]
PsAttributeGroupAffinity, // in PGROUP_AFFINITY
PsAttributePreferredNode, // in PUSHORT
PsAttributeIdealProcessor, // in PPROCESSOR_NUMBER
PsAttributeUmsThread, // ? in PUMS_CREATE_THREAD_ATTRIBUTES
PsAttributeMitigationOptions, // in PPS_MITIGATION_OPTIONS_MAP (PROCESS_CREATION_MITIGATION_POLICY_*) // since WIN8
PsAttributeProtectionLevel, // in PS_PROTECTION // since WINBLUE
PsAttributeSecureProcess, // in PPS_TRUSTLET_CREATE_ATTRIBUTES, since THRESHOLD
PsAttributeJobList, // in HANDLE[]
PsAttributeChildProcessPolicy, // 20, in PULONG (PROCESS_CREATION_CHILD_PROCESS_*) // since THRESHOLD2
PsAttributeAllApplicationPackagesPolicy,
// in PULONG (PROCESS_CREATION_ALL_APPLICATION_PACKAGES_*) // since REDSTONE
PsAttributeWin32kFilter, // in PWIN32K_SYSCALL_FILTER
PsAttributeSafeOpenPromptOriginClaim, // in SE_SAFE_OPEN_PROMPT_RESULTS
PsAttributeBnoIsolation, // in PPS_BNO_ISOLATION_PARAMETERS // since REDSTONE2
PsAttributeDesktopAppPolicy, // in PULONG (PROCESS_CREATION_DESKTOP_APP_*)
PsAttributeChpe, // in BOOLEAN // since REDSTONE3
PsAttributeMitigationAuditOptions,
// in PPS_MITIGATION_AUDIT_OPTIONS_MAP (PROCESS_CREATION_MITIGATION_AUDIT_POLICY_*) // since 21H1
PsAttributeMachineType, // in USHORT // since 21H2
PsAttributeComponentFilter,
PsAttributeEnableOptionalXStateFeatures, // since WIN11
PsAttributeSupportedMachines, // since 24H2
PsAttributeSveVectorLength, // PPS_PROCESS_CREATION_SVE_VECTOR_LENGTH
PsAttributeMax
} PS_ATTRIBUTE_NUM;
struct SYSTEM_PROCESSOR_INFORMATION64
{
USHORT ProcessorArchitecture;
USHORT ProcessorLevel;
USHORT ProcessorRevision;
USHORT MaximumProcessors;
ULONG ProcessorFeatureBits;
};
#ifndef OS_WINDOWS
typedef struct _M128A {
ULONGLONG Low;
LONGLONG High;
} M128A, *PM128A;
typedef struct _XMM_SAVE_AREA32 {
WORD ControlWord;
WORD StatusWord;
BYTE TagWord;
BYTE Reserved1;
WORD ErrorOpcode;
DWORD ErrorOffset;
WORD ErrorSelector;
WORD Reserved2;
DWORD DataOffset;
WORD DataSelector;
WORD Reserved3;
DWORD MxCsr;
DWORD MxCsr_Mask;
M128A FloatRegisters[8];
M128A XmmRegisters[16];
BYTE Reserved4[96];
} XMM_SAVE_AREA32, *PXMM_SAVE_AREA32;
#endif
typedef struct _NEON128
{
ULONGLONG Low;
LONGLONG High;
} NEON128;
typedef struct DECLSPEC_ALIGN(16) _CONTEXT64
{
DWORD64 P1Home;
DWORD64 P2Home;
DWORD64 P3Home;
DWORD64 P4Home;
DWORD64 P5Home;
DWORD64 P6Home;
DWORD ContextFlags;
DWORD MxCsr;
WORD SegCs;
WORD SegDs;
WORD SegEs;
WORD SegFs;
WORD SegGs;
WORD SegSs;
DWORD EFlags;
DWORD64 Dr0;
DWORD64 Dr1;
DWORD64 Dr2;
DWORD64 Dr3;
DWORD64 Dr6;
DWORD64 Dr7;
DWORD64 Rax;
DWORD64 Rcx;
DWORD64 Rdx;
DWORD64 Rbx;
DWORD64 Rsp;
DWORD64 Rbp;
DWORD64 Rsi;
DWORD64 Rdi;
DWORD64 R8;
DWORD64 R9;
DWORD64 R10;
DWORD64 R11;
DWORD64 R12;
DWORD64 R13;
DWORD64 R14;
DWORD64 R15;
DWORD64 Rip;
union
{
XMM_SAVE_AREA32 FltSave;
NEON128 Q[16];
ULONGLONG D[32];
struct
{
M128A Header[2];
M128A Legacy[8];
M128A Xmm0;
M128A Xmm1;
M128A Xmm2;
M128A Xmm3;
M128A Xmm4;
M128A Xmm5;
M128A Xmm6;
M128A Xmm7;
M128A Xmm8;
M128A Xmm9;
M128A Xmm10;
M128A Xmm11;
M128A Xmm12;
M128A Xmm13;
M128A Xmm14;
M128A Xmm15;
};
DWORD S[32];
};
M128A VectorRegister[26];
DWORD64 VectorControl;
DWORD64 DebugControl;
DWORD64 LastBranchToRip;
DWORD64 LastBranchFromRip;
DWORD64 LastExceptionToRip;
DWORD64 LastExceptionFromRip;
} CONTEXT64, *PCONTEXT64;
template <typename Traits>
struct EMU_EXCEPTION_RECORD
{
DWORD ExceptionCode;
DWORD ExceptionFlags;
EMULATOR_CAST(typename Traits::PVOID, struct EMU_EXCEPTION_RECORD *) ExceptionRecord;
typename Traits::PVOID ExceptionAddress;
DWORD NumberParameters;
typename Traits::ULONG_PTR ExceptionInformation[15];
};
template <typename Traits>
struct EMU_EXCEPTION_POINTERS
{
EMULATOR_CAST(typename Traits::PVOID, EMU_EXCEPTION_RECORD*) ExceptionRecord;
EMULATOR_CAST(typename Traits::PVOID, CONTEXT64* or CONTEXT32*) ContextRecord;
};
#define MAXIMUM_NODE_COUNT64 0x40
#define MAXIMUM_NODE_COUNT32 0x10
struct EMU_GROUP_AFFINITY64
{
EMULATOR_CAST(std::uint64_t, KAFFINITY) Mask;
WORD Group;
WORD Reserved[3];
};
typedef struct _SYSTEM_NUMA_INFORMATION64
{
ULONG HighestNodeNumber;
ULONG Reserved;
union
{
EMU_GROUP_AFFINITY64 ActiveProcessorsGroupAffinity[MAXIMUM_NODE_COUNT64];
ULONGLONG AvailableMemory[MAXIMUM_NODE_COUNT64];
ULONGLONG Pad[MAXIMUM_NODE_COUNT64 * 2];
};
} SYSTEM_NUMA_INFORMATION64, *PSYSTEM_NUMA_INFORMATION64;
typedef struct _SYSTEM_ERROR_PORT_TIMEOUTS
{
ULONG StartTimeout;
ULONG CommTimeout;
} SYSTEM_ERROR_PORT_TIMEOUTS, *PSYSTEM_ERROR_PORT_TIMEOUTS;
typedef struct _SYSTEM_BASIC_INFORMATION64
{
ULONG Reserved;
ULONG TimerResolution;
ULONG PageSize;
ULONG NumberOfPhysicalPages;
ULONG LowestPhysicalPageNumber;
ULONG HighestPhysicalPageNumber;
ULONG AllocationGranularity;
EMULATOR_CAST(EmulatorTraits<Emu64>::PVOID, ULONG_PTR) MinimumUserModeAddress;
EMULATOR_CAST(EmulatorTraits<Emu64>::PVOID, ULONG_PTR) MaximumUserModeAddress;
EMULATOR_CAST(EmulatorTraits<Emu64>::PVOID, KAFFINITY) ActiveProcessorsAffinityMask;
char NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION64, *PSYSTEM_BASIC_INFORMATION64;
typedef struct _SYSTEM_RANGE_START_INFORMATION64
{
EmulatorTraits<Emu64>::SIZE_T SystemRangeStart;
} SYSTEM_RANGE_START_INFORMATION64, *PSYSTEM_RANGE_START_INFORMATION64;
struct SID_AND_ATTRIBUTES64
{
EMULATOR_CAST(EmulatorTraits<Emu64>::PVOID, PSID) Sid;
DWORD Attributes;
};
struct TOKEN_USER64
{
SID_AND_ATTRIBUTES64 User;
};
struct TOKEN_BNO_ISOLATION_INFORMATION64
{
EmulatorTraits<Emu64>::PVOID IsolationPrefix;
BOOLEAN IsolationEnabled;
};
struct TOKEN_MANDATORY_LABEL64
{
SID_AND_ATTRIBUTES64 Label;
};
#ifndef OS_WINDOWS
typedef enum _TOKEN_TYPE {
TokenPrimary = 1,
TokenImpersonation
} TOKEN_TYPE;
typedef TOKEN_TYPE* PTOKEN_TYPE;
typedef struct _TOKEN_ELEVATION {
DWORD TokenIsElevated;
} TOKEN_ELEVATION, * PTOKEN_ELEVATION;
typedef enum _SECURITY_IMPERSONATION_LEVEL {
SecurityAnonymous,
SecurityIdentification,
SecurityImpersonation,
SecurityDelegation
} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
typedef struct _LUID {
DWORD LowPart;
LONG HighPart;
} LUID, *PLUID;
typedef struct _TOKEN_STATISTICS {
LUID TokenId;
LUID AuthenticationId;
LARGE_INTEGER ExpirationTime;
TOKEN_TYPE TokenType;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
DWORD DynamicCharged;
DWORD DynamicAvailable;
DWORD GroupCount;
DWORD PrivilegeCount;
LUID ModifiedId;
} TOKEN_STATISTICS, *PTOKEN_STATISTICS;
#endif
typedef struct _TOKEN_SECURITY_ATTRIBUTES_INFORMATION
{
USHORT Version;
USHORT Reserved;
ULONG AttributeCount;
union
{
EmulatorTraits<Emu64>::PVOID pAttributeV1;
} Attribute;
} TOKEN_SECURITY_ATTRIBUTES_INFORMATION, *PTOKEN_SECURITY_ATTRIBUTES_INFORMATION;
struct GDI_HANDLE_ENTRY64
{
union
{
EmulatorTraits<Emu64>::PVOID Object;
EmulatorTraits<Emu64>::PVOID NextFree;
};
union
{
struct
{
USHORT ProcessId;
USHORT Lock : 1;
USHORT Count : 15;
};
ULONG Value;
} Owner;
USHORT Unique;
UCHAR Type;
UCHAR Flags;
EmulatorTraits<Emu64>::PVOID UserPointer;
};
#define GDI_MAX_HANDLE_COUNT 0xFFFF // 0x4000
struct GDI_SHARED_MEMORY64
{
GDI_HANDLE_ENTRY64 Handles[GDI_MAX_HANDLE_COUNT];
};
struct CLIENT_ID64
{
DWORD64 UniqueProcess;
DWORD64 UniqueThread;
};
struct PORT_MESSAGE64
{
union
{
struct
{
CSHORT DataLength;
CSHORT TotalLength;
} s1;
ULONG Length;
} u1;
union
{
struct
{
CSHORT Type;
CSHORT DataInfoOffset;
} s2;
ULONG ZeroInit;
} u2;
union
{
CLIENT_ID64 ClientId;
double DoNotUseThisField;
};
ULONG MessageId;
union
{
EmulatorTraits<Emu64>::SIZE_T ClientViewSize; // only valid for LPC_CONNECTION_REQUEST messages
ULONG CallbackId; // only valid for LPC_REQUEST messages
};
};
struct ALPC_MESSAGE_ATTRIBUTES
{
ULONG AllocatedAttributes;
ULONG ValidAttributes;
};
template <typename Traits>
struct PORT_DATA_ENTRY
{
typename Traits::PVOID Base;
ULONG Size;
};
template <typename Traits>
struct EMU_RTL_SRWLOCK
{
typename Traits::PVOID Ptr;
};

View File

@@ -0,0 +1,64 @@
#pragma once
typedef enum _KEY_INFORMATION_CLASS
{
KeyBasicInformation, // KEY_BASIC_INFORMATION
KeyNodeInformation, // KEY_NODE_INFORMATION
KeyFullInformation, // KEY_FULL_INFORMATION
KeyNameInformation, // KEY_NAME_INFORMATION
KeyCachedInformation, // KEY_CACHED_INFORMATION
KeyFlagsInformation, // KEY_FLAGS_INFORMATION
KeyVirtualizationInformation, // KEY_VIRTUALIZATION_INFORMATION
KeyHandleTagsInformation, // KEY_HANDLE_TAGS_INFORMATION
KeyTrustInformation, // KEY_TRUST_INFORMATION
KeyLayerInformation, // KEY_LAYER_INFORMATION
MaxKeyInfoClass
} KEY_INFORMATION_CLASS;
typedef enum _KEY_VALUE_INFORMATION_CLASS
{
KeyValueBasicInformation, // KEY_VALUE_BASIC_INFORMATION
KeyValueFullInformation, // KEY_VALUE_FULL_INFORMATION
KeyValuePartialInformation, // KEY_VALUE_PARTIAL_INFORMATION
KeyValueFullInformationAlign64,
KeyValuePartialInformationAlign64, // KEY_VALUE_PARTIAL_INFORMATION_ALIGN64
KeyValueLayerInformation, // KEY_VALUE_LAYER_INFORMATION
MaxKeyValueInfoClass
} KEY_VALUE_INFORMATION_CLASS;
struct KEY_NAME_INFORMATION
{
std::uint32_t NameLength;
char16_t Name[1];
};
struct KEY_HANDLE_TAGS_INFORMATION
{
ULONG HandleTags;
};
struct KEY_VALUE_BASIC_INFORMATION
{
ULONG TitleIndex;
ULONG Type;
ULONG NameLength;
char16_t Name[1];
};
struct KEY_VALUE_PARTIAL_INFORMATION
{
ULONG TitleIndex;
ULONG Type;
ULONG DataLength;
UCHAR Data[1];
};
struct KEY_VALUE_FULL_INFORMATION
{
ULONG TitleIndex;
ULONG Type;
ULONG DataOffset;
ULONG DataLength;
ULONG NameLength;
char16_t Name[1];
};

View File

@@ -0,0 +1,46 @@
#pragma once
#include <cstdint>
using NTSTATUS = std::uint32_t;
#ifndef OS_WINDOWS
#define STATUS_WAIT_0 ((NTSTATUS)0x00000000L)
#define STATUS_TIMEOUT ((NTSTATUS)0x00000102L)
#define STATUS_ACCESS_VIOLATION ((NTSTATUS)0xC0000005L)
#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008L)
#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL)
#define STATUS_PENDING ((DWORD)0x00000103L)
#endif
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_WAIT_1 ((NTSTATUS)0x00000001L)
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0x00000001L)
#define STATUS_ALERTED ((NTSTATUS)0x00000101L)
#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS)0x40000000L)
#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L)
#define STATUS_ILLEGAL_INSTRUCTION ((DWORD )0xC000001DL)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL)
#define STATUS_FILE_INVALID ((NTSTATUS)0xC0000098L)
#define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS)0xC00000A0L)
#define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS)0xC00000BAL)
#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL)
#define STATUS_INVALID_ADDRESS ((NTSTATUS)0xC0000141L)
#define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225L)
#define STATUS_CONNECTION_REFUSED ((NTSTATUS)0xC0000236L)
#define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS)0xC0000328L)
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
#define FILE_DEVICE_NETWORK 0x00000012
#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK

View File

@@ -0,0 +1,16 @@
#pragma once
typedef enum _EVENT_TYPE
{
NotificationEvent,
SynchronizationEvent
} EVENT_TYPE;
typedef enum _WAIT_TYPE
{
WaitAll,
WaitAny,
WaitNotification,
WaitDequeue,
WaitDpc,
} WAIT_TYPE;

View File

@@ -0,0 +1,83 @@
#pragma once
typedef enum _THREADINFOCLASS
{
ThreadBasicInformation, // q: THREAD_BASIC_INFORMATION
ThreadTimes, // q: KERNEL_USER_TIMES
ThreadPriority, // s: KPRIORITY (requires SeIncreaseBasePriorityPrivilege)
ThreadBasePriority, // s: KPRIORITY
ThreadAffinityMask, // s: KAFFINITY
ThreadImpersonationToken, // s: HANDLE
ThreadDescriptorTableEntry, // q: DESCRIPTOR_TABLE_ENTRY (or WOW64_DESCRIPTOR_TABLE_ENTRY)
ThreadEnableAlignmentFaultFixup, // s: BOOLEAN
ThreadEventPair,
ThreadQuerySetWin32StartAddress, // q: ULONG_PTR
ThreadZeroTlsCell, // s: ULONG // TlsIndex // 10
ThreadPerformanceCount, // q: LARGE_INTEGER
ThreadAmILastThread, // q: ULONG
ThreadIdealProcessor, // s: ULONG
ThreadPriorityBoost, // qs: ULONG
ThreadSetTlsArrayAddress, // s: ULONG_PTR // Obsolete
ThreadIsIoPending, // q: ULONG
ThreadHideFromDebugger, // q: BOOLEAN; s: void
ThreadBreakOnTermination, // qs: ULONG
ThreadSwitchLegacyState, // s: void // NtCurrentThread // NPX/FPU
ThreadIsTerminated, // q: ULONG // 20
ThreadLastSystemCall, // q: THREAD_LAST_SYSCALL_INFORMATION
ThreadIoPriority, // qs: IO_PRIORITY_HINT (requires SeIncreaseBasePriorityPrivilege)
ThreadCycleTime, // q: THREAD_CYCLE_TIME_INFORMATION
ThreadPagePriority, // qs: PAGE_PRIORITY_INFORMATION
ThreadActualBasePriority, // s: LONG (requires SeIncreaseBasePriorityPrivilege)
ThreadTebInformation, // q: THREAD_TEB_INFORMATION (requires THREAD_GET_CONTEXT + THREAD_SET_CONTEXT)
ThreadCSwitchMon, // Obsolete
ThreadCSwitchPmu,
ThreadWow64Context, // qs: WOW64_CONTEXT, ARM_NT_CONTEXT since 20H1
ThreadGroupInformation, // qs: GROUP_AFFINITY // 30
ThreadUmsInformation, // q: THREAD_UMS_INFORMATION // Obsolete
ThreadCounterProfiling, // q: BOOLEAN; s: THREAD_PROFILING_INFORMATION?
ThreadIdealProcessorEx, // qs: PROCESSOR_NUMBER; s: previous PROCESSOR_NUMBER on return
ThreadCpuAccountingInformation, // q: BOOLEAN; s: HANDLE (NtOpenSession) // NtCurrentThread // since WIN8
ThreadSuspendCount, // q: ULONG // since WINBLUE
ThreadHeterogeneousCpuPolicy, // q: KHETERO_CPU_POLICY // since THRESHOLD
ThreadContainerId, // q: GUID
ThreadNameInformation, // qs: THREAD_NAME_INFORMATION
ThreadSelectedCpuSets,
ThreadSystemThreadInformation, // q: SYSTEM_THREAD_INFORMATION // 40
ThreadActualGroupAffinity, // q: GROUP_AFFINITY // since THRESHOLD2
ThreadDynamicCodePolicyInfo, // q: ULONG; s: ULONG (NtCurrentThread)
ThreadExplicitCaseSensitivity, // qs: ULONG; s: 0 disables, otherwise enables
ThreadWorkOnBehalfTicket, // RTL_WORK_ON_BEHALF_TICKET_EX
ThreadSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
ThreadDbgkWerReportActive, // s: ULONG; s: 0 disables, otherwise enables
ThreadAttachContainer, // s: HANDLE (job object) // NtCurrentThread
ThreadManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
ThreadPowerThrottlingState, // POWER_THROTTLING_THREAD_STATE // since REDSTONE3 (set), WIN11 22H2 (query)
ThreadWorkloadClass, // THREAD_WORKLOAD_CLASS // since REDSTONE5 // 50
ThreadCreateStateChange, // since WIN11
ThreadApplyStateChange,
ThreadStrongerBadHandleChecks, // since 22H1
ThreadEffectiveIoPriority, // q: IO_PRIORITY_HINT
ThreadEffectivePagePriority, // q: ULONG
ThreadUpdateLockOwnership, // since 24H2
ThreadSchedulerSharedDataSlot, // SCHEDULER_SHARED_DATA_SLOT_INFORMATION
ThreadTebInformationAtomic, // THREAD_TEB_INFORMATION
ThreadIndexInformation, // THREAD_INDEX_INFORMATION
MaxThreadInfoClass
} THREADINFOCLASS;
template <typename Traits>
struct THREAD_NAME_INFORMATION
{
UNICODE_STRING<Traits> ThreadName;
};
typedef struct _THREAD_BASIC_INFORMATION64
{
NTSTATUS ExitStatus;
PTEB64 TebBaseAddress;
CLIENT_ID64 ClientId;
EMULATOR_CAST(std::uint64_t, KAFFINITY) AffinityMask;
EMULATOR_CAST(std::uint32_t, KPRIORITY) Priority;
EMULATOR_CAST(std::uint32_t, KPRIORITY) BasePriority;
} THREAD_BASIC_INFORMATION64, *PTHREAD_BASIC_INFORMATION64;

View File

@@ -0,0 +1,37 @@
#pragma once
#include <cstdint>
// used to retain original type "x"
#define EMULATOR_CAST(T, x) T
struct Emu32
{
};
struct Emu64
{
};
template <typename EmuArch>
struct EmulatorTraits;
template <>
struct EmulatorTraits<Emu32>
{
using PVOID = std::uint32_t;
using ULONG_PTR = std::uint32_t;
using SIZE_T = std::uint32_t;
using UNICODE = char16_t;
using HANDLE = std::uint32_t;
};
template <>
struct EmulatorTraits<Emu64>
{
using PVOID = std::uint64_t;
using ULONG_PTR = std::uint64_t;
using SIZE_T = std::uint64_t;
using UNICODE = char16_t;
using HANDLE = std::uint64_t;
};

View File

@@ -0,0 +1,80 @@
#pragma once
#include <string>
template <typename Traits>
struct UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
EMULATOR_CAST(typename Traits::PVOID, char16_t*) Buffer;
};
inline std::string u16_to_u8(const std::u16string_view u16_view)
{
std::string utf8_str;
utf8_str.reserve(u16_view.size() * 2);
for (const char16_t ch : u16_view)
{
if (ch <= 0x7F)
{
utf8_str.push_back(static_cast<char>(ch));
}
else if (ch <= 0x7FF)
{
utf8_str.push_back(static_cast<char>(0xC0 | (ch >> 6)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
else
{
utf8_str.push_back(static_cast<char>(0xE0 | (ch >> 12)));
utf8_str.push_back(static_cast<char>(0x80 | ((ch >> 6) & 0x3F)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
}
return utf8_str;
}
inline std::string w_to_u8(const std::wstring_view w_view)
{
std::string utf8_str;
utf8_str.reserve(w_view.size() * 2);
for (const wchar_t w_ch : w_view)
{
const auto ch = static_cast<char16_t>(w_ch);
if (ch <= 0x7F)
{
utf8_str.push_back(static_cast<char>(ch));
}
else if (ch <= 0x7FF)
{
utf8_str.push_back(static_cast<char>(0xC0 | (ch >> 6)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
else
{
utf8_str.push_back(static_cast<char>(0xE0 | (ch >> 12)));
utf8_str.push_back(static_cast<char>(0x80 | ((ch >> 6) & 0x3F)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
}
return utf8_str;
}
#ifndef OS_WINDOWS
inline int open_unicode(FILE** handle, const std::u16string& fileName, const std::u16string& mode)
{
*handle = fopen(u16_to_u8(fileName).c_str(), u16_to_u8(mode).c_str());
return errno;
}
#else
inline std::wstring u16_to_w(const std::u16string& u16str)
{
return std::wstring(reinterpret_cast<const wchar_t*>(u16str.data()), u16str.size());
}
inline auto open_unicode(FILE** handle, const std::u16string& fileName, const std::u16string& mode)
{
return _wfopen_s(handle, u16_to_w(fileName).c_str(), u16_to_w(mode).c_str());
}
#endif

View File

@@ -0,0 +1,340 @@
#pragma once
#include <cstdint>
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
// IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage)
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
#define IMAGE_REL_BASED_ABSOLUTE 0
#define IMAGE_REL_BASED_HIGH 1
#define IMAGE_REL_BASED_LOW 2
#define IMAGE_REL_BASED_HIGHLOW 3
#define IMAGE_REL_BASED_HIGHADJ 4
#define IMAGE_REL_BASED_MIPS_JMPADDR 5
#define IMAGE_REL_BASED_ARM_MOV32A 5
#define IMAGE_REL_BASED_ARM_MOV32 5
#define IMAGE_REL_BASED_SECTION 6
#define IMAGE_REL_BASED_REL 7
#define IMAGE_REL_BASED_ARM_MOV32T 7
#define IMAGE_REL_BASED_THUMB_MOV32 7
#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
#define IMAGE_REL_BASED_IA64_IMM64 9
#define IMAGE_REL_BASED_DIR64 10
#define IMAGE_REL_BASED_HIGH3ADJ 11
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
#define IMAGE_FILE_DLL 0x2000
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define PROCESSOR_ARCHITECTURE_AMD64 9
enum class PEMachineType : std::uint16_t
{
UNKNOWN = 0,
I386 = 0x014c, // Intel 386.
R3000 = 0x0162, // MIPS little-endian, 0x160 big-endian
R4000 = 0x0166, // MIPS little-endian
R10000 = 0x0168, // MIPS little-endian
WCEMIPSV2 = 0x0169, // MIPS little-endian WCE v2
ALPHA = 0x0184, // Alpha_AXP
SH3 = 0x01a2, // SH3 little-endian
SH3DSP = 0x01a3,
SH3E = 0x01a4, // SH3E little-endian
SH4 = 0x01a6, // SH4 little-endian
SH5 = 0x01a8, // SH5
ARM = 0x01c0, // ARM Little-Endian
THUMB = 0x01c2, // ARM Thumb/Thumb-2 Little-Endian
ARMNT = 0x01c4, // ARM Thumb-2 Little-Endian
AM33 = 0x01d3,
POWERPC = 0x01F0, // IBM PowerPC Little-Endian
POWERPCFP = 0x01f1,
IA64 = 0x0200, // Intel 64
MIPS16 = 0x0266, // MIPS
ALPHA64 = 0x0284, // ALPHA64
MIPSFPU = 0x0366, // MIPS
MIPSFPU16 = 0x0466, // MIPS
AXP64 = ALPHA64,
TRICORE = 0x0520, // Infineon
CEF = 0x0CEF,
EBC = 0x0EBC, // EFI Byte Code
AMD64 = 0x8664, // AMD64 (K8)
M32R = 0x9041, // M32R little-endian
CEE = 0xC0EE,
};
#pragma pack(push, 4)
template <typename T>
struct PEOptionalHeaderBasePart2_t
{
};
template <>
struct PEOptionalHeaderBasePart2_t<std::uint32_t>
{
std::uint32_t BaseOfData;
std::uint32_t ImageBase;
};
template <>
struct PEOptionalHeaderBasePart2_t<std::uint64_t>
{
std::uint64_t ImageBase;
};
template <typename T>
struct PEOptionalHeaderBasePart1_t
{
enum
{
k_NumberOfDataDirectors = 16
};
uint16_t Magic;
uint8_t MajorLinkerVersion;
uint8_t MinorLinkerVersion;
uint32_t SizeOfCode;
uint32_t SizeOfInitializedData;
uint32_t SizeOfUninitializedData;
uint32_t AddressOfEntryPoint;
uint32_t BaseOfCode;
};
struct PEDirectory_t2
{
std::uint32_t VirtualAddress;
std::uint32_t Size;
};
template <typename T>
struct PEOptionalHeaderBasePart3_t : PEOptionalHeaderBasePart1_t<T>, PEOptionalHeaderBasePart2_t<T>
{
uint32_t SectionAlignment;
uint32_t FileAlignment;
uint16_t MajorOperatingSystemVersion;
uint16_t MinorOperatingSystemVersion;
uint16_t MajorImageVersion;
uint16_t MinorImageVersion;
uint16_t MajorSubsystemVersion;
uint16_t MinorSubsystemVersion;
uint32_t Win32VersionValue;
uint32_t SizeOfImage;
uint32_t SizeOfHeaders;
uint32_t CheckSum;
uint16_t Subsystem;
uint16_t DllCharacteristics;
T SizeOfStackReserve;
T SizeOfStackCommit;
T SizeOfHeapReserve;
T SizeOfHeapCommit;
uint32_t LoaderFlags;
uint32_t NumberOfRvaAndSizes;
PEDirectory_t2 DataDirectory[PEOptionalHeaderBasePart1_t<T>::k_NumberOfDataDirectors];
};
template <typename T>
struct PEOptionalHeader_t
{
};
template <>
struct PEOptionalHeader_t<std::uint32_t> : PEOptionalHeaderBasePart3_t<std::uint32_t>
{
enum
{
k_Magic = 0x10b, // IMAGE_NT_OPTIONAL_HDR32_MAGIC
};
};
template <>
struct PEOptionalHeader_t<std::uint64_t> : PEOptionalHeaderBasePart3_t<std::uint64_t>
{
enum
{
k_Magic = 0x20b, // IMAGE_NT_OPTIONAL_HDR64_MAGIC
};
};
struct PEFileHeader_t
{
PEMachineType Machine;
std::uint16_t NumberOfSections;
std::uint32_t TimeDateStamp;
std::uint32_t PointerToSymbolTable;
std::uint32_t NumberOfSymbols;
std::uint16_t SizeOfOptionalHeader;
std::uint16_t Characteristics;
};
template <typename T>
struct PENTHeaders_t
{
enum
{
k_Signature = 0x00004550, // IMAGE_NT_SIGNATURE
};
uint32_t Signature;
PEFileHeader_t FileHeader;
PEOptionalHeader_t<T> OptionalHeader;
};
struct PEDosHeader_t
{
enum
{
k_Magic = 0x5A4D
};
std::uint16_t e_magic; // Magic number ( k_Magic )
std::uint16_t e_cblp; // Bytes on last page of file
std::uint16_t e_cp; // Pages in file
std::uint16_t e_crlc; // Relocations
std::uint16_t e_cparhdr; // Size of header in paragraphs
std::uint16_t e_minalloc; // Minimum extra paragraphs needed
std::uint16_t e_maxalloc; // Maximum extra paragraphs needed
std::uint16_t e_ss; // Initial (relative) SS value
std::uint16_t e_sp; // Initial SP value
std::uint16_t e_csum; // Checksum
std::uint16_t e_ip; // Initial IP value
std::uint16_t e_cs; // Initial (relative) CS value
std::uint16_t e_lfarlc; // File address of relocation table
std::uint16_t e_ovno; // Overlay number
std::uint16_t e_res[4]; // Reserved words
std::uint16_t e_oemid; // OEM identifier (for e_oeminfo)
std::uint16_t e_oeminfo; // OEM information; e_oemid specific
std::uint16_t e_res2[10]; // Reserved words
std::uint32_t e_lfanew; // File address of new exe header
};
#pragma pack(pop)
#define IMAGE_SIZEOF_SHORT_NAME 8
#ifndef OS_WINDOWS
typedef struct _IMAGE_SECTION_HEADER
{
std::uint8_t Name[IMAGE_SIZEOF_SHORT_NAME];
union {
std:: uint32_t PhysicalAddress;
std::uint32_t VirtualSize;
} Misc;
std::uint32_t VirtualAddress;
std::uint32_t SizeOfRawData;
std::uint32_t PointerToRawData;
std::uint32_t PointerToRelocations;
std::uint32_t PointerToLinenumbers;
std::uint16_t NumberOfRelocations;
std::uint16_t NumberOfLinenumbers;
std::uint32_t Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions;
DWORD AddressOfNames;
DWORD AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
typedef struct _IMAGE_BASE_RELOCATION {
DWORD VirtualAddress;
DWORD SizeOfBlock;
WORD TypeOffset[1];
} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
#endif
template <typename Traits>
struct SECTION_IMAGE_INFORMATION
{
typename Traits::PVOID TransferAddress;
ULONG ZeroBits;
typename Traits::SIZE_T MaximumStackSize;
typename Traits::SIZE_T CommittedStackSize;
ULONG SubSystemType;
union
{
struct
{
USHORT SubSystemMinorVersion;
USHORT SubSystemMajorVersion;
};
ULONG SubSystemVersion;
};
union
{
struct
{
USHORT MajorOperatingSystemVersion;
USHORT MinorOperatingSystemVersion;
};
ULONG OperatingSystemVersion;
};
USHORT ImageCharacteristics;
USHORT DllCharacteristics;
PEMachineType Machine;
BOOLEAN ImageContainsCode;
union
{
UCHAR ImageFlags;
struct
{
UCHAR ComPlusNativeReady : 1;
UCHAR ComPlusILOnly : 1;
UCHAR ImageDynamicallyRelocated : 1;
UCHAR ImageMappedFlat : 1;
UCHAR BaseBelow4gb : 1;
UCHAR ComPlusPrefer32bit : 1;
UCHAR Reserved : 2;
};
};
ULONG LoaderFlags;
ULONG ImageFileSize;
ULONG CheckSum;
};

View File

@@ -13,8 +13,8 @@ namespace utils
{
public:
static_assert(!std::is_reference<F>::value && !std::is_const<F>::value &&
!std::is_volatile<F>::value,
"Final_action should store its callable by value");
!std::is_volatile<F>::value,
"Final_action should store its callable by value");
explicit final_action(F f) noexcept : f_(std::move(f))
{
@@ -52,4 +52,4 @@ namespace utils
return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(
std::forward<F>(f));
}
}
}

View File

@@ -28,12 +28,12 @@ namespace utils::io
io::create_directory(file.parent_path());
}
std::basic_ofstream<uint8_t> stream(
std::ofstream stream(
file, std::ios::binary | std::ofstream::out | (append ? std::ofstream::app : std::ofstream::out));
if (stream.is_open())
{
stream.write(data.data(), static_cast<std::streamsize>(data.size()));
stream.write(reinterpret_cast<const char*>(data.data()), static_cast<std::streamsize>(data.size()));
stream.close();
return true;
}

View File

@@ -1,5 +1,7 @@
#pragma once
#ifdef WIN32
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -83,3 +85,5 @@ namespace utils::nt
HANDLE handle_{InvalidHandleFunction()};
};
}
#endif

View File

@@ -11,6 +11,16 @@ namespace utils::string
return static_cast<char>(std::tolower(static_cast<unsigned char>(val)));
}
inline char16_t char_to_lower(const char16_t val)
{
if (val >= u'A' && val <= u'Z')
{
return val + 32;
}
return val;
}
inline wchar_t char_to_lower(const wchar_t val)
{
return std::towlower(val);

View File

@@ -21,6 +21,6 @@ namespace utils
}
private:
typename Clock::time_point point_{ Clock::now() };
typename Clock::time_point point_{Clock::now()};
};
}

View File

@@ -42,7 +42,8 @@ using instruction_hook_callback = std::function<instruction_hook_continuation()>
using interrupt_hook_callback = std::function<void(int interrupt)>;
using simple_memory_hook_callback = std::function<void(uint64_t address, size_t size, uint64_t value)>;
using complex_memory_hook_callback = std::function<void(uint64_t address, size_t size, uint64_t value, memory_operation operation)>;
using complex_memory_hook_callback = std::function<void(uint64_t address, size_t size, uint64_t value,
memory_operation operation)>;
using memory_violation_hook_callback = std::function<memory_violation_continuation(
uint64_t address, size_t size, memory_operation operation,
memory_violation_type type)>;
@@ -140,7 +141,8 @@ private:
{
assert((static_cast<uint8_t>(operation) & (static_cast<uint8_t>(operation) - 1)) == 0);
return this->hook_memory_access(address, size, operation,
[c = std::move(callback)](const uint64_t a, const size_t s, const uint64_t value,
[c = std::move(callback)](const uint64_t a, const size_t s,
const uint64_t value,
memory_operation)
{
c(a, s, value);

View File

@@ -63,30 +63,33 @@ namespace
}
}
static void serialize(utils::buffer_serializer& buffer, const memory_manager::committed_region& region)
namespace utils
{
buffer.write<uint64_t>(region.length);
buffer.write(region.pemissions);
}
static void serialize(buffer_serializer& buffer, const memory_manager::committed_region& region)
{
buffer.write<uint64_t>(region.length);
buffer.write(region.pemissions);
}
static void deserialize(utils::buffer_deserializer& buffer, memory_manager::committed_region& region)
{
region.length = static_cast<size_t>(buffer.read<uint64_t>());
region.pemissions = buffer.read<memory_permission>();
}
static void deserialize(buffer_deserializer& buffer, memory_manager::committed_region& region)
{
region.length = static_cast<size_t>(buffer.read<uint64_t>());
region.pemissions = buffer.read<memory_permission>();
}
static void serialize(utils::buffer_serializer& buffer, const memory_manager::reserved_region& region)
{
buffer.write(region.is_mmio);
buffer.write<uint64_t>(region.length);
buffer.write_map(region.committed_regions);
}
static void serialize(buffer_serializer& buffer, const memory_manager::reserved_region& region)
{
buffer.write(region.is_mmio);
buffer.write<uint64_t>(region.length);
buffer.write_map(region.committed_regions);
}
static void deserialize(utils::buffer_deserializer& buffer, memory_manager::reserved_region& region)
{
buffer.read(region.is_mmio);
region.length = static_cast<size_t>(buffer.read<uint64_t>());
buffer.read_map(region.committed_regions);
static void deserialize(buffer_deserializer& buffer, memory_manager::reserved_region& region)
{
buffer.read(region.is_mmio);
region.length = static_cast<size_t>(buffer.read<uint64_t>());
buffer.read_map(region.committed_regions);
}
}
void memory_manager::serialize_memory_state(utils::buffer_serializer& buffer, const bool is_snapshot) const
@@ -243,7 +246,7 @@ bool memory_manager::allocate_memory(const uint64_t address, const size_t size,
return false;
}
const auto entry = this->reserved_regions_.try_emplace(address, size).first;
const auto entry = this->reserved_regions_.try_emplace(address, reserved_region{.length = size,}).first;
if (!reserve_only)
{

View File

@@ -1,14 +1,15 @@
#pragma once
#include "memory_permission.hpp"
struct basic_memory_region
{
uint64_t start{};
size_t length{};
memory_permission permissions{};
};
struct memory_region : basic_memory_region
{
bool committed{};
};
#pragma once
#include "memory_permission.hpp"
#include <cstddef>
struct basic_memory_region
{
uint64_t start{};
size_t length{};
memory_permission permissions{};
};
struct memory_region : basic_memory_region
{
bool committed{};
};

View File

@@ -38,8 +38,8 @@ namespace utils
};
template <typename T>
struct has_serialize_function<T, std::void_t<decltype(::serialize(std::declval<buffer_serializer&>(),
std::declval<const std::remove_cvref_t<T>&>())
struct has_serialize_function<T, std::void_t<decltype(serialize(std::declval<buffer_serializer&>(),
std::declval<const std::remove_cvref_t<T>&>())
)>>
: std::true_type
{
@@ -51,7 +51,7 @@ namespace utils
};
template <typename T>
struct has_deserialize_function<T, std::void_t<decltype(::deserialize(
struct has_deserialize_function<T, std::void_t<decltype(deserialize(
std::declval<buffer_deserializer&>(),
std::declval<std::remove_cvref_t<T>&>()))>>
: std::true_type
@@ -97,6 +97,7 @@ namespace utils
const std::span result(this->buffer_.data() + this->offset_, length);
this->offset_ += length;
(void)this->no_debugging_;
#ifndef NDEBUG
if (!this->no_debugging_)
@@ -137,7 +138,7 @@ namespace utils
}
else if constexpr (detail::has_deserialize_function<T>::value)
{
::deserialize(*this, object);
deserialize(*this, object);
}
else if constexpr (is_trivially_copyable)
{
@@ -360,7 +361,7 @@ namespace utils
}
else if constexpr (detail::has_serialize_function<T>::value)
{
::serialize(*this, object);
serialize(*this, object);
}
else if constexpr (is_trivially_copyable)
{
@@ -465,6 +466,12 @@ namespace utils
object = this->read_string<wchar_t>();
}
template <>
inline void buffer_deserializer::read<std::u16string>(std::u16string& object)
{
object = this->read_string<char16_t>();
}
template <>
inline void buffer_serializer::write<bool>(const bool& object)
{
@@ -482,4 +489,10 @@ namespace utils
{
this->write_string(object);
}
template <>
inline void buffer_serializer::write<std::u16string>(const std::u16string& object)
{
this->write_string(object);
}
}

View File

@@ -5,40 +5,43 @@
#include <chrono>
#include <filesystem>
inline void serialize(utils::buffer_serializer& buffer, const std::chrono::steady_clock::time_point& tp)
namespace utils
{
buffer.write(tp.time_since_epoch().count());
}
inline void deserialize(utils::buffer_deserializer& buffer, std::chrono::steady_clock::time_point& tp)
{
using time_point = std::chrono::steady_clock::time_point;
using duration = time_point::duration;
const auto count = buffer.read<duration::rep>();
tp = time_point{duration{count}};
}
inline void serialize(utils::buffer_serializer& buffer, const std::chrono::system_clock::time_point& tp)
{
buffer.write(tp.time_since_epoch().count());
}
inline void deserialize(utils::buffer_deserializer& buffer, std::chrono::system_clock::time_point& tp)
{
using time_point = std::chrono::system_clock::time_point;
using duration = time_point::duration;
const auto count = buffer.read<duration::rep>();
tp = time_point{duration{count}};
}
inline void serialize(utils::buffer_serializer& buffer, const std::filesystem::path& path)
{
buffer.write_string<wchar_t>(path.wstring());
}
inline void deserialize(utils::buffer_deserializer& buffer, std::filesystem::path& path)
{
path = buffer.read_string<wchar_t>();
inline void serialize(buffer_serializer& buffer, const std::chrono::steady_clock::time_point& tp)
{
buffer.write(tp.time_since_epoch().count());
}
inline void deserialize(buffer_deserializer& buffer, std::chrono::steady_clock::time_point& tp)
{
using time_point = std::chrono::steady_clock::time_point;
using duration = time_point::duration;
const auto count = buffer.read<duration::rep>();
tp = time_point{duration{count}};
}
inline void serialize(buffer_serializer& buffer, const std::chrono::system_clock::time_point& tp)
{
buffer.write(tp.time_since_epoch().count());
}
inline void deserialize(buffer_deserializer& buffer, std::chrono::system_clock::time_point& tp)
{
using time_point = std::chrono::system_clock::time_point;
using duration = time_point::duration;
const auto count = buffer.read<duration::rep>();
tp = time_point{duration{count}};
}
inline void serialize(buffer_serializer& buffer, const std::filesystem::path& path)
{
buffer.write_string<char16_t>(path.u16string());
}
inline void deserialize(buffer_deserializer& buffer, std::filesystem::path& path)
{
path = buffer.read_string<char16_t>();
}
}

View File

@@ -24,7 +24,8 @@ namespace
catch (...)
{
win_emu.log.disable_output(false);
win_emu.log.print(color::red, "Emulation failed at: 0x%llX\n", win_emu.emu().read_instruction_pointer());
win_emu.log.print(color::red, "Emulation failed at: 0x%" PRIx64 "\n",
win_emu.emu().read_instruction_pointer());
throw;
}
@@ -90,7 +91,7 @@ namespace
restore_emulator();
const auto memory = emu.emu().allocate_memory(page_align_up(std::max(data.size(), 1ULL)),
const auto memory = emu.emu().allocate_memory(page_align_up(std::max(data.size(), size_t(1))),
memory_permission::read_write);
emu.emu().write_memory(memory, data.data(), data.size());
@@ -109,12 +110,12 @@ namespace
}
};
struct my_fuzzer_handler : fuzzer::handler
struct my_fuzzing_handler : fuzzer::fuzzing_handler
{
std::vector<std::byte> emulator_state{};
std::atomic_bool stop_fuzzing{false};
my_fuzzer_handler(std::vector<std::byte> emulator_state)
my_fuzzing_handler(std::vector<std::byte> emulator_state)
: emulator_state(std::move(emulator_state))
{
}
@@ -137,7 +138,7 @@ namespace
utils::buffer_serializer serializer{};
base_emulator.serialize(serializer);
my_fuzzer_handler handler{serializer.move_buffer()};
my_fuzzing_handler handler{serializer.move_buffer()};
fuzzer::run(handler, concurrency);
}

View File

@@ -1,37 +1,5 @@
#pragma once
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4005)
#pragma warning(disable: 4127)
#pragma warning(disable: 4201)
#pragma warning(disable: 4244)
#pragma warning(disable: 4245)
#pragma warning(disable: 4324)
#pragma warning(disable: 4458)
#pragma warning(disable: 4471)
#pragma warning(disable: 4505)
#pragma warning(disable: 4702)
#pragma warning(disable: 4996)
#pragma warning(disable: 5054)
#pragma warning(disable: 6011)
#pragma warning(disable: 6297)
#pragma warning(disable: 6385)
#pragma warning(disable: 6386)
#pragma warning(disable: 6387)
#pragma warning(disable: 26110)
#pragma warning(disable: 26451)
#pragma warning(disable: 26444)
#pragma warning(disable: 26451)
#pragma warning(disable: 26489)
#pragma warning(disable: 26495)
#pragma warning(disable: 26498)
#pragma warning(disable: 26812)
#pragma warning(disable: 28020)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <map>
#include <set>
#include <list>
@@ -57,23 +25,6 @@
#include <cassert>
#define NTDDI_WIN11_GE 0
#define PHNT_VERSION PHNT_WIN11
#include <phnt_windows.h>
#include <phnt.h>
#include <ntgdi.h>
#ifdef _WIN32
#pragma warning(pop)
#endif
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
#endif
#include <platform/platform.hpp>
using namespace std::literals;

View File

@@ -1,4 +1,6 @@
#include "fuzzer.hpp"
#include <cinttypes>
#include "input_generator.hpp"
namespace fuzzer
@@ -8,7 +10,7 @@ namespace fuzzer
class fuzzing_context
{
public:
fuzzing_context(input_generator& generator, handler& handler)
fuzzing_context(input_generator& generator, fuzzing_handler& handler)
: generator(generator)
, handler(handler)
{
@@ -36,7 +38,7 @@ namespace fuzzer
}
input_generator& generator;
handler& handler;
fuzzing_handler& handler;
std::atomic_uint64_t executions{0};
private:
@@ -110,7 +112,7 @@ namespace fuzzer
};
}
void run(handler& handler, const size_t concurrency)
void run(fuzzing_handler& handler, const size_t concurrency)
{
input_generator generator{};
fuzzing_context context{generator, handler};
@@ -123,7 +125,8 @@ namespace fuzzer
const auto executions = context.executions.exchange(0);
const auto highest_scorer = context.generator.get_highest_scorer();
const auto avg_score = context.generator.get_average_score();
printf("Executions/s: %lld - Score: %llX - Avg: %.3f\n", executions, highest_scorer.score, avg_score);
printf("Executions/s: %" PRIu64 " - Score: %" PRIx64 " - Avg: %.3f\n", executions, highest_scorer.score,
avg_score);
}
}
}

View File

@@ -20,12 +20,12 @@ namespace fuzzer
virtual ~executer() = default;
virtual execution_result execute(std::span<const uint8_t> data,
const std::function<coverage_functor>& coverage_handler) = 0;
const std::function<coverage_functor>& coverage_handler) = 0;
};
struct handler
struct fuzzing_handler
{
virtual ~handler() = default;
virtual ~fuzzing_handler() = default;
virtual std::unique_ptr<executer> make_executer() = 0;
@@ -35,5 +35,5 @@ namespace fuzzer
}
};
void run(handler& handler, size_t concurrency = std::thread::hardware_concurrency());
void run(fuzzing_handler& handler, size_t concurrency = std::thread::hardware_concurrency());
}

View File

@@ -1,4 +1,5 @@
#include "random_generator.hpp"
#include <cstring>
namespace fuzzer
{

View File

@@ -2,6 +2,7 @@
#include <span>
#include <random>
#include <cstdint>
#include <cstring>
namespace fuzzer
{

View File

@@ -13,4 +13,4 @@ target_include_directories(unicorn-emulator INTERFACE
)
target_link_libraries(unicorn-emulator PUBLIC emulator)
target_link_libraries(unicorn-emulator PRIVATE unicorn)
target_link_libraries(unicorn-emulator PRIVATE unicorn common)

View File

@@ -1,7 +1,9 @@
#pragma once
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4505)
#endif
#ifdef __clang__
#pragma GCC diagnostic push
@@ -15,7 +17,9 @@
#pragma GCC diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#include <stdexcept>

View File

@@ -5,6 +5,7 @@
#include "unicorn_hook.hpp"
#include "function_wrapper.hpp"
#include <ranges>
namespace unicorn
{
@@ -127,8 +128,17 @@ namespace unicorn
throw std::runtime_error("Memory saving not supported atm");
}
#ifndef OS_WINDOWS
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#endif
uc_ctl_context_mode(uc, UC_CTL_CONTEXT_CPU | (in_place ? UC_CTL_CONTEXT_MEMORY : 0));
#ifndef OS_WINDOWS
#pragma GCC diagnostic pop
#endif
this->size_ = uc_context_size(uc);
uce(uc_context_alloc(uc, &this->context_));
}
@@ -242,7 +252,17 @@ namespace unicorn
unicorn_x64_emulator()
{
uce(uc_open(UC_ARCH_X86, UC_MODE_64, &this->uc_));
#ifndef OS_WINDOWS
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#endif
uce(uc_ctl_set_tcg_buffer_size(this->uc_, 2 << 30 /* 2 gb */));
#ifndef OS_WINDOWS
#pragma GCC diagnostic pop
#endif
}
~unicorn_x64_emulator() override
@@ -316,15 +336,17 @@ namespace unicorn
mmio_write_callback write_cb) override
{
mmio_callbacks cb{
.read = [c = std::move(read_cb)](uc_engine*, const uint64_t addr, const uint32_t s)
{
return c(addr, s);
},
.write = [c = std::move(write_cb)](uc_engine*, const uint64_t addr, const uint32_t s,
const uint64_t value)
{
c(addr, s, value);
}
.read = mmio_callbacks::read_wrapper(
[c = std::move(read_cb)](uc_engine*, const uint64_t addr, const uint32_t s)
{
return c(addr, s);
}),
.write = mmio_callbacks::write_wrapper(
[c = std::move(write_cb)](uc_engine*, const uint64_t addr, const uint32_t s,
const uint64_t value)
{
c(addr, s, value);
})
};
uce(uc_mmio_map(*this, address, size, cb.read.get_c_function(), cb.read.get_user_data(),

View File

@@ -2,11 +2,12 @@
#include <memory>
#include <x64_emulator.hpp>
#include "platform/platform.hpp"
#ifdef UNICORN_EMULATOR_IMPL
#define UNICORN_EMULATOR_DLL_STORAGE __declspec(dllexport)
#define UNICORN_EMULATOR_DLL_STORAGE EXPORT_SYMBOL
#else
#define UNICORN_EMULATOR_DLL_STORAGE __declspec(dllimport)
#define UNICORN_EMULATOR_DLL_STORAGE IMPORT_SYMBOL
#endif
namespace unicorn

View File

@@ -16,7 +16,9 @@ target_link_libraries(windows-emulator-test PRIVATE
windows-emulator
)
add_dependencies(windows-emulator-test test-sample)
if(WIN32)
add_dependencies(windows-emulator-test test-sample)
endif()
add_test(NAME windows-emulator-test
COMMAND windows-emulator-test

View File

@@ -2,6 +2,6 @@
int main(int argc, char* argv[])
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -6,8 +6,8 @@ namespace test
{
std::string output_buffer{};
emulator_settings settings{
.arguments = {L"-time"},
const emulator_settings settings{
.arguments = {u"-time"},
.stdout_callback = [&output_buffer](const std::string_view data)
{
output_buffer.append(data);

View File

@@ -20,7 +20,6 @@ target_link_libraries(windows-emulator PRIVATE
target_link_libraries(windows-emulator PUBLIC
emulator
phnt::phnt
)
target_include_directories(windows-emulator INTERFACE

View File

@@ -3,9 +3,9 @@
namespace context_frame
{
void restore(x64_emulator& emu, const CONTEXT& context)
void restore(x64_emulator& emu, const CONTEXT64& context)
{
if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS)
if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64)
{
emu.reg(x64_register::dr0, context.Dr0);
emu.reg(x64_register::dr1, context.Dr1);
@@ -15,7 +15,7 @@ namespace context_frame
emu.reg(x64_register::dr7, context.Dr7);
}
if (context.ContextFlags & CONTEXT_CONTROL)
if (context.ContextFlags & CONTEXT_CONTROL_64)
{
emu.reg<uint16_t>(x64_register::ss, context.SegSs);
emu.reg<uint16_t>(x64_register::cs, context.SegCs);
@@ -26,7 +26,7 @@ namespace context_frame
emu.reg<uint32_t>(x64_register::eflags, context.EFlags);
}
if (context.ContextFlags & CONTEXT_INTEGER)
if (context.ContextFlags & CONTEXT_INTEGER_64)
{
emu.reg(x64_register::rax, context.Rax);
emu.reg(x64_register::rbx, context.Rbx);
@@ -53,7 +53,7 @@ namespace context_frame
emu.reg<uint16_t>(x64_register::gs, context.SegGs);
}*/
if (context.ContextFlags & CONTEXT_FLOATING_POINT)
if (context.ContextFlags & CONTEXT_FLOATING_POINT_64)
{
emu.reg<uint16_t>(x64_register::fpcw, context.FltSave.ControlWord);
emu.reg<uint16_t>(x64_register::fpsw, context.FltSave.StatusWord);
@@ -66,7 +66,7 @@ namespace context_frame
}
}
if (context.ContextFlags & CONTEXT_XSTATE)
if (context.ContextFlags & CONTEXT_XSTATE_64)
{
emu.reg<uint32_t>(x64_register::mxcsr, context.MxCsr);
@@ -78,9 +78,9 @@ namespace context_frame
}
}
void save(x64_emulator& emu, CONTEXT& context)
void save(x64_emulator& emu, CONTEXT64& context)
{
if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS)
if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64)
{
context.Dr0 = emu.reg(x64_register::dr0);
context.Dr1 = emu.reg(x64_register::dr1);
@@ -90,7 +90,7 @@ namespace context_frame
context.Dr7 = emu.reg(x64_register::dr7);
}
if (context.ContextFlags & CONTEXT_CONTROL)
if (context.ContextFlags & CONTEXT_CONTROL_64)
{
context.SegSs = emu.reg<uint16_t>(x64_register::ss);
context.SegCs = emu.reg<uint16_t>(x64_register::cs);
@@ -99,7 +99,7 @@ namespace context_frame
context.EFlags = emu.reg<uint32_t>(x64_register::eflags);
}
if (context.ContextFlags & CONTEXT_INTEGER)
if (context.ContextFlags & CONTEXT_INTEGER_64)
{
context.Rax = emu.reg(x64_register::rax);
context.Rbx = emu.reg(x64_register::rbx);
@@ -118,7 +118,7 @@ namespace context_frame
context.R15 = emu.reg(x64_register::r15);
}
if (context.ContextFlags & CONTEXT_SEGMENTS)
if (context.ContextFlags & CONTEXT_SEGMENTS_64)
{
context.SegDs = emu.reg<uint16_t>(x64_register::ds);
context.SegEs = emu.reg<uint16_t>(x64_register::es);
@@ -126,7 +126,7 @@ namespace context_frame
context.SegGs = emu.reg<uint16_t>(x64_register::gs);
}
if (context.ContextFlags & CONTEXT_FLOATING_POINT)
if (context.ContextFlags & CONTEXT_FLOATING_POINT_64)
{
context.FltSave.ControlWord = emu.reg<uint16_t>(x64_register::fpcw);
context.FltSave.StatusWord = emu.reg<uint16_t>(x64_register::fpsw);
@@ -138,7 +138,7 @@ namespace context_frame
}
}
if (context.ContextFlags & CONTEXT_XSTATE)
if (context.ContextFlags & CONTEXT_XSTATE_64)
{
context.MxCsr = emu.reg<uint32_t>(x64_register::mxcsr);
for (int i = 0; i < 16; i++)

View File

@@ -3,6 +3,6 @@
namespace context_frame
{
void save(x64_emulator& emu, CONTEXT& context);
void restore(x64_emulator& emu, const CONTEXT& context);
void save(x64_emulator& emu, CONTEXT64& context);
void restore(x64_emulator& emu, const CONTEXT64& context);
}

View File

@@ -35,4 +35,5 @@ struct gdb_stub_handler
virtual void on_interrupt() = 0;
};
bool run_gdb_stub(gdb_stub_handler& handler, std::string target_description, size_t register_count, std::string bind_address);
bool run_gdb_stub(gdb_stub_handler& handler, std::string target_description, size_t register_count,
std::string bind_address);

View File

@@ -32,23 +32,23 @@ namespace
return win_emu.emu().read_memory<afd_creation_data>(data.buffer);
}
std::pair<AFD_POLL_INFO, std::vector<AFD_POLL_HANDLE_INFO>> get_poll_info(
std::pair<AFD_POLL_INFO64, std::vector<AFD_POLL_HANDLE_INFO64>> get_poll_info(
windows_emulator& win_emu, const io_device_context& c)
{
constexpr auto info_size = offsetof(AFD_POLL_INFO, Handles);
constexpr auto info_size = offsetof(AFD_POLL_INFO64, Handles);
if (!c.input_buffer || c.input_buffer_length < info_size)
{
throw std::runtime_error("Bad AFD poll data");
}
AFD_POLL_INFO poll_info{};
AFD_POLL_INFO64 poll_info{};
win_emu.emu().read_memory(c.input_buffer, &poll_info, info_size);
std::vector<AFD_POLL_HANDLE_INFO> handle_info{};
std::vector<AFD_POLL_HANDLE_INFO64> handle_info{};
const emulator_object<AFD_POLL_HANDLE_INFO> handle_info_obj{win_emu.emu(), c.input_buffer + info_size};
const emulator_object<AFD_POLL_HANDLE_INFO64> handle_info_obj{win_emu.emu(), c.input_buffer + info_size};
if (c.input_buffer_length < (info_size + sizeof(AFD_POLL_HANDLE_INFO) * poll_info.NumberOfHandles))
if (c.input_buffer_length < (info_size + sizeof(AFD_POLL_HANDLE_INFO64) * poll_info.NumberOfHandles))
{
throw std::runtime_error("Bad AFD poll handle data");
}
@@ -126,7 +126,7 @@ namespace
NTSTATUS perform_poll(windows_emulator& win_emu, const io_device_context& c,
const std::span<const SOCKET> endpoints,
const std::span<const AFD_POLL_HANDLE_INFO> handles)
const std::span<const AFD_POLL_HANDLE_INFO64> handles)
{
std::vector<pollfd> poll_data{};
poll_data.resize(endpoints.size());
@@ -147,8 +147,8 @@ namespace
return STATUS_PENDING;
}
constexpr auto info_size = offsetof(AFD_POLL_INFO, Handles);
const emulator_object<AFD_POLL_HANDLE_INFO> handle_info_obj{win_emu.emu(), c.input_buffer + info_size};
constexpr auto info_size = offsetof(AFD_POLL_INFO64, Handles);
const emulator_object<AFD_POLL_HANDLE_INFO64> handle_info_obj{win_emu.emu(), c.input_buffer + info_size};
size_t current_index = 0;
@@ -170,7 +170,7 @@ namespace
assert(current_index == static_cast<size_t>(count));
emulator_object<AFD_POLL_INFO>{win_emu.emu(), c.input_buffer}.access([&](AFD_POLL_INFO& info)
emulator_object<AFD_POLL_INFO64>{win_emu.emu(), c.input_buffer}.access([&](AFD_POLL_INFO64& info)
{
info.NumberOfHandles = static_cast<ULONG>(current_index);
});
@@ -354,7 +354,7 @@ namespace
}
const auto* address = reinterpret_cast<const sockaddr*>(data.data() + address_offset);
const auto address_size = static_cast<int>(data.size() - address_offset);
const auto address_size = static_cast<socklen_t>(data.size() - address_offset);
const network::address addr(address, address_size);
@@ -367,7 +367,7 @@ namespace
}
static std::vector<SOCKET> resolve_endpoints(windows_emulator& win_emu,
const std::span<const AFD_POLL_HANDLE_INFO> handles)
const std::span<const AFD_POLL_HANDLE_INFO64> handles)
{
auto& proc = win_emu.process();
@@ -376,7 +376,7 @@ namespace
for (const auto& handle : handles)
{
auto* device = proc.devices.get(reinterpret_cast<uint64_t>(handle.Handle));
auto* device = proc.devices.get(handle.Handle);
if (!device)
{
throw std::runtime_error("Bad device!");
@@ -428,17 +428,17 @@ namespace
{
auto& emu = win_emu.emu();
if (c.input_buffer_length < sizeof(AFD_RECV_DATAGRAM_INFO))
if (c.input_buffer_length < sizeof(AFD_RECV_DATAGRAM_INFO<EmulatorTraits<Emu64>>))
{
return STATUS_BUFFER_TOO_SMALL;
}
const auto receive_info = emu.read_memory<AFD_RECV_DATAGRAM_INFO>(c.input_buffer);
const auto buffer = emu.read_memory<WSABUF>(receive_info.BufferArray);
const auto receive_info = emu.read_memory<AFD_RECV_DATAGRAM_INFO<EmulatorTraits<Emu64>>>(c.input_buffer);
const auto buffer = emu.read_memory<EMU_WSABUF<EmulatorTraits<Emu64>>>(receive_info.BufferArray);
std::vector<std::byte> address{};
ULONG address_length = 0x1000;
unsigned long address_length = 0x1000;
if (receive_info.AddressLength)
{
address_length = emu.read_memory<ULONG>(receive_info.AddressLength);
@@ -451,12 +451,12 @@ namespace
return STATUS_INVALID_PARAMETER;
}
int fromlength = static_cast<int>(address.size());
auto fromlength = static_cast<socklen_t>(address.size());
std::vector<char> data{};
data.resize(buffer.len);
const auto recevied_data = recvfrom(*this->s_, data.data(), static_cast<int>(data.size()), 0,
const auto recevied_data = recvfrom(*this->s_, data.data(), static_cast<send_size>(data.size()), 0,
reinterpret_cast<sockaddr*>(address.data()), &fromlength);
if (recevied_data < 0)
@@ -482,7 +482,7 @@ namespace
if (c.io_status_block)
{
IO_STATUS_BLOCK block{};
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
block.Information = static_cast<uint32_t>(recevied_data);
c.io_status_block.write(block);
}
@@ -494,24 +494,24 @@ namespace
{
const auto& emu = win_emu.emu();
if (c.input_buffer_length < sizeof(AFD_SEND_DATAGRAM_INFO))
if (c.input_buffer_length < sizeof(AFD_SEND_DATAGRAM_INFO<EmulatorTraits<Emu64>>))
{
return STATUS_BUFFER_TOO_SMALL;
}
const auto send_info = emu.read_memory<AFD_SEND_DATAGRAM_INFO>(c.input_buffer);
const auto buffer = emu.read_memory<WSABUF>(send_info.BufferArray);
const auto send_info = emu.read_memory<AFD_SEND_DATAGRAM_INFO<EmulatorTraits<Emu64>>>(c.input_buffer);
const auto buffer = emu.read_memory<EMU_WSABUF<EmulatorTraits<Emu64>>>(send_info.BufferArray);
const auto address = emu.read_memory(send_info.TdiConnInfo.RemoteAddress,
send_info.TdiConnInfo.RemoteAddressLength);
static_cast<size_t>(send_info.TdiConnInfo.RemoteAddressLength));
const network::address target(reinterpret_cast<const sockaddr*>(address.data()),
static_cast<int>(address.size()));
static_cast<socklen_t>(address.size()));
const auto data = emu.read_memory(buffer.buf, buffer.len);
const auto sent_data = sendto(*this->s_, reinterpret_cast<const char*>(data.data()),
static_cast<int>(data.size()), 0 /* ? */, &target.get_addr(),
static_cast<send_size>(data.size()), 0 /* ? */, &target.get_addr(),
target.get_size());
if (sent_data < 0)
@@ -528,7 +528,7 @@ namespace
if (c.io_status_block)
{
IO_STATUS_BLOCK block{};
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
block.Information = static_cast<uint32_t>(sent_data);
c.io_status_block.write(block);
}

View File

@@ -3,87 +3,93 @@
#include "../std_include.hpp"
typedef LONG TDI_STATUS;
typedef PVOID CONNECTION_CONTEXT;
typedef struct _TDI_CONNECTION_INFORMATION
template <typename Traits>
struct TDI_CONNECTION_INFORMATION
{
LONG UserDataLength;
PVOID UserData;
typename Traits::PVOID UserData;
LONG OptionsLength;
PVOID Options;
typename Traits::PVOID Options;
LONG RemoteAddressLength;
PVOID RemoteAddress;
} TDI_CONNECTION_INFORMATION, *PTDI_CONNECTION_INFORMATION;
typename Traits::PVOID RemoteAddress;
};
typedef struct _TDI_REQUEST
template <typename Traits>
struct TDI_REQUEST
{
union
{
HANDLE AddressHandle;
CONNECTION_CONTEXT ConnectionContext;
HANDLE ControlChannel;
typename Traits::HANDLE AddressHandle;
EMULATOR_CAST(typename Traits::PVOID, CONNECTION_CONTEXT) ConnectionContext;
typename Traits::HANDLE ControlChannel;
} Handle;
PVOID RequestNotifyObject;
PVOID RequestContext;
typename Traits::PVOID RequestNotifyObject;
typename Traits::PVOID RequestContext;
TDI_STATUS TdiStatus;
} TDI_REQUEST, *PTDI_REQUEST;
};
typedef struct _TDI_REQUEST_SEND_DATAGRAM
template <typename Traits>
struct TDI_REQUEST_SEND_DATAGRAM
{
TDI_REQUEST Request;
PTDI_CONNECTION_INFORMATION SendDatagramInformation;
} TDI_REQUEST_SEND_DATAGRAM, *PTDI_REQUEST_SEND_DATAGRAM;
TDI_REQUEST<Traits> Request;
EMULATOR_CAST(typename Traits::PVOID, PTDI_CONNECTION_INFORMATION) SendDatagramInformation;
};
typedef struct _AFD_SEND_INFO
template <typename Traits>
struct AFD_SEND_INFO
{
LPWSABUF BufferArray;
EMULATOR_CAST(typename Traits::PVOID, LPWSABUF) BufferArray;
ULONG BufferCount;
ULONG AfdFlags;
ULONG TdiFlags;
} AFD_SEND_INFO, *PAFD_SEND_INFO;
};
typedef struct _AFD_SEND_DATAGRAM_INFO
template <typename Traits>
struct AFD_SEND_DATAGRAM_INFO
{
LPWSABUF BufferArray;
EMULATOR_CAST(typename Traits::PVOID, LPWSABUF) BufferArray;
ULONG BufferCount;
ULONG AfdFlags;
TDI_REQUEST_SEND_DATAGRAM TdiRequest;
TDI_CONNECTION_INFORMATION TdiConnInfo;
} AFD_SEND_DATAGRAM_INFO, *PAFD_SEND_DATAGRAM_INFO;
TDI_REQUEST_SEND_DATAGRAM<Traits> TdiRequest;
TDI_CONNECTION_INFORMATION<Traits> TdiConnInfo;
};
typedef struct _AFD_RECV_INFO
template <typename Traits>
struct AFD_RECV_INFO
{
LPWSABUF BufferArray;
EMULATOR_CAST(typename Traits::PVOID, LPWSABUF) BufferArray;
ULONG BufferCount;
ULONG AfdFlags;
ULONG TdiFlags;
} AFD_RECV_INFO, *PAFD_RECV_INFO;
};
typedef struct _AFD_RECV_DATAGRAM_INFO
template <typename Traits>
struct AFD_RECV_DATAGRAM_INFO
{
LPWSABUF BufferArray;
EMULATOR_CAST(typename Traits::PVOID, LPWSABUF) BufferArray;
ULONG BufferCount;
ULONG AfdFlags;
ULONG TdiFlags;
PVOID Address;
PULONG AddressLength;
} AFD_RECV_DATAGRAM_INFO, *PAFD_RECV_DATAGRAM_INFO;
typename Traits::PVOID Address;
EMULATOR_CAST(typename Traits::PVOID, PULONG) AddressLength;
};
typedef struct _AFD_POLL_HANDLE_INFO
struct AFD_POLL_HANDLE_INFO64
{
HANDLE Handle;
EmulatorTraits<Emu64>::HANDLE Handle;
ULONG PollEvents;
NTSTATUS Status;
} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO;
};
typedef struct _AFD_POLL_INFO
struct AFD_POLL_INFO64
{
LARGE_INTEGER Timeout;
ULONG NumberOfHandles;
BOOLEAN Unique;
AFD_POLL_HANDLE_INFO Handles[1];
} AFD_POLL_INFO, *PAFD_POLL_INFO;
AFD_POLL_HANDLE_INFO64 Handles[1];
};
#define AFD_POLL_RECEIVE_BIT 0
#define AFD_POLL_RECEIVE (1 << AFD_POLL_RECEIVE_BIT)

View File

@@ -140,6 +140,8 @@ private:
uint64_t address_{};
};
// TODO: warning emulator_utils is hardcoded for 64bit unicode_string usage
class emulator_allocator
{
public:
@@ -179,14 +181,15 @@ public:
return emulator_object<T>(*this->emu_, potential_start);
}
wchar_t* copy_string(const std::wstring_view str)
char16_t* copy_string(const std::u16string_view str)
{
UNICODE_STRING uc_str{};
UNICODE_STRING<EmulatorTraits<Emu64>> uc_str{};
this->make_unicode_string(uc_str, str);
return uc_str.Buffer;
return reinterpret_cast<char16_t*>(uc_str.Buffer);
}
void make_unicode_string(UNICODE_STRING& result, const std::wstring_view str)
void make_unicode_string(UNICODE_STRING<EmulatorTraits<Emu64>>& result, const std::u16string_view str)
{
constexpr auto element_size = sizeof(str[0]);
constexpr auto required_alignment = alignof(decltype(str[0]));
@@ -199,16 +202,16 @@ public:
constexpr std::array<char, element_size> nullbyte{};
this->emu_->write_memory(string_buffer + total_length, nullbyte.data(), nullbyte.size());
result.Buffer = reinterpret_cast<PWCH>(string_buffer);
result.Buffer = string_buffer;
result.Length = static_cast<USHORT>(total_length);
result.MaximumLength = static_cast<USHORT>(total_length + element_size);
}
emulator_object<UNICODE_STRING> make_unicode_string(const std::wstring_view str)
emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> make_unicode_string(const std::u16string_view str)
{
const auto unicode_string = this->reserve<UNICODE_STRING>();
const auto unicode_string = this->reserve<UNICODE_STRING<EmulatorTraits<Emu64>>>();
unicode_string.access([&](UNICODE_STRING& unicode_str)
unicode_string.access([&](UNICODE_STRING<EmulatorTraits<Emu64>>& unicode_str)
{
this->make_unicode_string(unicode_str, str);
});
@@ -267,29 +270,31 @@ private:
uint64_t active_address_{0};
};
inline std::wstring read_unicode_string(const emulator& emu, const UNICODE_STRING ucs)
{
static_assert(offsetof(UNICODE_STRING, Length) == 0);
static_assert(offsetof(UNICODE_STRING, MaximumLength) == 2);
static_assert(offsetof(UNICODE_STRING, Buffer) == 8);
static_assert(sizeof(UNICODE_STRING) == 16);
std::wstring result{};
inline std::u16string read_unicode_string(const emulator& emu, const UNICODE_STRING<EmulatorTraits<Emu64>> ucs)
{
static_assert(offsetof(UNICODE_STRING<EmulatorTraits<Emu64>>, Length) == 0);
static_assert(offsetof(UNICODE_STRING<EmulatorTraits<Emu64>>, MaximumLength) == 2);
static_assert(offsetof(UNICODE_STRING<EmulatorTraits<Emu64>>, Buffer) == 8);
static_assert(sizeof(UNICODE_STRING<EmulatorTraits<Emu64>>) == 16);
std::u16string result{};
result.resize(ucs.Length / 2);
emu.read_memory(reinterpret_cast<uint64_t>(ucs.Buffer), result.data(), ucs.Length);
emu.read_memory(ucs.Buffer, result.data(), ucs.Length);
return result;
}
inline std::wstring read_unicode_string(const emulator& emu, const emulator_object<UNICODE_STRING> uc_string)
inline std::u16string read_unicode_string(const emulator& emu,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> uc_string)
{
const auto ucs = uc_string.read();
return read_unicode_string(emu, ucs);
}
inline std::wstring read_unicode_string(emulator& emu, const UNICODE_STRING* uc_string)
inline std::u16string read_unicode_string(emulator& emu, const UNICODE_STRING<EmulatorTraits<Emu64>>* uc_string)
{
return read_unicode_string(emu, emulator_object<UNICODE_STRING>{emu, uc_string});
return read_unicode_string(emu, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>{emu, uc_string});
}

View File

@@ -34,21 +34,25 @@ struct handle_value
static_assert(sizeof(handle_value) == 8);
// TODO: this is a concrete 64bit handle
union handle
{
handle_value value;
uint64_t bits;
HANDLE h;
std::uint64_t h;
};
inline void serialize(utils::buffer_serializer& buffer, const handle& h)
namespace utils
{
buffer.write(h.bits);
}
inline void serialize(buffer_serializer& buffer, const handle& h)
{
buffer.write(h.bits);
}
inline void deserialize(utils::buffer_deserializer& buffer, handle& h)
{
buffer.read(h.bits);
inline void deserialize(buffer_deserializer& buffer, handle& h)
{
buffer.read(h.bits);
}
}
inline bool operator==(const handle& h1, const handle& h2)

View File

@@ -12,21 +12,21 @@ namespace
};
}
std::unique_ptr<io_device> create_device(const std::wstring_view device)
std::unique_ptr<io_device> create_device(const std::u16string_view device)
{
if (device == L"CNG"
|| device == L"KsecDD"
|| device == L"PcwDrv"
|| device == L"DeviceApi\\CMApi"
|| device == L"ConDrv\\Server")
if (device == u"CNG"
|| device == u"KsecDD"
|| device == u"PcwDrv"
|| device == u"DeviceApi\\CMApi"
|| device == u"ConDrv\\Server")
{
return std::make_unique<dummy_device>();
}
if (device == L"Afd\\Endpoint")
if (device == u"Afd\\Endpoint")
{
return create_afd_endpoint();
}
throw std::runtime_error("Unsupported device: " + std::string(device.begin(), device.end()));
throw std::runtime_error("Unsupported device: " + u16_to_u8(device));
}

View File

@@ -15,7 +15,7 @@ struct io_device_context
handle event{};
emulator_pointer /*PIO_APC_ROUTINE*/ apc_routine{};
emulator_pointer apc_context{};
emulator_object<IO_STATUS_BLOCK> io_status_block;
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block;
ULONG io_control_code{};
emulator_pointer input_buffer{};
ULONG input_buffer_length{};
@@ -65,11 +65,12 @@ struct io_device_creation_data
uint32_t length;
};
inline void write_io_status(const emulator_object<IO_STATUS_BLOCK> io_status_block, const NTSTATUS status)
inline void write_io_status(const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
const NTSTATUS status)
{
if (io_status_block)
{
io_status_block.access([&](IO_STATUS_BLOCK& status_block)
io_status_block.access([&](IO_STATUS_BLOCK<EmulatorTraits<Emu64>>& status_block)
{
status_block.Status = status;
});
@@ -131,14 +132,14 @@ struct stateless_device : io_device
}
};
std::unique_ptr<io_device> create_device(std::wstring_view device);
std::unique_ptr<io_device> create_device(std::u16string_view device);
class io_device_container : public io_device
{
public:
io_device_container() = default;
io_device_container(std::wstring device, windows_emulator& win_emu, const io_device_creation_data& data)
io_device_container(std::u16string device, windows_emulator& win_emu, const io_device_creation_data& data)
: device_name_(std::move(device))
{
this->setup();
@@ -182,7 +183,7 @@ public:
}
private:
std::wstring device_name_{};
std::u16string device_name_{};
std::unique_ptr<io_device> device_{};
void setup()

View File

@@ -5,14 +5,14 @@
#include <address_utils.hpp>
constexpr auto KUSD_ADDRESS = 0x7ffe0000ULL;
constexpr auto KUSD_SIZE = sizeof(KUSER_SHARED_DATA);
constexpr auto KUSD_SIZE = sizeof(KUSER_SHARED_DATA64);
constexpr auto KUSD_BUFFER_SIZE = page_align_up(KUSD_SIZE);
namespace
{
void setup_kusd(KUSER_SHARED_DATA& kusd, const bool use_relative_time)
void setup_kusd(KUSER_SHARED_DATA64& kusd, const bool use_relative_time)
{
memset(&kusd, 0, sizeof(kusd));
memset(reinterpret_cast<void*>(&kusd), 0, sizeof(kusd));
kusd.TickCountMultiplier = 0x0fa00000;
kusd.InterruptTime.LowPart = 0x17bd9547;
@@ -88,15 +88,18 @@ namespace
}
}
inline void serialize(utils::buffer_serializer& buffer, const KUSER_SHARED_DATA& kusd)
namespace utils
{
static_assert(KUSD_SIZE == sizeof(kusd));
buffer.write(&kusd, KUSD_SIZE);
}
inline void serialize(buffer_serializer& buffer, const KUSER_SHARED_DATA64& kusd)
{
static_assert(KUSD_SIZE == sizeof(kusd));
buffer.write(&kusd, KUSD_SIZE);
}
inline void deserialize(utils::buffer_deserializer& buffer, KUSER_SHARED_DATA& kusd)
{
buffer.read(&kusd, KUSD_SIZE);
inline void deserialize(buffer_deserializer& buffer, KUSER_SHARED_DATA64& kusd)
{
buffer.read(&kusd, KUSD_SIZE);
}
}
kusd_mmio::kusd_mmio(x64_emulator& emu, process_context& process)
@@ -154,7 +157,7 @@ uint64_t kusd_mmio::read(const uint64_t addr, const size_t size)
}
const auto end = addr + size;
const auto valid_end = std::min(end, KUSD_SIZE);
const auto valid_end = std::min(end, static_cast<uint64_t>(KUSD_SIZE));
const auto real_size = valid_end - addr;
if (real_size > sizeof(result))
@@ -180,7 +183,7 @@ void kusd_mmio::update()
if (this->use_relative_time_)
{
const auto passed_time = this->process_->executed_instructions;
const auto clock_frequency = this->kusd_.QpcFrequency;
const auto clock_frequency = static_cast<uint64_t>(this->kusd_.QpcFrequency);
using duration = std::chrono::system_clock::duration;
time += duration(passed_time * duration::period::den / clock_frequency);
@@ -206,7 +209,7 @@ void kusd_mmio::register_mmio()
[this](const uint64_t addr, const size_t size)
{
return this->read(addr, size);
}, [this](const uint64_t, const size_t, const uint64_t)
}, [](const uint64_t, const size_t, const uint64_t)
{
// Writing not supported!
});

View File

@@ -24,12 +24,12 @@ public:
void serialize(utils::buffer_serializer& buffer) const;
void deserialize(utils::buffer_deserializer& buffer);
KUSER_SHARED_DATA& get()
KUSER_SHARED_DATA64& get()
{
return this->kusd_;
}
const KUSER_SHARED_DATA& get() const
const KUSER_SHARED_DATA64& get() const
{
return this->kusd_;
}
@@ -45,7 +45,7 @@ private:
bool registered_{};
bool use_relative_time_{};
KUSER_SHARED_DATA kusd_{};
KUSER_SHARED_DATA64 kusd_{};
std::chrono::system_clock::time_point start_time_{};
uint64_t read(uint64_t addr, size_t size);

View File

@@ -75,6 +75,12 @@ namespace
return {buffer, static_cast<size_t>(count)};
}
#define format_to_string(msg, str)\
va_list ap;\
va_start(ap, msg);\
const auto str = format(&ap, msg);\
va_end(ap);
void print_colored(const std::string_view& line, const color_type base_color)
{
const auto _ = utils::finally(&reset_color);
@@ -83,18 +89,48 @@ namespace
}
}
void logger::print(const color c, const char* message, ...) const
void logger::print(const color c, const std::string_view message) const
{
if (this->disable_output_)
{
return;
}
va_list ap;
va_start(ap, message);
const auto data = format(&ap, message);
print_colored(data, get_color_type(c));
va_end(ap);
print_colored(message, get_color_type(c));
}
void logger::print(const color c, const char* message, ...) const
{
format_to_string(message, data);
this->print(c, data);
}
void logger::info(const char* message, ...) const
{
format_to_string(message, data);
this->print(color::cyan, data);
}
void logger::warn(const char* message, ...) const
{
format_to_string(message, data);
this->print(color::yellow, data);
}
void logger::error(const char* message, ...) const
{
format_to_string(message, data);
this->print(color::red, data);
}
void logger::success(const char* message, ...) const
{
format_to_string(message, data);
this->print(color::green, data);
}
void logger::log(const char* message, ...) const
{
format_to_string(message, data);
this->print(color::gray, data);
}

View File

@@ -1,5 +1,11 @@
#pragma once
#ifdef OS_WINDOWS
#define FORMAT_ATTRIBUTE(fmt_pos, var_pos)
#else
#define FORMAT_ATTRIBUTE(fmt_pos, var_pos) __attribute__((format( printf, fmt_pos, var_pos)))
#endif
enum class color
{
black,
@@ -17,37 +23,13 @@ enum class color
class logger
{
public:
void print(color c, const char* message, ...) const;
template <typename... Args>
void info(const char* message, Args... args)
{
this->print(color::cyan, message, args...);
}
template <typename... Args>
void warn(const char* message, Args... args)
{
this->print(color::yellow, message, args...);
}
template <typename... Args>
void error(const char* message, Args... args)
{
this->print(color::red, message, args...);
}
template <typename... Args>
void success(const char* message, Args... args)
{
this->print(color::green, message, args...);
}
template <typename... Args>
void log(const char* message, Args... args)
{
this->print(color::gray, message, args...);
}
void print(color c, std::string_view message) const;
void print(color c, const char* message, ...) const FORMAT_ATTRIBUTE(3, 4);
void info(const char* message, ...) const FORMAT_ATTRIBUTE(2, 3);
void warn(const char* message, ...) const FORMAT_ATTRIBUTE(2, 3);
void error(const char* message, ...) const FORMAT_ATTRIBUTE(2, 3);
void success(const char* message, ...) const FORMAT_ATTRIBUTE(2, 3);
void log(const char* message, ...) const FORMAT_ATTRIBUTE(2, 3);
void disable_output(const bool value)
{

View File

@@ -21,7 +21,7 @@ inline std::string get_permission_string(const memory_permission permission)
inline memory_permission map_nt_to_emulator_protection(uint32_t nt_protection)
{
nt_protection &= ~PAGE_GUARD; // TODO: Implement that
nt_protection &= ~static_cast<uint32_t>(PAGE_GUARD); // TODO: Implement that
switch (nt_protection)
{

View File

@@ -19,46 +19,49 @@ namespace
}
}
static void serialize(utils::buffer_serializer& buffer, const exported_symbol& sym)
namespace utils
{
buffer.write(sym.name);
buffer.write(sym.ordinal);
buffer.write(sym.rva);
buffer.write(sym.address);
}
static void serialize(buffer_serializer& buffer, const exported_symbol& sym)
{
buffer.write(sym.name);
buffer.write(sym.ordinal);
buffer.write(sym.rva);
buffer.write(sym.address);
}
static void deserialize(utils::buffer_deserializer& buffer, exported_symbol& sym)
{
buffer.read(sym.name);
buffer.read(sym.ordinal);
buffer.read(sym.rva);
buffer.read(sym.address);
}
static void deserialize(buffer_deserializer& buffer, exported_symbol& sym)
{
buffer.read(sym.name);
buffer.read(sym.ordinal);
buffer.read(sym.rva);
buffer.read(sym.address);
}
static void serialize(utils::buffer_serializer& buffer, const mapped_module& mod)
{
buffer.write_string(mod.name);
buffer.write_string(mod.path.wstring());
static void serialize(buffer_serializer& buffer, const mapped_module& mod)
{
buffer.write_string(mod.name);
buffer.write(mod.path.u16string());
buffer.write(mod.image_base);
buffer.write(mod.size_of_image);
buffer.write(mod.entry_point);
buffer.write(mod.image_base);
buffer.write(mod.size_of_image);
buffer.write(mod.entry_point);
buffer.write_vector(mod.exports);
buffer.write_map(mod.address_names);
}
buffer.write_vector(mod.exports);
buffer.write_map(mod.address_names);
}
static void deserialize(utils::buffer_deserializer& buffer, mapped_module& mod)
{
mod.name = buffer.read_string();
mod.path = buffer.read_string<wchar_t>();
static void deserialize(buffer_deserializer& buffer, mapped_module& mod)
{
mod.name = buffer.read_string();
mod.path = buffer.read_string<std::u16string::value_type>();
buffer.read(mod.image_base);
buffer.read(mod.size_of_image);
buffer.read(mod.entry_point);
buffer.read(mod.image_base);
buffer.read(mod.size_of_image);
buffer.read(mod.entry_point);
buffer.read_vector(mod.exports);
buffer.read_map(mod.address_names);
buffer.read_vector(mod.exports);
buffer.read_map(mod.address_names);
}
}
module_manager::module_manager(emulator& emu)
@@ -82,7 +85,7 @@ mapped_module* module_manager::map_module(const std::filesystem::path& file, log
{
auto mod = map_module_from_file(*this->emu_, std::move(canonical_file));
logger.log("Mapped %s at 0x%llX\n", mod.path.generic_string().c_str(), mod.image_base);
logger.log("Mapped %s at 0x%" PRIx64 "\n", mod.path.generic_string().c_str(), mod.image_base);
const auto image_base = mod.image_base;
const auto entry = this->modules_.try_emplace(image_base, std::move(mod));

View File

@@ -7,9 +7,15 @@
namespace
{
uint64_t get_first_section_offset(const IMAGE_NT_HEADERS& nt_headers, const uint64_t nt_headers_offset)
uint64_t get_first_section_offset(const PENTHeaders_t<std::uint64_t>& nt_headers, const uint64_t nt_headers_offset)
{
const auto first_section_absolute = reinterpret_cast<uint64_t>(IMAGE_FIRST_SECTION(&nt_headers));
const uint8_t* nt_headers_addr = reinterpret_cast<const uint8_t*>(&nt_headers);
size_t optional_header_offset = reinterpret_cast<uintptr_t>(&(nt_headers.OptionalHeader)) - reinterpret_cast<
uintptr_t>(&nt_headers);
size_t optional_header_size = nt_headers.FileHeader.SizeOfOptionalHeader;
const uint8_t* first_section_addr = nt_headers_addr + optional_header_offset + optional_header_size;
const auto first_section_absolute = reinterpret_cast<uint64_t>(first_section_addr);
const auto absolute_base = reinterpret_cast<uint64_t>(&nt_headers);
return nt_headers_offset + (first_section_absolute - absolute_base);
}
@@ -24,7 +30,7 @@ namespace
}
void collect_exports(mapped_module& binary, const utils::safe_buffer_accessor<const uint8_t> buffer,
const IMAGE_OPTIONAL_HEADER& optional_header)
const PEOptionalHeader_t<std::uint64_t>& optional_header)
{
auto& export_directory_entry = optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if (export_directory_entry.VirtualAddress == 0 || export_directory_entry.Size == 0)
@@ -75,7 +81,7 @@ namespace
}
void apply_relocations(const mapped_module& binary, const utils::safe_buffer_accessor<uint8_t> buffer,
const IMAGE_OPTIONAL_HEADER& optional_header)
const PEOptionalHeader_t<std::uint64_t>& optional_header)
{
const auto delta = binary.image_base - optional_header.ImageBase;
if (delta == 0)
@@ -113,7 +119,7 @@ namespace
const auto entry = entries.get(i);
const int type = entry >> 12;
const int offset = entry & 0xfff;
const auto offset = static_cast<uint16_t>(entry & 0xfff);
const auto total_offset = relocation.VirtualAddress + offset;
switch (type)
@@ -138,7 +144,7 @@ namespace
void map_sections(emulator& emu, mapped_module& binary,
const utils::safe_buffer_accessor<const uint8_t> buffer,
const IMAGE_NT_HEADERS& nt_headers, const uint64_t nt_headers_offset)
const PENTHeaders_t<std::uint64_t>& nt_headers, const uint64_t nt_headers_offset)
{
const auto first_section_offset = get_first_section_offset(nt_headers, nt_headers_offset);
const auto sections = buffer.as<IMAGE_SECTION_HEADER>(first_section_offset);
@@ -200,13 +206,13 @@ mapped_module map_module_from_data(emulator& emu, const std::span<const uint8_t>
utils::safe_buffer_accessor buffer{data};
const auto dos_header = buffer.as<IMAGE_DOS_HEADER>(0).get();
const auto dos_header = buffer.as<PEDosHeader_t>(0).get();
const auto nt_headers_offset = dos_header.e_lfanew;
const auto nt_headers = buffer.as<IMAGE_NT_HEADERS>(nt_headers_offset).get();
const auto nt_headers = buffer.as<PENTHeaders_t<std::uint64_t>>(nt_headers_offset).get();
auto& optional_header = nt_headers.OptionalHeader;
if (nt_headers.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64)
if (nt_headers.FileHeader.Machine != PEMachineType::AMD64)
{
throw std::runtime_error("Unsupported architecture!");
}

View File

@@ -4,7 +4,7 @@
#include "mapped_module.hpp"
mapped_module map_module_from_data(emulator& emu, std::span<const uint8_t> data,
std::filesystem::path file);
std::filesystem::path file);
mapped_module map_module_from_file(emulator& emu, std::filesystem::path file);
bool unmap_module(emulator& emu, const mapped_module& mod);

View File

@@ -51,7 +51,7 @@ struct event : ref_counted_object
{
bool signaled{};
EVENT_TYPE type{};
std::wstring name{};
std::u16string name{};
bool is_signaled()
{
@@ -88,7 +88,7 @@ struct mutant : ref_counted_object
{
uint32_t locked_count{0};
uint32_t owning_thread_id{};
std::wstring name{};
std::u16string name{};
bool try_lock(const uint32_t thread_id)
{
@@ -176,7 +176,7 @@ struct file_enumeration_state
struct file
{
utils::file_handle handle{};
std::wstring name{};
std::u16string name{};
std::optional<file_enumeration_state> enumeration_state{};
bool is_file() const
@@ -206,8 +206,8 @@ struct file
struct section
{
std::wstring name{};
std::wstring file_name{};
std::u16string name{};
std::u16string file_name{};
uint64_t maximum_size{};
uint32_t section_page_protection{};
uint32_t allocation_attributes{};
@@ -238,7 +238,7 @@ struct section
struct semaphore : ref_counted_object
{
std::wstring name{};
std::u16string name{};
volatile uint32_t current_count{};
uint32_t max_count{};
@@ -263,7 +263,7 @@ struct semaphore : ref_counted_object
struct port
{
std::wstring name{};
std::u16string name{};
uint64_t view_base{};
void serialize(utils::buffer_serializer& buffer) const
@@ -356,7 +356,7 @@ public:
uint32_t id{};
std::wstring name{};
std::u16string name{};
std::optional<NTSTATUS> exit_status{};
std::vector<handle> await_objects{};
@@ -368,7 +368,7 @@ public:
std::optional<NTSTATUS> pending_status{};
std::optional<emulator_allocator> gs_segment;
std::optional<emulator_object<TEB>> teb;
std::optional<emulator_object<TEB64>> teb;
std::vector<std::byte> last_registers{};
@@ -466,7 +466,7 @@ public:
buffer.read_optional(this->await_time);
buffer.read_optional(this->pending_status);
buffer.read_optional(this->gs_segment, [this] { return emulator_allocator(*this->emu_ptr); });
buffer.read_optional(this->teb, [this] { return emulator_object<TEB>(*this->emu_ptr); });
buffer.read_optional(this->teb, [this] { return emulator_object<TEB64>(*this->emu_ptr); });
buffer.read_vector(this->last_registers);
}
@@ -522,8 +522,8 @@ struct process_context
emulator_allocator base_allocator;
emulator_object<PEB> peb;
emulator_object<RTL_USER_PROCESS_PARAMETERS> process_params;
emulator_object<PEB64> peb;
emulator_object<RTL_USER_PROCESS_PARAMETERS64> process_params;
kusd_mmio kusd;
module_manager mod_manager;

View File

@@ -10,45 +10,45 @@ namespace
struct offset_entry_t
{
long offset;
long hash;
int32_t offset;
int32_t hash;
};
struct offsets_t
{
long block_size;
int32_t block_size;
char block_type[2];
short count;
int16_t count;
offset_entry_t entries[1];
};
struct key_block_t
{
long block_size;
int32_t block_size;
char block_type[2];
char dummya[18];
int subkey_count;
char dummyb[4];
int subkeys;
char dummyc[4];
int value_count;
int offsets;
char dummyd[28];
short len;
short du;
uint8_t dummya[18];
int32_t subkey_count;
uint8_t dummyb[4];
int32_t subkeys;
uint8_t dummyc[4];
int32_t value_count;
int32_t offsets;
uint8_t dummyd[28];
int16_t len;
int16_t du;
char name[255];
};
struct value_block_t
{
long block_size;
int32_t block_size;
char block_type[2];
short name_len;
long size;
long offset;
long value_type;
short flags;
short dummy;
int16_t name_len;
int32_t size;
int32_t offset;
int32_t value_type;
int16_t flags;
int16_t dummy;
char name[255];
};
@@ -206,7 +206,7 @@ void hive_key::parse(std::ifstream& file)
const auto subkey_block_offset = MAIN_ROOT_OFFSET + offset_entry.offset;
const auto subkey = read_file_object<key_block_t>(file, subkey_block_offset);
std::string subkey_name(subkey.name, std::min(subkey.len, static_cast<short>(sizeof(subkey.name))));
std::string subkey_name(subkey.name, std::min(subkey.len, static_cast<int16_t>(sizeof(subkey.name))));
utils::string::to_lower_inplace(subkey_name);
this->sub_keys_.emplace(std::move(subkey_name), hive_key{subkey.subkeys, subkey.value_count, subkey.offsets});

View File

@@ -1,6 +1,9 @@
#pragma once
#include <ranges>
#include <fstream>
#include <algorithm>
#include <utils/container.hpp>
struct hive_value

View File

@@ -2,8 +2,7 @@
#include "../std_include.hpp"
#include <serialization_helper.hpp>
class hive_parser;
#include "hive_parser.hpp"
struct registry_key
{

View File

@@ -28,9 +28,8 @@
#pragma warning(disable: 26498)
#pragma warning(disable: 26812)
#pragma warning(disable: 28020)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#pragma warning(pop)
#endif
#include <map>
#include <set>
@@ -56,25 +55,9 @@
#include <condition_variable>
#include <cassert>
#include <cstdarg>
#include <cinttypes>
#define NTDDI_WIN11_GE 0
#define PHNT_VERSION PHNT_WIN11
#include <phnt_windows.h>
#include <phnt.h>
#include <ntgdi.h>
#include <ws2def.h>
#ifdef _WIN32
#pragma warning(pop)
#endif
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
#endif
#include "platform/platform.hpp"
using namespace std::literals;

View File

@@ -93,10 +93,10 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
const auto* mod = context.mod_manager.find_by_address(address);
if (mod != context.ntdll && mod != context.win32u)
{
win_emu.log.print(color::blue, "Executing inline syscall: %s (0x%X) at 0x%llX (%s)\n",
entry->second.name.c_str(),
syscall_id,
address, mod ? mod->name.c_str() : "<N/A>");
win_emu.log.print(color::blue, "Executing inline syscall: %s (0x%X) at 0x%" PRIx64 " (%s)\n",
entry->second.name.c_str(),
syscall_id,
address, mod ? mod->name.c_str() : "<N/A>");
}
else
{
@@ -106,19 +106,21 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
const auto return_address = c.emu.read_memory<uint64_t>(rsp);
const auto* mod_name = context.mod_manager.find_name(return_address);
win_emu.log.print(color::dark_gray, "Executing syscall: %s (0x%X) at 0x%llX via 0x%llX (%s) %lld\n",
entry->second.name.c_str(),
syscall_id, address, return_address, mod_name, c.proc.executed_instructions);
win_emu.log.print(color::dark_gray,
"Executing syscall: %s (0x%X) at 0x%" PRIx64 " via 0x%" PRIx64 " (%s)\n",
entry->second.name.c_str(),
syscall_id, address, return_address, mod_name);
}
else
{
const auto* previous_mod = context.mod_manager.find_by_address(context.previous_ip);
win_emu.log.print(color::blue,
"Crafted out-of-line syscall: %s (0x%X) at 0x%llX (%s) via 0x%llX (%s)\n",
entry->second.name.c_str(),
syscall_id,
address, mod ? mod->name.c_str() : "<N/A>", context.previous_ip,
previous_mod ? previous_mod->name.c_str() : "<N/A>");
"Crafted out-of-line syscall: %s (0x%X) at 0x%" PRIx64 " (%s) via 0x%" PRIx64
" (%s)\n",
entry->second.name.c_str(),
syscall_id,
address, mod ? mod->name.c_str() : "<N/A>", context.previous_ip,
previous_mod ? previous_mod->name.c_str() : "<N/A>");
}
}
@@ -126,13 +128,13 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
}
catch (std::exception& e)
{
printf("Syscall threw an exception: %X (0x%llX) - %s\n", syscall_id, address, e.what());
printf("Syscall threw an exception: %X (0x%" PRIx64 ") - %s\n", syscall_id, address, e.what());
emu.reg<uint64_t>(x64_register::rax, STATUS_UNSUCCESSFUL);
emu.stop();
}
catch (...)
{
printf("Syscall threw an unknown exception: %X (0x%llX)\n", syscall_id, address);
printf("Syscall threw an unknown exception: %X (0x%" PRIx64 ")\n", syscall_id, address);
emu.reg<uint64_t>(x64_register::rax, STATUS_UNSUCCESSFUL);
emu.stop();
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include "windows_emulator.hpp"
#include <ctime>
struct syscall_context
{
@@ -173,6 +174,8 @@ void forward_syscall(const syscall_context& c, NTSTATUS (*handler)(const syscall
resolve_indexed_argument<std::remove_cv_t<std::remove_reference_t<Args>>>(c.emu, index)...
};
(void)index;
const auto ret = std::apply(handler, std::move(func_args));
write_status(c, ret, ip);
}
@@ -186,12 +189,12 @@ syscall_handler make_syscall_handler()
};
}
template <typename T>
void write_attribute(emulator& emu, const PS_ATTRIBUTE& attribute, const T& value)
template <typename T, typename Traits>
void write_attribute(emulator& emu, const PS_ATTRIBUTE<Traits>& attribute, const T& value)
{
if (attribute.ReturnLength)
{
emulator_object<SIZE_T>{emu, attribute.ReturnLength}.write(sizeof(T));
emulator_object<typename Traits::SIZE_T>{emu, attribute.ReturnLength}.write(sizeof(T));
}
if (attribute.Size >= sizeof(T))
@@ -269,6 +272,10 @@ inline std::chrono::system_clock::time_point convert_from_ksystem_time(const vol
return convert_from_ksystem_time(*const_cast<const KSYSTEM_TIME*>(&time));
}
#ifndef OS_WINDOWS
using __time64_t = int64_t;
#endif
inline LARGE_INTEGER convert_unix_to_windows_time(const __time64_t unix_time)
{
LARGE_INTEGER windows_time{};

File diff suppressed because it is too large Load Diff

View File

@@ -14,8 +14,8 @@ namespace
emulator_object<T> allocate_object_on_stack(x64_emulator& emu)
{
const auto old_sp = emu.reg(x64_register::rsp);
const auto new_sp = align_down(old_sp - sizeof(CONTEXT),
std::max(alignof(CONTEXT), alignof(x64_emulator::pointer_type)));
const auto new_sp = align_down(old_sp - sizeof(CONTEXT64),
std::max(alignof(CONTEXT64), alignof(x64_emulator::pointer_type)));
emu.reg(x64_register::rsp, new_sp);
return {emu, new_sp};
@@ -143,8 +143,13 @@ namespace
emulator_object<API_SET_NAMESPACE> build_api_set_map(x64_emulator& emu, emulator_allocator& allocator)
{
const auto& orig_api_set_map = *NtCurrentTeb()->ProcessEnvironmentBlock->ApiSetMap;
// TODO: fix
#ifdef OS_WINDOWS
const auto& orig_api_set_map = *NtCurrentTeb64()->ProcessEnvironmentBlock->ApiSetMap;
return clone_api_set_map(emu, allocator, orig_api_set_map);
#else
return clone_api_set_map(emu, allocator, {});
#endif
}
emulator_allocator create_allocator(emulator& emu, const size_t size)
@@ -187,7 +192,7 @@ namespace
context.base_allocator = create_allocator(emu, PEB_SEGMENT_SIZE);
auto& allocator = context.base_allocator;
context.peb = allocator.reserve<PEB>();
context.peb = allocator.reserve<PEB64>();
/* Values of the following fields must be
* allocated relative to the process_params themselves
@@ -204,9 +209,9 @@ namespace
* RedirectionDllName
*/
context.process_params = allocator.reserve<RTL_USER_PROCESS_PARAMETERS>();
context.process_params = allocator.reserve<RTL_USER_PROCESS_PARAMETERS64>();
context.process_params.access([&](RTL_USER_PROCESS_PARAMETERS& proc_params)
context.process_params.access([&](RTL_USER_PROCESS_PARAMETERS64& proc_params)
{
proc_params.Flags = 0x6001; //| 0x80000000; // Prevent CsrClientConnectToServer
@@ -215,41 +220,43 @@ namespace
proc_params.StandardInput = STDIN_HANDLE.h;
proc_params.StandardError = proc_params.StandardOutput;
proc_params.Environment = allocator.copy_string(L"=::=::\\");
allocator.copy_string(L"EMULATOR=1");
allocator.copy_string(L"COMPUTERNAME=momo");
allocator.copy_string(L"SystemRoot=C:\\WINDOWS");
allocator.copy_string(L"");
proc_params.Environment = reinterpret_cast<std::uint64_t*>(allocator.copy_string(u"=::=::\\"));
allocator.copy_string(u"EMULATOR=1");
allocator.copy_string(u"COMPUTERNAME=momo");
allocator.copy_string(u"SystemRoot=C:\\WINDOWS");
allocator.copy_string(u"");
std::wstring command_line = L"\"" + settings.application.wstring() + L"\"";
std::u16string command_line = u"\"" + settings.application.u16string() + u"\"";
for (const auto& arg : settings.arguments)
{
command_line.push_back(L' ');
command_line.push_back(u' ');
command_line.append(arg);
}
std::wstring current_folder{};
std::u16string current_folder{};
if (!settings.working_directory.empty())
{
current_folder = canonicalize_path(settings.working_directory).wstring() + L"\\";
current_folder = canonicalize_path(settings.working_directory).u16string() + u"\\";
}
else
{
current_folder = canonicalize_path(settings.application).parent_path().wstring() + L"\\";
current_folder = canonicalize_path(settings.application).parent_path().u16string() + u"\\";
}
allocator.make_unicode_string(proc_params.CommandLine, command_line);
allocator.make_unicode_string(proc_params.CurrentDirectory.DosPath, current_folder);
allocator.make_unicode_string(proc_params.ImagePathName, canonicalize_path(settings.application).wstring());
allocator.make_unicode_string(proc_params.ImagePathName,
canonicalize_path(settings.application).u16string());
const auto total_length = allocator.get_next_address() - context.process_params.value();
proc_params.Length = static_cast<uint32_t>(std::max(sizeof(proc_params), total_length));
proc_params.Length = static_cast<uint32_t>(std::max(static_cast<uint64_t>(sizeof(proc_params)),
total_length));
proc_params.MaximumLength = proc_params.Length;
});
context.peb.access([&](PEB& peb)
context.peb.access([&](PEB64& peb)
{
peb.ImageBaseAddress = nullptr;
peb.ProcessParameters = context.process_params.ptr();
@@ -270,21 +277,24 @@ namespace
});
}
using exception_record_map = std::unordered_map<const EXCEPTION_RECORD*, emulator_object<EXCEPTION_RECORD>>;
using exception_record_map = std::unordered_map<
const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*, emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<
Emu64>>>>;
emulator_object<EXCEPTION_RECORD> save_exception_record(emulator_allocator& allocator,
const EXCEPTION_RECORD& record,
exception_record_map& record_mapping)
emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> save_exception_record(emulator_allocator& allocator,
const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>& record,
exception_record_map& record_mapping)
{
const auto record_obj = allocator.reserve<EXCEPTION_RECORD>();
const auto record_obj = allocator.reserve<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>>();
record_obj.write(record);
if (record.ExceptionRecord)
{
record_mapping.emplace(&record, record_obj);
emulator_object<EXCEPTION_RECORD> nested_record_obj{allocator.get_emulator()};
const auto nested_record = record_mapping.find(record.ExceptionRecord);
emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> nested_record_obj{allocator.get_emulator()};
const auto nested_record = record_mapping.find(
reinterpret_cast<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*>(record.ExceptionRecord));
if (nested_record != record_mapping.end())
{
@@ -292,21 +302,22 @@ namespace
}
else
{
nested_record_obj = save_exception_record(allocator, *record.ExceptionRecord,
record_mapping);
nested_record_obj = save_exception_record(
allocator, *reinterpret_cast<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*>(record.ExceptionRecord),
record_mapping);
}
record_obj.access([&](EXCEPTION_RECORD& r)
record_obj.access([&](EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>& r)
{
r.ExceptionRecord = nested_record_obj.ptr();
r.ExceptionRecord = reinterpret_cast<EmulatorTraits<Emu64>::PVOID>(nested_record_obj.ptr());
});
}
return record_obj;
}
emulator_object<EXCEPTION_RECORD> save_exception_record(emulator_allocator& allocator,
const EXCEPTION_RECORD& record)
emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> save_exception_record(emulator_allocator& allocator,
const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>& record)
{
exception_record_map record_mapping{};
return save_exception_record(allocator, record, record_mapping);
@@ -325,12 +336,12 @@ namespace
}
}
size_t calculate_exception_record_size(const EXCEPTION_RECORD& record)
size_t calculate_exception_record_size(const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>& record)
{
std::unordered_set<const EXCEPTION_RECORD*> records{};
std::unordered_set<const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*> records{};
size_t total_size = 0;
const EXCEPTION_RECORD* current_record = &record;
const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>* current_record = &record;
while (current_record)
{
if (!records.insert(current_record).second)
@@ -339,7 +350,7 @@ namespace
}
total_size += sizeof(*current_record);
current_record = record.ExceptionRecord;
current_record = reinterpret_cast<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*>(record.ExceptionRecord);
}
return total_size;
@@ -354,11 +365,13 @@ namespace
uint64_t ss;
};
void dispatch_exception_pointers(x64_emulator& emu, const uint64_t dispatcher, const EXCEPTION_POINTERS pointers)
void dispatch_exception_pointers(x64_emulator& emu, const uint64_t dispatcher,
const EMU_EXCEPTION_POINTERS<EmulatorTraits<Emu64>> pointers)
{
constexpr auto mach_frame_size = 0x40;
constexpr auto context_record_size = 0x4F0;
const auto exception_record_size = calculate_exception_record_size(*pointers.ExceptionRecord);
const auto exception_record_size = calculate_exception_record_size(
*reinterpret_cast<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*>(pointers.ExceptionRecord));
const auto combined_size = align_up(exception_record_size + context_record_size, 0x10);
assert(combined_size == 0x590);
@@ -379,11 +392,12 @@ namespace
emu.reg(x64_register::rsp, new_sp);
emu.reg(x64_register::rip, dispatcher);
const emulator_object<CONTEXT> context_record_obj{emu, new_sp};
context_record_obj.write(*pointers.ContextRecord);
const emulator_object<CONTEXT64> context_record_obj{emu, new_sp};
context_record_obj.write(*reinterpret_cast<CONTEXT64*>(pointers.ContextRecord));
emulator_allocator allocator{emu, new_sp + context_record_size, exception_record_size};
const auto exception_record_obj = save_exception_record(allocator, *pointers.ExceptionRecord);
const auto exception_record_obj = save_exception_record(
allocator, *reinterpret_cast<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*>(pointers.ExceptionRecord));
if (exception_record_obj.value() != allocator.get_base())
{
@@ -393,55 +407,56 @@ namespace
const emulator_object<machine_frame> machine_frame_obj{emu, new_sp + combined_size};
machine_frame_obj.access([&](machine_frame& frame)
{
frame.rip = pointers.ContextRecord->Rip;
frame.rsp = pointers.ContextRecord->Rsp;
frame.ss = pointers.ContextRecord->SegSs;
frame.cs = pointers.ContextRecord->SegCs;
frame.eflags = pointers.ContextRecord->EFlags;
const auto& record = *reinterpret_cast<CONTEXT64*>(pointers.ContextRecord);
frame.rip = record.Rip;
frame.rsp = record.Rsp;
frame.ss = record.SegSs;
frame.cs = record.SegCs;
frame.eflags = record.EFlags;
});
}
void dispatch_access_violation(x64_emulator& emu, const uint64_t dispatcher, const uint64_t address,
const memory_operation operation)
{
CONTEXT ctx{};
ctx.ContextFlags = CONTEXT_ALL;
CONTEXT64 ctx{};
ctx.ContextFlags = CONTEXT64_ALL;
context_frame::save(emu, ctx);
EXCEPTION_RECORD record{};
EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>> record{};
memset(&record, 0, sizeof(record));
record.ExceptionCode = static_cast<DWORD>(STATUS_ACCESS_VIOLATION);
record.ExceptionFlags = 0;
record.ExceptionRecord = nullptr;
record.ExceptionAddress = reinterpret_cast<void*>(emu.read_instruction_pointer());
record.ExceptionRecord = 0;
record.ExceptionAddress = static_cast<EmulatorTraits<Emu64>::PVOID>(emu.read_instruction_pointer());
record.NumberParameters = 2;
record.ExceptionInformation[0] = map_violation_operation_to_parameter(operation);
record.ExceptionInformation[1] = address;
EXCEPTION_POINTERS pointers{};
pointers.ContextRecord = &ctx;
pointers.ExceptionRecord = &record;
EMU_EXCEPTION_POINTERS<EmulatorTraits<Emu64>> pointers{};
pointers.ContextRecord = reinterpret_cast<EmulatorTraits<Emu64>::PVOID>(&ctx);
pointers.ExceptionRecord = reinterpret_cast<EmulatorTraits<Emu64>::PVOID>(&record);
dispatch_exception_pointers(emu, dispatcher, pointers);
}
void dispatch_illegal_instruction_violation(x64_emulator& emu, const uint64_t dispatcher)
{
CONTEXT ctx{};
ctx.ContextFlags = CONTEXT_ALL;
CONTEXT64 ctx{};
ctx.ContextFlags = CONTEXT64_ALL;
context_frame::save(emu, ctx);
EXCEPTION_RECORD record{};
EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>> record{};
memset(&record, 0, sizeof(record));
record.ExceptionCode = static_cast<DWORD>(STATUS_ILLEGAL_INSTRUCTION);
record.ExceptionFlags = 0;
record.ExceptionRecord = nullptr;
record.ExceptionAddress = reinterpret_cast<void*>(emu.read_instruction_pointer());
record.ExceptionRecord = 0;
record.ExceptionAddress = static_cast<EmulatorTraits<Emu64>::PVOID>(emu.read_instruction_pointer());
record.NumberParameters = 0;
EXCEPTION_POINTERS pointers{};
pointers.ContextRecord = &ctx;
pointers.ExceptionRecord = &record;
EMU_EXCEPTION_POINTERS<EmulatorTraits<Emu64>> pointers{};
pointers.ContextRecord = reinterpret_cast<EmulatorTraits<Emu64>::PVOID>(&ctx);
pointers.ExceptionRecord = reinterpret_cast<EmulatorTraits<Emu64>::PVOID>(&record);
dispatch_exception_pointers(emu, dispatcher, pointers);
}
@@ -596,7 +611,7 @@ emulator_thread::emulator_thread(x64_emulator& emu, const process_context& conte
const uint64_t argument,
const uint64_t stack_size, const uint32_t id)
: emu_ptr(&emu)
, stack_size(page_align_up(std::max(stack_size, STACK_SIZE)))
, stack_size(page_align_up(std::max(stack_size, static_cast<uint64_t>(STACK_SIZE))))
, start_address(start_address)
, argument(argument)
, id(id)
@@ -610,14 +625,14 @@ emulator_thread::emulator_thread(x64_emulator& emu, const process_context& conte
GS_SEGMENT_SIZE,
};
this->teb = this->gs_segment->reserve<TEB>();
this->teb = this->gs_segment->reserve<TEB64>();
this->teb->access([&](TEB& teb_obj)
this->teb->access([&](TEB64& teb_obj)
{
teb_obj.ClientId.UniqueProcess = reinterpret_cast<HANDLE>(1);
teb_obj.ClientId.UniqueThread = reinterpret_cast<HANDLE>(static_cast<uint64_t>(this->id));
teb_obj.NtTib.StackLimit = reinterpret_cast<void*>(this->stack_base);
teb_obj.NtTib.StackBase = reinterpret_cast<void*>(this->stack_base + this->stack_size);
teb_obj.ClientId.UniqueProcess = 1ul;
teb_obj.ClientId.UniqueThread = static_cast<uint64_t>(this->id);
teb_obj.NtTib.StackLimit = reinterpret_cast<std::uint64_t*>(this->stack_base);
teb_obj.NtTib.StackBase = reinterpret_cast<std::uint64_t*>(this->stack_base + this->stack_size);
teb_obj.NtTib.Self = &this->teb->ptr()->NtTib;
teb_obj.ProcessEnvironmentBlock = context.peb.ptr();
});
@@ -712,8 +727,8 @@ void emulator_thread::setup_registers(x64_emulator& emu, const process_context&
setup_stack(emu, this->stack_base, this->stack_size);
setup_gs_segment(emu, *this->gs_segment);
CONTEXT ctx{};
ctx.ContextFlags = CONTEXT_ALL;
CONTEXT64 ctx{};
ctx.ContextFlags = CONTEXT64_ALL;
unalign_stack(emu);
context_frame::save(emu, ctx);
@@ -722,7 +737,7 @@ void emulator_thread::setup_registers(x64_emulator& emu, const process_context&
ctx.Rcx = this->start_address;
ctx.Rdx = this->argument;
const auto ctx_obj = allocate_object_on_stack<CONTEXT>(emu);
const auto ctx_obj = allocate_object_on_stack<CONTEXT64>(emu);
ctx_obj.write(ctx);
unalign_stack(emu);
@@ -766,9 +781,9 @@ void windows_emulator::setup_process(const emulator_settings& settings)
context.executable = context.mod_manager.map_module(settings.application, this->log);
context.peb.access([&](PEB& peb)
context.peb.access([&](PEB64& peb)
{
peb.ImageBaseAddress = reinterpret_cast<void*>(context.executable->image_base);
peb.ImageBaseAddress = reinterpret_cast<std::uint64_t*>(context.executable->image_base);
});
context.ntdll = context.mod_manager.map_module(R"(C:\Windows\System32\ntdll.dll)", this->log);
@@ -843,16 +858,16 @@ void windows_emulator::on_instruction_execution(uint64_t address)
if (export_entry != binary->address_names.end())
{
log.print(is_interesting_call ? color::yellow : color::dark_gray,
"Executing function: %s - %s (0x%llX)\n",
binary->name.c_str(),
export_entry->second.c_str(), address);
"Executing function: %s - %s (0x%" PRIx64 ")\n",
binary->name.c_str(),
export_entry->second.c_str(), address);
}
else if (address == binary->entry_point)
{
log.print(is_interesting_call ? color::yellow : color::gray,
"Executing entry point: %s (0x%llX)\n",
binary->name.c_str(),
address);
"Executing entry point: %s (0x%" PRIx64 ")\n",
binary->name.c_str(),
address);
}
}
@@ -864,7 +879,8 @@ void windows_emulator::on_instruction_execution(uint64_t address)
auto& emu = this->emu();
printf(
"Inst: %16llX - RAX: %16llX - RBX: %16llX - RCX: %16llX - RDX: %16llX - R8: %16llX - R9: %16llX - RDI: %16llX - RSI: %16llX - %s\n",
"Inst: %16" PRIx64 " - RAX: %16" PRIx64 " - RBX: %16" PRIx64 " - RCX: %16" PRIx64 " - RDX: %16" PRIx64
" - R8: %16" PRIx64 " - R9: %16" PRIx64 " - RDI: %16" PRIx64 " - RSI: %16" PRIx64 " - %s\n",
address,
emu.reg(x64_register::rax), emu.reg(x64_register::rbx),
emu.reg(x64_register::rcx),
@@ -901,7 +917,8 @@ void windows_emulator::setup_hooks()
this->emu().hook_instruction(x64_hookable_instructions::invalid, [&]
{
const auto ip = this->emu().read_instruction_pointer();
printf("Invalid instruction at: 0x%llX\n", ip);
this->log.print(color::gray, "Invalid instruction at: 0x%" PRIx64 "\n", ip);
return instruction_hook_continuation::skip_instruction;
});
@@ -915,7 +932,7 @@ void windows_emulator::setup_hooks()
}
const auto rip = this->emu().read_instruction_pointer();
printf("Interrupt: %i 0x%llX\n", interrupt, rip);
this->log.print(color::gray, "Interrupt: %i 0x%" PRIx64 "\n", interrupt, rip);
if (this->fuzzing || true) // TODO: Fix
{
@@ -933,15 +950,17 @@ void windows_emulator::setup_hooks()
if (type == memory_violation_type::protection)
{
this->log.print(color::gray, "Protection violation: 0x%llX (%zX) - %s at 0x%llX (%s)\n", address, size,
permission.c_str(), ip,
name);
this->log.print(color::gray, "Protection violation: 0x%" PRIx64 " (%zX) - %s at 0x%" PRIx64 " (%s)\n",
address, size,
permission.c_str(), ip,
name);
}
else if (type == memory_violation_type::unmapped)
{
this->log.print(color::gray, "Mapping violation: 0x%llX (%zX) - %s at 0x%llX (%s)\n", address, size,
permission.c_str(), ip,
name);
this->log.print(color::gray, "Mapping violation: 0x%" PRIx64 " (%zX) - %s at 0x%" PRIx64 " (%s)\n", address,
size,
permission.c_str(), ip,
name);
}
if (this->fuzzing)

View File

@@ -15,7 +15,7 @@ struct emulator_settings
std::filesystem::path application{};
std::filesystem::path working_directory{};
std::filesystem::path registry_directory{"./registry"};
std::vector<std::wstring> arguments{};
std::vector<std::u16string> arguments{};
std::function<void(std::string_view)> stdout_callback{};
bool disable_logging{false};
bool silent_until_main{false};