Merge remote-tracking branch 'origin/main' into wow64

This commit is contained in:
momo5502
2025-10-25 11:06:03 +02:00
17 changed files with 303 additions and 51 deletions

View File

@@ -319,6 +319,14 @@ typedef struct _FILE_FS_DEVICE_INFORMATION
ULONG Characteristics;
} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
typedef struct _FILE_FS_ATTRIBUTE_INFORMATION
{
ULONG FileSystemAttributes;
LONG MaximumComponentNameLength;
ULONG FileSystemNameLength;
char16_t FileSystemName[10];
} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
typedef struct _FILE_POSITION_INFORMATION
{
LARGE_INTEGER CurrentByteOffset;
@@ -330,6 +338,24 @@ typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION
ULONG ReparseTag;
} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION;
typedef struct _FILE_IS_REMOTE_DEVICE_INFORMATION
{
BOOLEAN IsRemote;
} FILE_IS_REMOTE_DEVICE_INFORMATION, *PFILE_IS_REMOTE_DEVICE_INFORMATION;
#ifndef OS_WINDOWS
typedef struct _FILE_ID_128
{
BYTE Identifier[16];
} FILE_ID_128, *PFILE_ID_128;
#endif
typedef struct _FILE_ID_INFORMATION
{
ULONGLONG VolumeSerialNumber;
FILE_ID_128 FileId;
} FILE_ID_INFORMATION, *PFILE_ID_INFORMATION;
typedef struct _FILE_STANDARD_INFORMATION
{
LARGE_INTEGER AllocationSize;
@@ -423,11 +449,6 @@ typedef struct _FILE_RENAME_INFORMATION
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
#ifndef OS_WINDOWS
typedef struct _FILE_ID_128
{
BYTE Identifier[16];
} FILE_ID_128, *PFILE_ID_128;
typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;
typedef struct _SECURITY_QUALITY_OF_SERVICE
{

View File

@@ -52,4 +52,63 @@ struct EMU_DISPLAY_DEVICEW
char16_t DeviceKey[128];
};
#ifndef ENUM_CURRENT_SETTINGS
#define ENUM_CURRENT_SETTINGS ((DWORD) - 1)
#endif
struct EMU_DEVMODEW
{
char16_t dmDeviceName[32];
WORD dmSpecVersion;
WORD dmDriverVersion;
WORD dmSize;
WORD dmDriverExtra;
DWORD dmFields;
union
{
struct
{
int16_t dmOrientation;
int16_t dmPaperSize;
int16_t dmPaperLength;
int16_t dmPaperWidth;
int16_t dmScale;
int16_t dmCopies;
int16_t dmDefaultSource;
int16_t dmPrintQuality;
} s;
POINT dmPosition;
struct
{
POINT dmPosition;
DWORD dmDisplayOrientation;
DWORD dmDisplayFixedOutput;
} s2;
} u;
int16_t dmColor;
int16_t dmDuplex;
int16_t dmYResolution;
int16_t dmTTOption;
int16_t dmCollate;
char16_t dmFormName[32];
WORD dmLogPixels;
DWORD dmBitsPerPel;
DWORD dmPelsWidth;
DWORD dmPelsHeight;
union
{
DWORD dmDisplayFlags;
DWORD dmNup;
} u2;
DWORD dmDisplayFrequency;
DWORD dmICMMethod;
DWORD dmICMIntent;
DWORD dmMediaType;
DWORD dmDitherType;
DWORD dmReserved1;
DWORD dmReserved2;
DWORD dmPanningWidth;
DWORD dmPanningHeight;
};
// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)

View File

@@ -19,26 +19,18 @@ namespace utils::string
template <typename T, size_t Size>
requires(std::is_trivially_copyable_v<T>)
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
void copy(T (&array)[Size], const std::basic_string_view<T> str)
void copy(T (&array)[Size], const T* str)
{
if constexpr (Size == 0)
{
return;
}
const auto size = std::min(Size, str.size());
memcpy(array, str.data(), size * sizeof(T));
const auto size = std::min(Size, std::char_traits<T>::length(str));
memcpy(array, str, size * sizeof(T));
array[std::min(Size - 1, size)] = {};
}
template <typename T, size_t Size>
requires(std::is_trivially_copyable_v<T>)
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
void copy(T (&array)[Size], const T* str)
{
copy<T, Size>(array, std::basic_string_view<T>(str));
}
inline char char_to_lower(const char val)
{
return static_cast<char>(std::tolower(static_cast<unsigned char>(val)));

View File

@@ -9,7 +9,7 @@ namespace
{
// RNG Microsoft Primitive Provider
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
std::uint8_t output_data[216] = //
std::uint8_t rng_output_data[216] = //
{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
@@ -22,6 +22,21 @@ namespace
0x70, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x73, 0x00,
0x2E, 0x00, 0x64, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// SHA256 Microsoft Primitive Provider
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
std::uint8_t sha256_output_data[224] = //
{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x32, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53, 0x00, 0x48, 0x00,
0x41, 0x00, 0x32, 0x00, 0x35, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, 0x6F,
0x00, 0x73, 0x00, 0x6F, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00,
0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x76, 0x00, 0x69, 0x00, 0x64,
0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x70,
0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2E, 0x00,
0x64, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
NTSTATUS io_control(windows_emulator& win_emu, const io_device_context& c) override
{
if (c.io_control_code != 0x390400)
@@ -33,13 +48,32 @@ namespace
if (operation == 2)
{
win_emu.emu().write_memory(c.output_buffer, output_data);
std::array<char16_t, 8> alg_name_buffer{};
win_emu.emu().read_memory(c.input_buffer + 0x30, alg_name_buffer.data(), sizeof(alg_name_buffer));
if (c.io_status_block)
const std::u16string algorithm_name(alg_name_buffer.data());
if (algorithm_name == u"SHA256")
{
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
block.Information = sizeof(output_data);
c.io_status_block.write(block);
win_emu.emu().write_memory(c.output_buffer, sha256_output_data);
if (c.io_status_block)
{
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
block.Information = sizeof(sha256_output_data);
c.io_status_block.write(block);
}
}
else
{
win_emu.emu().write_memory(c.output_buffer, rng_output_data);
if (c.io_status_block)
{
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
block.Information = sizeof(rng_output_data);
c.io_status_block.write(block);
}
}
}

View File

@@ -207,7 +207,10 @@ emulator_thread::emulator_thread(memory_manager& memory, const process_context&
teb_obj.NtTib.StackBase = wow64_cpureserved_base;
teb_obj.NtTib.Self = this->teb64->value();
teb_obj.CurrentLocale = 0x409;
teb_obj.ProcessEnvironmentBlock = context.peb64.value();
teb_obj.StaticUnicodeString.MaximumLength = sizeof(teb_obj.StaticUnicodeBuffer);
teb_obj.StaticUnicodeString.Buffer = this->teb64->value() + offsetof(TEB64, StaticUnicodeBuffer);
// Set WowTebOffset to point to 32-bit TEB offset
teb_obj.WowTebOffset = static_cast<int32_t>(wow_teb_offset); // 0x2000

View File

@@ -490,7 +490,7 @@ uint64_t memory_manager::find_free_allocation_base(const size_t size, const uint
// Since reserved_regions_ is a sorted map, we can iterate through it
// and find gaps between regions
while (start_address + size <= MAX_ALLOCATION_ADDRESS)
while (start_address + size <= MAX_ALLOCATION_END_EXCL)
{
bool conflict = false;
@@ -530,7 +530,7 @@ region_info memory_manager::get_region_info(const uint64_t address)
{
region_info result{};
result.start = MIN_ALLOCATION_ADDRESS;
result.length = static_cast<size_t>(MAX_ALLOCATION_ADDRESS - result.start);
result.length = static_cast<size_t>(MAX_ALLOCATION_END_EXCL - result.start);
result.permissions = nt_memory_permission();
result.initial_permissions = nt_memory_permission();
result.allocation_base = {};
@@ -555,7 +555,7 @@ region_info memory_manager::get_region_info(const uint64_t address)
if (lower_end <= address)
{
result.start = lower_end;
result.length = static_cast<size_t>(MAX_ALLOCATION_ADDRESS - result.start);
result.length = static_cast<size_t>(MAX_ALLOCATION_END_EXCL - result.start);
return result;
}

View File

@@ -12,6 +12,7 @@
constexpr auto ALLOCATION_GRANULARITY = 0x0000000000010000ULL;
constexpr auto MIN_ALLOCATION_ADDRESS = 0x0000000000010000ULL;
constexpr auto MAX_ALLOCATION_ADDRESS = 0x00007ffffffeffffULL;
constexpr auto MAX_ALLOCATION_END_EXCL = MAX_ALLOCATION_ADDRESS + 1ULL;
constexpr auto DEFAULT_ALLOCATION_ADDRESS_64BIT = 0x100000000ULL;
constexpr auto DEFAULT_ALLOCATION_ADDRESS_32BIT = 0x10000ULL;

View File

@@ -51,8 +51,10 @@ inline std::optional<nt_memory_permission> try_map_nt_to_emulator_protection(uin
case PAGE_EXECUTE_READWRITE:
common = memory_permission::all;
break;
case 0:
case PAGE_EXECUTE_WRITECOPY:
common = memory_permission::all;
break;
case 0:
default:
return std::nullopt;
}

View File

@@ -54,7 +54,7 @@ struct mapped_module
bool contains(const uint64_t address) const
{
return address >= this->image_base && address < (this->image_base + this->size_of_image);
return (address - this->image_base) < this->size_of_image;
}
uint64_t find_export(const std::string_view export_name) const

View File

@@ -211,6 +211,7 @@ mapped_module* module_manager::map_module_core(const pe_detection_result& detect
const auto image_base = mod.image_base;
const auto entry = this->modules_.try_emplace(image_base, std::move(mod));
this->last_module_cache_ = this->modules_.end();
// TODO: Patch shell32.dll entry point to prevent TLS storage issues
// The shell32.dll module in SysWOW64 has TLS storage that fails, causing crashes
@@ -409,6 +410,7 @@ void module_manager::install_wow64_heaven_gate(const logger& logger)
module.sections.emplace_back(std::move(section));
this->modules_.emplace(module.image_base, std::move(module));
this->last_module_cache_ = this->modules_.end();
}
}
@@ -521,6 +523,7 @@ void module_manager::serialize(utils::buffer_serializer& buffer) const
void module_manager::deserialize(utils::buffer_deserializer& buffer)
{
buffer.read_map(this->modules_);
this->last_module_cache_ = this->modules_.end();
const auto executable_base = buffer.read<uint64_t>();
const auto ntdll_base = buffer.read<uint64_t>();
@@ -559,6 +562,7 @@ bool module_manager::unmap(const uint64_t address)
this->callbacks_->on_module_unload(mod->second);
unmap_module(*this->memory_, mod->second);
this->modules_.erase(mod);
this->last_module_cache_ = this->modules_.end();
return true;
}

View File

@@ -173,6 +173,7 @@ class module_manager
callbacks* callbacks_{};
module_map modules_{};
mutable module_map::iterator last_module_cache_{modules_.end()};
// Strategy pattern components
mapping_strategy_factory strategy_factory_;
@@ -198,6 +199,11 @@ class module_manager
module_map::iterator get_module(const uint64_t address)
{
if (last_module_cache_ != this->modules_.end() && last_module_cache_->second.contains(address))
{
return last_module_cache_;
}
if (this->modules_.empty())
{
return this->modules_.end();
@@ -213,6 +219,7 @@ class module_manager
if (upper_bound->second.contains(address))
{
last_module_cache_ = upper_bound;
return upper_bound;
}

View File

@@ -31,7 +31,7 @@ inline bool is_syscall(const std::string_view name)
inline bool is_named_pipe_path(const std::u16string_view& filename)
{
return filename == u"\\Device\\NamedPipe\\" || filename.starts_with(u"\\Device\\NamedPipe\\");
return filename == u"\\Device\\NamedPipe\\" || filename.starts_with(u"\\Device\\NamedPipe\\") || filename.starts_with(u"\\??\\pipe\\");
}
inline std::optional<uint32_t> extract_syscall_id(const exported_symbol& symbol, std::span<const std::byte> data)

View File

@@ -155,6 +155,7 @@ namespace syscalls
NTSTATUS handle_NtSetInformationObject();
NTSTATUS handle_NtQuerySecurityObject(const syscall_context& c, handle /*h*/, SECURITY_INFORMATION /*security_information*/,
emulator_pointer security_descriptor, ULONG length, emulator_object<ULONG> length_needed);
NTSTATUS handle_NtSetSecurityObject();
// syscalls/port.cpp:
NTSTATUS handle_NtConnectPort(const syscall_context& c, emulator_object<handle> client_port_handle,
@@ -920,32 +921,78 @@ namespace syscalls
return FALSE;
}
NTSTATUS handle_NtUserEnumDisplayDevices(const syscall_context& /*c*/,
NTSTATUS handle_NtUserEnumDisplayDevices(const syscall_context& c,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> str_device, const DWORD dev_num,
const emulator_object<EMU_DISPLAY_DEVICEW> display_device, const DWORD /*flags*/)
{
if (str_device && dev_num != 0)
if (!str_device)
{
return STATUS_UNSUCCESSFUL;
}
if (dev_num > 0)
{
return STATUS_UNSUCCESSFUL;
}
if (dev_num > 0)
display_device.access([&](EMU_DISPLAY_DEVICEW& dev) {
dev.StateFlags = 0x5; // DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1");
utils::string::copy(dev.DeviceString, u"Emulated Virtual Adapter");
utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1");
utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{00000001-"
u"0002-0003-0004-000000000005}\\0000");
});
}
else
{
return STATUS_UNSUCCESSFUL;
}
const auto dev_name = read_unicode_string(c.emu, str_device);
display_device.access([&](EMU_DISPLAY_DEVICEW& dev) {
dev.StateFlags = 0;
utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1");
utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1");
utils::string::copy(dev.DeviceString, u"Emulator Display");
utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{00000001-"
u"0002-0003-0004-000000000005}\\0001");
});
if (dev_name != u"\\\\.\\DISPLAY1")
{
return STATUS_UNSUCCESSFUL;
}
if (dev_num > 0)
{
return STATUS_UNSUCCESSFUL;
}
display_device.access([&](EMU_DISPLAY_DEVICEW& dev) {
dev.StateFlags = 0x1; // DISPLAY_DEVICE_ACTIVE
utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1\\Monitor0");
utils::string::copy(dev.DeviceString, u"Generic PnP Monitor");
utils::string::copy(dev.DeviceID, u"MONITOR\\EMU1234\\{4d36e96e-e325-11ce-bfc1-08002be10318}\\0000");
utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\DISPLAY\\EMU1234\\"
u"1&23a45b&0&UID67568640");
});
}
return STATUS_SUCCESS;
}
NTSTATUS handle_NtUserEnumDisplaySettings(const syscall_context& c,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> device_name,
const DWORD mode_num, const emulator_object<EMU_DEVMODEW> dev_mode, const DWORD /*flags*/)
{
if (dev_mode && (mode_num == ENUM_CURRENT_SETTINGS || mode_num == 0))
{
const auto dev_name = read_unicode_string(c.emu, device_name);
if (dev_name == u"\\\\.\\DISPLAY1")
{
dev_mode.access([](EMU_DEVMODEW& dm) {
dm.dmFields = 0x5C0000; // DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY
dm.dmPelsWidth = 1920;
dm.dmPelsHeight = 1080;
dm.dmBitsPerPel = 32;
dm.dmDisplayFrequency = 60;
});
return STATUS_SUCCESS;
}
}
return STATUS_UNSUCCESSFUL;
}
NTSTATUS handle_NtAssociateWaitCompletionPacket()
{
return STATUS_SUCCESS;
@@ -1142,6 +1189,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
add_handler(NtUserGetRawInputDeviceList);
add_handler(NtUserGetKeyboardType);
add_handler(NtUserEnumDisplayDevices);
add_handler(NtUserEnumDisplaySettings);
add_handler(NtUserSetProp);
add_handler(NtUserSetProp2);
add_handler(NtUserChangeWindowMessageFilterEx);
@@ -1165,6 +1213,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
add_handler(NtReleaseWorkerFactoryWorker);
add_handler(NtAlpcCreateSecurityContext);
add_handler(NtAlpcDeleteSecurityContext);
add_handler(NtSetSecurityObject);
#undef add_handler
}

View File

@@ -182,8 +182,18 @@ namespace syscalls
return handle_query<FILE_FS_VOLUME_INFORMATION>(c.emu, fs_information, length, io_status_block,
[&](FILE_FS_VOLUME_INFORMATION&) {});
case FileFsAttributeInformation:
return handle_query<_FILE_FS_ATTRIBUTE_INFORMATION>(
c.emu, fs_information, length, io_status_block, [&](_FILE_FS_ATTRIBUTE_INFORMATION& info) {
info.FileSystemAttributes = 0x40006; // FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_NAMED_STREAMS
info.MaximumComponentNameLength = 255;
constexpr auto name = u"NTFS"sv;
info.FileSystemNameLength = static_cast<ULONG>(name.size() * sizeof(char16_t));
memcpy(info.FileSystemName, name.data(), info.FileSystemNameLength);
});
default:
c.win_emu.log.error("Unsupported fs info class: %X\n", fs_information_class);
c.win_emu.log.error("Unsupported fs info class: 0x%X\n", fs_information_class);
c.emu.stop();
return write_io_status(io_status_block, STATUS_NOT_SUPPORTED, true);
}
@@ -211,7 +221,7 @@ namespace syscalls
files.emplace_back(file_entry{
.file_path = file.path().filename(),
.file_size = file.file_size(),
.file_size = file.is_directory() ? 0 : file.file_size(),
.is_directory = file.is_directory(),
});
}
@@ -232,7 +242,7 @@ namespace syscalls
files.emplace_back(file_entry{
.file_path = filename,
.file_size = dir_entry.file_size(),
.file_size = dir_entry.is_directory() ? 0 : dir_entry.file_size(),
.is_directory = dir_entry.is_directory(),
});
});
@@ -537,12 +547,68 @@ namespace syscalls
return ret(STATUS_SUCCESS);
}
if (info_class == FileIsRemoteDeviceInformation)
{
if (!f->handle)
{
return ret(STATUS_NOT_SUPPORTED);
}
block.Information = sizeof(FILE_IS_REMOTE_DEVICE_INFORMATION);
if (length < block.Information)
{
return ret(STATUS_BUFFER_OVERFLOW);
}
const emulator_object<FILE_IS_REMOTE_DEVICE_INFORMATION> info{c.emu, file_information};
FILE_IS_REMOTE_DEVICE_INFORMATION i{};
i.IsRemote = FALSE;
info.write(i);
return ret(STATUS_SUCCESS);
}
if (info_class == FileIdInformation)
{
if (!f->handle)
{
return ret(STATUS_NOT_SUPPORTED);
}
block.Information = sizeof(FILE_ID_INFORMATION);
if (length < block.Information)
{
return ret(STATUS_BUFFER_OVERFLOW);
}
struct _stat64 file_stat{};
if (fstat64(f->handle, &file_stat) != 0)
{
return ret(STATUS_INVALID_HANDLE);
}
const emulator_object<FILE_ID_INFORMATION> info{c.emu, file_information};
FILE_ID_INFORMATION i{};
i.VolumeSerialNumber = file_stat.st_dev;
memset(&i.FileId, 0, sizeof(i.FileId));
memcpy(&i.FileId.Identifier[0], &file_stat.st_ino, sizeof(file_stat.st_ino));
info.write(i);
return ret(STATUS_SUCCESS);
}
if (info_class == FileAllInformation)
{
return ret(STATUS_NOT_SUPPORTED);
}
c.win_emu.log.error("Unsupported query file info class: %X\n", info_class);
c.win_emu.log.error("Unsupported query file info class: 0x%X\n", info_class);
c.emu.stop();
return ret(STATUS_NOT_SUPPORTED);

View File

@@ -20,6 +20,15 @@ namespace syscalls
return STATUS_NOT_SUPPORTED;
}
if (base_address < MIN_ALLOCATION_ADDRESS || base_address >= MAX_ALLOCATION_END_EXCL)
{
if (return_length)
{
return_length.write(0);
}
return STATUS_INVALID_PARAMETER;
}
if (info_class == MemoryBasicInformation)
{
if (return_length)

View File

@@ -434,4 +434,9 @@ namespace syscalls
return STATUS_SUCCESS;
}
NTSTATUS handle_NtSetSecurityObject()
{
return STATUS_SUCCESS;
}
}

View File

@@ -448,8 +448,8 @@ void windows_emulator::setup_hooks()
this->callbacks.on_rdtscp();
const auto ticks = this->clock_->timestamp_counter();
this->emu().reg(x86_register::rax, ticks & 0xFFFFFFFF);
this->emu().reg(x86_register::rdx, (ticks >> 32) & 0xFFFFFFFF);
this->emu().reg(x86_register::rax, static_cast<uint32_t>(ticks));
this->emu().reg(x86_register::rdx, static_cast<uint32_t>(ticks >> 32));
// Return the IA32_TSC_AUX value in RCX (low 32 bits)
auto tsc_aux = 0; // Need to replace this with proper CPUID later
@@ -462,8 +462,8 @@ void windows_emulator::setup_hooks()
this->callbacks.on_rdtsc();
const auto ticks = this->clock_->timestamp_counter();
this->emu().reg(x86_register::rax, ticks & 0xFFFFFFFF);
this->emu().reg(x86_register::rdx, (ticks >> 32) & 0xFFFFFFFF);
this->emu().reg(x86_register::rax, static_cast<uint32_t>(ticks));
this->emu().reg(x86_register::rdx, static_cast<uint32_t>(ticks >> 32));
return instruction_hook_continuation::skip_instruction;
});