diff --git a/src/windows_emulator/handles.hpp b/src/windows_emulator/handles.hpp index e452baf..72a74a1 100644 --- a/src/windows_emulator/handles.hpp +++ b/src/windows_emulator/handles.hpp @@ -9,6 +9,7 @@ struct handle_types section, symlink, directory, + semaphore, }; }; diff --git a/src/windows_emulator/module/module_mapping.cpp b/src/windows_emulator/module/module_mapping.cpp index eee294f..b37c0fb 100644 --- a/src/windows_emulator/module/module_mapping.cpp +++ b/src/windows_emulator/module/module_mapping.cpp @@ -200,10 +200,13 @@ namespace if (!emu.allocate_memory(binary.image_base, binary.size_of_image, memory_permission::read)) { binary.image_base = emu.find_free_allocation_base(binary.size_of_image); - if (/*(optional_header.DllCharacteristics & - IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 ||*/ // - !emu.allocate_memory( - binary.image_base, binary.size_of_image, memory_permission::read)) + const auto is_dll = nt_headers.FileHeader.Characteristics & IMAGE_FILE_DLL; + const auto has_dynamic_base = + optional_header.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; + const auto is_relocatable = is_dll || has_dynamic_base; + + if (!is_relocatable || !emu.allocate_memory(binary.image_base, binary.size_of_image, + memory_permission::read)) { return {}; } diff --git a/src/windows_emulator/process_context.hpp b/src/windows_emulator/process_context.hpp index 301efaa..a0ffd10 100644 --- a/src/windows_emulator/process_context.hpp +++ b/src/windows_emulator/process_context.hpp @@ -27,6 +27,13 @@ struct file std::wstring name{}; }; +struct semaphore +{ + std::wstring name{}; + volatile uint32_t current_count{}; + uint32_t max_count{}; +}; + struct process_context { uint64_t executed_instructions{0}; @@ -42,6 +49,7 @@ struct process_context handle_store events{}; handle_store files{}; + handle_store semaphores{}; emulator_allocator gs_segment{}; bool verbose{false}; diff --git a/src/windows_emulator/syscalls.cpp b/src/windows_emulator/syscalls.cpp index 7f2bbd2..fc61505 100644 --- a/src/windows_emulator/syscalls.cpp +++ b/src/windows_emulator/syscalls.cpp @@ -256,6 +256,11 @@ namespace return STATUS_SUCCESS; } + if (value.type == handle_types::semaphore && c.proc.semaphores.erase(handle)) + { + return STATUS_SUCCESS; + } + return STATUS_INVALID_HANDLE; } @@ -491,7 +496,7 @@ namespace } const auto mod = c.proc.module_manager.find_by_address(base_address); - if(!mod) + if (!mod) { printf("Bad address for memory image request: %llX\n", base_address); return STATUS_INVALID_ADDRESS; @@ -755,6 +760,33 @@ namespace return STATUS_SUCCESS; } + if (info_class == ProcessEnclaveInformation) + { + return STATUS_NOT_SUPPORTED; + } + + if (info_class == ProcessBasicInformation) + { + if (return_length) + { + return_length.write(sizeof(PROCESS_BASIC_INFORMATION)); + } + + if (process_information_length != sizeof(PROCESS_BASIC_INFORMATION)) + { + return STATUS_BUFFER_OVERFLOW; + } + + const emulator_object info{c.emu, process_information}; + info.access([&](PROCESS_BASIC_INFORMATION& basic_info) + { + basic_info.PebBaseAddress = c.proc.peb.ptr(); + basic_info.UniqueProcessId = reinterpret_cast(1); + }); + + return STATUS_SUCCESS; + } + printf("Unsupported process info class: %X\n", info_class); c.emu.stop(); @@ -772,7 +804,8 @@ namespace if (info_class == ProcessSchedulerSharedData || info_class == ProcessTlsInformation - || info_class == ProcessConsoleHostProcess) + || info_class == ProcessConsoleHostProcess + || info_class == ProcessRaiseUMExceptionOnInvalidHandleClose) { return STATUS_SUCCESS; } @@ -1128,10 +1161,34 @@ namespace response.write(ResponseAbort); } - printf("Hard error: %X\n", error_status); + printf("Hard error: %X\n", static_cast(error_status)); c.emu.stop(); return STATUS_SUCCESS; } + + NTSTATUS handle_NtCreateSemaphore(const syscall_context& c, const emulator_object semaphore_handle, + const ACCESS_MASK /*desired_access*/, + const emulator_object object_attributes, + const ULONG initial_count, const ULONG maximum_count) + { + semaphore s{}; + s.current_count = initial_count; + s.max_count = maximum_count; + + if (object_attributes) + { + const auto attributes = object_attributes.read(); + if (attributes.ObjectName) + { + s.name = read_unicode_string(c.emu, attributes.ObjectName); + } + } + + const auto handle = c.proc.semaphores.store(std::move(s)); + semaphore_handle.write(handle.bits); + + return STATUS_SUCCESS; + } } syscall_dispatcher::syscall_dispatcher(const exported_symbols& ntdll_exports) @@ -1190,6 +1247,7 @@ syscall_dispatcher::syscall_dispatcher(const exported_symbols& ntdll_exports) add_handler(NtTerminateProcess); add_handler(NtWriteFile); add_handler(NtRaiseHardError); + add_handler(NtCreateSemaphore); #undef add_handler }