mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-17 19:13:55 +00:00
Various fixes and changes (#450)
This commit is contained in:
@@ -29,11 +29,43 @@ namespace
|
||||
};
|
||||
}
|
||||
|
||||
std::string get_instruction_string(const emulator& emu, const uint64_t address)
|
||||
{
|
||||
std::vector<uint8_t> instruction_bytes(15, 0);
|
||||
const auto result = emu.try_read_memory(address, instruction_bytes.data(), instruction_bytes.size());
|
||||
if (!result)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
disassembler disasm{};
|
||||
const auto instructions = disasm.disassemble(instruction_bytes, 1);
|
||||
if (instructions.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto& inst = instructions[0];
|
||||
return std::string(inst.mnemonic) + (strlen(inst.op_str) ? " "s + inst.op_str : "");
|
||||
}
|
||||
|
||||
void handle_suspicious_activity(const analysis_context& c, const std::string_view details)
|
||||
{
|
||||
std::string addition{};
|
||||
const auto rip = c.win_emu->emu().read_instruction_pointer();
|
||||
c.win_emu->log.print(color::pink, "Suspicious: %.*s at 0x%" PRIx64 " (via 0x%" PRIx64 ")\n", STR_VIEW_VA(details), rip,
|
||||
c.win_emu->process.previous_ip);
|
||||
|
||||
// TODO: Pass enum?
|
||||
if (details == "Illegal instruction")
|
||||
{
|
||||
const auto inst = get_instruction_string(c.win_emu->emu(), rip);
|
||||
if (!inst.empty())
|
||||
{
|
||||
addition = " (" + inst + ")";
|
||||
}
|
||||
}
|
||||
|
||||
c.win_emu->log.print(color::pink, "Suspicious: %.*s%.*s at 0x%" PRIx64 " (via 0x%" PRIx64 ")\n", STR_VIEW_VA(details),
|
||||
STR_VIEW_VA(addition), rip, c.win_emu->current_thread().previous_ip);
|
||||
}
|
||||
|
||||
void handle_debug_string(const analysis_context& c, const std::string_view details)
|
||||
@@ -256,8 +288,9 @@ namespace
|
||||
}
|
||||
#endif
|
||||
|
||||
const auto previous_ip = c.win_emu->current_thread().previous_ip;
|
||||
const auto is_main_exe = win_emu.mod_manager.executable->is_within(address);
|
||||
const auto is_previous_main_exe = win_emu.mod_manager.executable->is_within(c.win_emu->process.previous_ip);
|
||||
const auto is_previous_main_exe = win_emu.mod_manager.executable->is_within(previous_ip);
|
||||
|
||||
const auto binary = utils::make_lazy([&] {
|
||||
if (is_main_exe)
|
||||
@@ -274,7 +307,7 @@ namespace
|
||||
return win_emu.mod_manager.executable;
|
||||
}
|
||||
|
||||
return win_emu.mod_manager.find_by_address(win_emu.process.previous_ip); //
|
||||
return win_emu.mod_manager.find_by_address(previous_ip); //
|
||||
});
|
||||
|
||||
const auto is_in_interesting_module = [&] {
|
||||
@@ -310,8 +343,7 @@ namespace
|
||||
{
|
||||
win_emu.log.print(is_interesting_call ? color::yellow : color::dark_gray,
|
||||
"Executing function: %s (%s) (0x%" PRIx64 ") via (0x%" PRIx64 ") %s\n", export_entry->second.c_str(),
|
||||
binary->name.c_str(), address, win_emu.process.previous_ip,
|
||||
previous_binary ? previous_binary->name.c_str() : "<N/A>");
|
||||
binary->name.c_str(), address, previous_ip, previous_binary ? previous_binary->name.c_str() : "<N/A>");
|
||||
|
||||
if (is_interesting_call)
|
||||
{
|
||||
@@ -324,7 +356,7 @@ namespace
|
||||
win_emu.log.print(is_interesting_call ? color::yellow : color::gray, "Executing entry point: %s (0x%" PRIx64 ")\n",
|
||||
binary->name.c_str(), address);
|
||||
}
|
||||
else if (is_previous_main_exe && binary != previous_binary && !is_return(c.win_emu->emu(), win_emu.process.previous_ip))
|
||||
else if (is_previous_main_exe && binary != previous_binary && !is_return(c.win_emu->emu(), previous_ip))
|
||||
{
|
||||
auto nearest_entry = binary->address_names.upper_bound(address);
|
||||
if (nearest_entry == binary->address_names.begin())
|
||||
@@ -336,8 +368,8 @@ namespace
|
||||
|
||||
win_emu.log.print(is_interesting_call ? color::yellow : color::dark_gray,
|
||||
"Transition to foreign code: %s+0x%" PRIx64 " (%s) (0x%" PRIx64 ") via (0x%" PRIx64 ") %s\n",
|
||||
nearest_entry->second.c_str(), address - nearest_entry->first, binary->name.c_str(), address,
|
||||
win_emu.process.previous_ip, previous_binary ? previous_binary->name.c_str() : "<N/A>");
|
||||
nearest_entry->second.c_str(), address - nearest_entry->first, binary->name.c_str(), address, previous_ip,
|
||||
previous_binary ? previous_binary->name.c_str() : "<N/A>");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,13 +415,14 @@ namespace
|
||||
const auto address = emu.read_instruction_pointer();
|
||||
const auto* mod = win_emu.mod_manager.find_by_address(address);
|
||||
const auto is_sus_module = mod != win_emu.mod_manager.ntdll && mod != win_emu.mod_manager.win32u;
|
||||
const auto previous_ip = win_emu.current_thread().previous_ip;
|
||||
|
||||
if (is_sus_module)
|
||||
{
|
||||
win_emu.log.print(color::blue, "Executing inline syscall: %.*s (0x%X) at 0x%" PRIx64 " (%s)\n", STR_VIEW_VA(syscall_name),
|
||||
syscall_id, address, mod ? mod->name.c_str() : "<N/A>");
|
||||
}
|
||||
else if (mod->is_within(win_emu.process.previous_ip))
|
||||
else if (mod->is_within(previous_ip))
|
||||
{
|
||||
const auto rsp = emu.read_stack_pointer();
|
||||
|
||||
@@ -403,11 +436,11 @@ namespace
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto* previous_mod = win_emu.mod_manager.find_by_address(win_emu.process.previous_ip);
|
||||
const auto* previous_mod = win_emu.mod_manager.find_by_address(previous_ip);
|
||||
|
||||
win_emu.log.print(color::blue, "Crafted out-of-line syscall: %.*s (0x%X) at 0x%" PRIx64 " (%s) via 0x%" PRIx64 " (%s)\n",
|
||||
STR_VIEW_VA(syscall_name), syscall_id, address, mod ? mod->name.c_str() : "<N/A>",
|
||||
win_emu.process.previous_ip, previous_mod ? previous_mod->name.c_str() : "<N/A>");
|
||||
STR_VIEW_VA(syscall_name), syscall_id, address, mod ? mod->name.c_str() : "<N/A>", previous_ip,
|
||||
previous_mod ? previous_mod->name.c_str() : "<N/A>");
|
||||
}
|
||||
|
||||
return instruction_hook_continuation::run_instruction;
|
||||
|
||||
@@ -117,6 +117,7 @@ emulator_thread::emulator_thread(memory_manager& memory, const process_context&
|
||||
teb_obj.NtTib.StackLimit = this->stack_base;
|
||||
teb_obj.NtTib.StackBase = this->stack_base + this->stack_size;
|
||||
teb_obj.NtTib.Self = this->teb->value();
|
||||
teb_obj.CurrentLocale = 0x409;
|
||||
teb_obj.ProcessEnvironmentBlock = context.peb.value();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -74,6 +74,9 @@ class emulator_thread : public ref_counted_object
|
||||
|
||||
uint32_t id{};
|
||||
|
||||
uint64_t current_ip{0};
|
||||
uint64_t previous_ip{0};
|
||||
|
||||
std::u16string name{};
|
||||
|
||||
std::optional<NTSTATUS> exit_status{};
|
||||
@@ -144,6 +147,8 @@ class emulator_thread : public ref_counted_object
|
||||
buffer.write(this->argument);
|
||||
buffer.write(this->executed_instructions);
|
||||
buffer.write(this->id);
|
||||
buffer.write(this->current_ip);
|
||||
buffer.write(this->previous_ip);
|
||||
|
||||
buffer.write_string(this->name);
|
||||
|
||||
@@ -182,6 +187,8 @@ class emulator_thread : public ref_counted_object
|
||||
buffer.read(this->argument);
|
||||
buffer.read(this->executed_instructions);
|
||||
buffer.read(this->id);
|
||||
buffer.read(this->current_ip);
|
||||
buffer.read(this->previous_ip);
|
||||
|
||||
buffer.read_string(this->name);
|
||||
|
||||
|
||||
@@ -367,7 +367,7 @@ inline std::u16string read_unicode_string(emulator& emu, const uint64_t uc_strin
|
||||
return read_unicode_string(emu, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>{emu, uc_string});
|
||||
}
|
||||
|
||||
inline uint64_t get_function_argument(x86_64_emulator& emu, const size_t index, bool is_syscall = false)
|
||||
inline uint64_t get_function_argument(x86_64_emulator& emu, const size_t index, const bool is_syscall = false)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
|
||||
@@ -27,16 +27,16 @@ namespace
|
||||
kusd.TimeZoneBias.High2Time = -17;
|
||||
kusd.TimeZoneId = 0x00000002;
|
||||
kusd.LargePageMinimum = 0x00200000;
|
||||
kusd.RNGSeedVersion = 0x0000000000000013;
|
||||
kusd.RNGSeedVersion = 0;
|
||||
kusd.TimeZoneBiasStamp = 0x00000004;
|
||||
kusd.NtBuildNumber = 0x00006c51;
|
||||
kusd.NtBuildNumber = 19045;
|
||||
kusd.NtProductType = NtProductWinNt;
|
||||
kusd.ProductTypeIsValid = 0x01;
|
||||
kusd.NativeProcessorArchitecture = 0x0009;
|
||||
kusd.NtMajorVersion = 0x0000000a;
|
||||
kusd.BootId = 0x0000000b;
|
||||
kusd.SystemExpirationDate.QuadPart = 0x01dc26860a9ff300;
|
||||
kusd.SuiteMask = 0x00000110;
|
||||
kusd.BootId = 0;
|
||||
kusd.SystemExpirationDate.QuadPart = 0;
|
||||
kusd.SuiteMask = 0;
|
||||
kusd.MitigationPolicies.MitigationPolicies = 0x0a;
|
||||
kusd.MitigationPolicies.NXSupportPolicy = 0x02;
|
||||
kusd.MitigationPolicies.SEHValidationPolicy = 0x02;
|
||||
@@ -48,7 +48,7 @@ namespace
|
||||
kusd.FullNumberOfPhysicalPages = 0x0000000000bf0958;
|
||||
kusd.TickCount.TickCount.LowPart = 0x001f7f05;
|
||||
kusd.TickCount.TickCountQuad = 0x00000000001f7f05;
|
||||
kusd.Cookie = 0x1c3471da;
|
||||
kusd.Cookie = 0;
|
||||
kusd.ConsoleSessionForegroundProcessId = 0x00000000000028f4;
|
||||
kusd.TimeUpdateLock = 0x0000000002b28586;
|
||||
kusd.BaselineSystemTimeQpc = 0x0000004b17cd596c;
|
||||
@@ -61,7 +61,7 @@ namespace
|
||||
kusd.TelemetryCoverageRound = 0x00000001;
|
||||
kusd.LangGenerationCount = 0x00000003;
|
||||
kusd.InterruptTimeBias = 0x00000015a5d56406;
|
||||
kusd.ActiveProcessorCount = 0x0000000c;
|
||||
kusd.ActiveProcessorCount = 0x00000004;
|
||||
kusd.ActiveGroupCount = 0x01;
|
||||
kusd.TimeZoneBiasEffectiveStart.QuadPart = 0x01db276e654cb2ff;
|
||||
kusd.TimeZoneBiasEffectiveEnd.QuadPart = 0x01db280b8c3b2800;
|
||||
|
||||
@@ -654,7 +654,6 @@ namespace minidump_loader
|
||||
return;
|
||||
}
|
||||
|
||||
win_emu.process.current_ip = exception_info->exception_record.exception_address;
|
||||
win_emu.log.info("Exception context: address=0x%" PRIx64 ", code=0x%08X, thread=%u\n",
|
||||
exception_info->exception_record.exception_address, exception_info->exception_record.exception_code,
|
||||
exception_info->thread_id);
|
||||
@@ -704,4 +703,4 @@ namespace minidump_loader
|
||||
throw;
|
||||
}
|
||||
}
|
||||
} // namespace minidump_loader
|
||||
} // namespace minidump_loader
|
||||
|
||||
@@ -39,6 +39,19 @@ class module_manager
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mapped_module* find_by_name(const std::string_view name)
|
||||
{
|
||||
for (auto& mod : this->modules_ | std::views::values)
|
||||
{
|
||||
if (mod.name == name)
|
||||
{
|
||||
return &mod;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* find_name(const uint64_t address)
|
||||
{
|
||||
const auto* mod = this->find_by_address(address);
|
||||
|
||||
@@ -225,6 +225,8 @@ void process_context::setup(x86_64_emulator& emu, memory_manager& memory, regist
|
||||
p.HeapDeCommitFreeBlockThreshold = 0x0000000000001000;
|
||||
p.NumberOfHeaps = 0x00000000;
|
||||
p.MaximumNumberOfHeaps = 0x00000010;
|
||||
p.NumberOfProcessors = 4;
|
||||
p.ImageSubsystemMajorVersion = 6;
|
||||
|
||||
p.OSPlatformId = 2;
|
||||
p.OSMajorVersion = 0x0000000a;
|
||||
@@ -246,8 +248,6 @@ void process_context::setup(x86_64_emulator& emu, memory_manager& memory, regist
|
||||
|
||||
void process_context::serialize(utils::buffer_serializer& buffer) const
|
||||
{
|
||||
buffer.write(this->current_ip);
|
||||
buffer.write(this->previous_ip);
|
||||
buffer.write(this->shared_section_address);
|
||||
buffer.write(this->shared_section_size);
|
||||
buffer.write(this->dbwin_buffer);
|
||||
@@ -285,8 +285,6 @@ void process_context::serialize(utils::buffer_serializer& buffer) const
|
||||
|
||||
void process_context::deserialize(utils::buffer_deserializer& buffer)
|
||||
{
|
||||
buffer.read(this->current_ip);
|
||||
buffer.read(this->previous_ip);
|
||||
buffer.read(this->shared_section_address);
|
||||
buffer.read(this->shared_section_size);
|
||||
buffer.read(this->dbwin_buffer);
|
||||
|
||||
@@ -83,9 +83,6 @@ struct process_context
|
||||
|
||||
callbacks* callbacks_{};
|
||||
|
||||
uint64_t current_ip{0};
|
||||
uint64_t previous_ip{0};
|
||||
|
||||
uint64_t shared_section_address{0};
|
||||
uint64_t shared_section_size{0};
|
||||
uint64_t dbwin_buffer{0};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "windows_emulator.hpp"
|
||||
#include <ctime>
|
||||
#include <platform/primitives.hpp>
|
||||
#include "windows-emulator/devices/named_pipe.hpp"
|
||||
#include "devices/named_pipe.hpp"
|
||||
|
||||
struct syscall_context
|
||||
{
|
||||
|
||||
@@ -180,6 +180,7 @@ namespace syscalls
|
||||
/*receive_message_attributes*/,
|
||||
emulator_object<LARGE_INTEGER> /*timeout*/);
|
||||
NTSTATUS handle_NtAlpcConnectPort();
|
||||
NTSTATUS handle_NtAlpcConnectPortEx();
|
||||
|
||||
// syscalls/process.cpp:
|
||||
NTSTATUS handle_NtQueryInformationProcess(const syscall_context& c, handle process_handle, uint32_t info_class,
|
||||
@@ -1050,6 +1051,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
|
||||
add_handler(NtEnumerateKey);
|
||||
add_handler(NtEnumerateValueKey);
|
||||
add_handler(NtAlpcConnectPort);
|
||||
add_handler(NtAlpcConnectPortEx);
|
||||
add_handler(NtGetNextThread);
|
||||
add_handler(NtSetInformationObject);
|
||||
add_handler(NtUserGetCursorPos);
|
||||
|
||||
@@ -94,4 +94,9 @@ namespace syscalls
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtAlpcConnectPortEx()
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,8 +267,8 @@ namespace syscalls
|
||||
basic_info.AllocationGranularity = ALLOCATION_GRANULARITY;
|
||||
basic_info.MinimumUserModeAddress = MIN_ALLOCATION_ADDRESS;
|
||||
basic_info.MaximumUserModeAddress = MAX_ALLOCATION_ADDRESS;
|
||||
basic_info.ActiveProcessorsAffinityMask = 0x0000000000000fff;
|
||||
basic_info.NumberOfProcessors = 1;
|
||||
basic_info.ActiveProcessorsAffinityMask = 0x0000000000000f;
|
||||
basic_info.NumberOfProcessors = 4;
|
||||
});
|
||||
|
||||
default:
|
||||
|
||||
@@ -420,8 +420,8 @@ void windows_emulator::on_instruction_execution(const uint64_t address)
|
||||
this->yield_thread();
|
||||
}
|
||||
|
||||
this->process.previous_ip = this->process.current_ip;
|
||||
this->process.current_ip = this->emu().read_instruction_pointer();
|
||||
thread.previous_ip = thread.current_ip;
|
||||
thread.current_ip = this->emu().read_instruction_pointer();
|
||||
|
||||
this->callbacks.on_instruction(address);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user