mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-20 12:13:57 +00:00
Demo stuff
This commit is contained in:
@@ -34,19 +34,8 @@ namespace
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void run()
|
||||
void run_emulation(windows_emulator& win_emu)
|
||||
{
|
||||
windows_emulator win_emu {
|
||||
R"(C:\Users\mauri\source\repos\ConsoleApplication6\x64\Release\ConsoleApplication6.exe)",
|
||||
{
|
||||
L"Hello",
|
||||
L"World",
|
||||
}
|
||||
};
|
||||
|
||||
watch_system_objects(win_emu);
|
||||
|
||||
try
|
||||
{
|
||||
if (use_gdb)
|
||||
@@ -69,6 +58,52 @@ namespace
|
||||
|
||||
printf("Emulation done.\n");
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
windows_emulator win_emu{
|
||||
R"(C:\Users\mauri\Desktop\Desktop\qiling-sample\lul.exe)",
|
||||
{
|
||||
L"Hello",
|
||||
L"World",
|
||||
}
|
||||
};
|
||||
|
||||
watch_system_objects(win_emu);
|
||||
|
||||
|
||||
const auto& exe = *win_emu.process().executable;
|
||||
|
||||
const auto text_start = exe.image_base + 0x1000;
|
||||
const auto text_end = exe.image_base + 0x52000;
|
||||
const auto scan_size = 0x1000;
|
||||
|
||||
win_emu.emu().hook_memory_read(text_start, scan_size, [&](uint64_t address, size_t, uint64_t)
|
||||
{
|
||||
const auto rip = win_emu.emu().read_instruction_pointer();
|
||||
if (rip >= text_start && rip < text_end)
|
||||
{
|
||||
win_emu.logger.print(color::green, "Reading from executable .text: 0x%llX at 0x%llX\n", address, rip);
|
||||
}
|
||||
});
|
||||
|
||||
win_emu.add_syscall_hook([&]
|
||||
{
|
||||
const auto rip = win_emu.emu().read_instruction_pointer();
|
||||
if (rip >= text_start && rip < text_end)
|
||||
{
|
||||
const auto syscall_id = win_emu.emu().reg(x64_register::eax);
|
||||
const auto syscall_name = win_emu.dispatcher().get_syscall_name(syscall_id);
|
||||
|
||||
win_emu.logger.print(color::blue, "Executing inline syscall: %s (0x%X) at 0x%llX\n", syscall_name.c_str(),
|
||||
syscall_id, rip);
|
||||
}
|
||||
|
||||
return instruction_hook_continuation::run_instruction;
|
||||
});
|
||||
|
||||
run_emulation(win_emu);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int /*argc*/, char** /*argv*/)
|
||||
|
||||
@@ -13,8 +13,9 @@ emulator_hook* watch_object(windows_emulator& emu, emulator_object<T> object)
|
||||
const auto rip = emu.emu().read_instruction_pointer();
|
||||
|
||||
const auto offset = address - object.value();
|
||||
printf("%s: %llX (%s) at %llX (%s)\n", i.get_type_name().c_str(), offset,
|
||||
i.get_member_name(offset).c_str(), rip,
|
||||
emu.process().module_manager.find_name(rip));
|
||||
emu.logger.log("Object access: %s - %llX (%s) at %llX (%s)\n", i.get_type_name().c_str(),
|
||||
offset,
|
||||
i.get_member_name(offset).c_str(), rip,
|
||||
emu.process().module_manager.find_name(rip));
|
||||
});
|
||||
}
|
||||
|
||||
94
src/windows_emulator/logger.cpp
Normal file
94
src/windows_emulator/logger.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "std_include.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <utils/finally.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#define COLOR(win, posix) win
|
||||
using color_type = WORD;
|
||||
#else
|
||||
#define COLOR(win, posix) posix
|
||||
using color_type = const char*;
|
||||
#endif
|
||||
|
||||
color_type get_reset_color()
|
||||
{
|
||||
return COLOR(7, "\033[0m");
|
||||
}
|
||||
|
||||
color_type get_color_type(const color c)
|
||||
{
|
||||
using enum color;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case black: return COLOR(0x8, "\033[0;90m");
|
||||
case red: return COLOR(0xC, "\033[0;91m");
|
||||
case green: return COLOR(0xA, "\033[0;92m");
|
||||
case yellow: return COLOR(0xE, "\033[0;93m");
|
||||
case blue: return COLOR(0x9, "\033[0;94m");
|
||||
case cyan: return COLOR(0xB, "\033[0;96m");
|
||||
case pink: return COLOR(0xD, "\033[0;95m");
|
||||
case white: return COLOR(0xF, "\033[0;97m");
|
||||
case gray:
|
||||
default: return get_reset_color();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE get_console_handle()
|
||||
{
|
||||
return GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
void set_color(const color_type color)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetConsoleTextAttribute(get_console_handle(), color);
|
||||
#else
|
||||
printf("%s", color);
|
||||
#endif
|
||||
}
|
||||
|
||||
void reset_color()
|
||||
{
|
||||
(void)fflush(stdout);
|
||||
set_color(get_reset_color());
|
||||
(void)fflush(stdout);
|
||||
}
|
||||
|
||||
std::string_view format(va_list* ap, const char* message)
|
||||
{
|
||||
thread_local char buffer[0x1000];
|
||||
|
||||
#ifdef _WIN32
|
||||
const int count = _vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), message, *ap);
|
||||
#else
|
||||
const int count = vsnprintf(buffer, sizeof(buffer), message, *ap);
|
||||
#endif
|
||||
|
||||
if (count < 0) return {};
|
||||
return {buffer, static_cast<size_t>(count)};
|
||||
}
|
||||
|
||||
void print_colored(const std::string_view& line, const color_type base_color)
|
||||
{
|
||||
const auto _ = utils::finally(&reset_color);
|
||||
set_color(base_color);
|
||||
(void)fwrite(line.data(), 1, line.size(), stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void logger::print(const color c, const char* message, ...) const
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, message);
|
||||
|
||||
const auto data = format(&ap, message);
|
||||
print_colored(data, get_color_type(c));
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
50
src/windows_emulator/logger.hpp
Normal file
50
src/windows_emulator/logger.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
enum class color
|
||||
{
|
||||
black,
|
||||
red,
|
||||
green,
|
||||
yellow,
|
||||
blue,
|
||||
cyan,
|
||||
pink,
|
||||
white,
|
||||
gray,
|
||||
};
|
||||
|
||||
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...);
|
||||
}
|
||||
};
|
||||
@@ -26,6 +26,11 @@ public:
|
||||
|
||||
void setup(const exported_symbols& ntdll_exports, const exported_symbols& win32u_exports);
|
||||
|
||||
std::string get_syscall_name(const uint64_t id)
|
||||
{
|
||||
return this->handlers_.at(id).name;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<uint64_t, syscall_handler_entry> handlers_{};
|
||||
|
||||
|
||||
@@ -535,6 +535,14 @@ void windows_emulator::setup_hooks()
|
||||
{
|
||||
this->emu().hook_instruction(x64_hookable_instructions::syscall, [&]
|
||||
{
|
||||
for (const auto& hook : this->syscall_hooks_)
|
||||
{
|
||||
if (hook() == instruction_hook_continuation::skip_instruction)
|
||||
{
|
||||
return instruction_hook_continuation::skip_instruction;
|
||||
}
|
||||
}
|
||||
|
||||
this->dispatcher_.dispatch(this->emu(), this->process());
|
||||
return instruction_hook_continuation::skip_instruction;
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "syscalls.hpp"
|
||||
#include "process_context.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
std::unique_ptr<x64_emulator> create_default_x64_emulator();
|
||||
|
||||
@@ -38,6 +39,16 @@ public:
|
||||
return this->process_;
|
||||
}
|
||||
|
||||
syscall_dispatcher& dispatcher()
|
||||
{
|
||||
return this->dispatcher_;
|
||||
}
|
||||
|
||||
const syscall_dispatcher& dispatcher() const
|
||||
{
|
||||
return this->dispatcher_;
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const;
|
||||
void deserialize(utils::buffer_deserializer& buffer);
|
||||
|
||||
@@ -49,10 +60,19 @@ public:
|
||||
this->verbose_ = verbose;
|
||||
}
|
||||
|
||||
void add_syscall_hook(instruction_hook_callback callback)
|
||||
{
|
||||
this->syscall_hooks_.push_back(std::move(callback));
|
||||
}
|
||||
|
||||
logger logger{};
|
||||
|
||||
private:
|
||||
bool verbose_{false};
|
||||
std::unique_ptr<x64_emulator> emu_{};
|
||||
|
||||
std::vector<instruction_hook_callback> syscall_hooks_{};
|
||||
|
||||
process_context process_;
|
||||
syscall_dispatcher dispatcher_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user