mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 08:36:16 +00:00
Prepare PEB/TEB
This commit is contained in:
@@ -17,7 +17,7 @@ set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
|
||||
|
||||
##########################################
|
||||
|
||||
project(bird LANGUAGES C CXX)
|
||||
project(emulator LANGUAGES C CXX)
|
||||
|
||||
##########################################
|
||||
|
||||
|
||||
@@ -6,16 +6,14 @@ file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS
|
||||
|
||||
list(SORT SRC_FILES)
|
||||
|
||||
add_executable(client ${SRC_FILES})
|
||||
add_executable(emulator ${SRC_FILES})
|
||||
|
||||
momo_assign_source_group(${SRC_FILES})
|
||||
|
||||
target_precompile_headers(client PRIVATE std_include.hpp)
|
||||
target_precompile_headers(emulator PRIVATE std_include.hpp)
|
||||
|
||||
target_link_libraries(client PRIVATE unicorn phnt::phnt)
|
||||
target_link_libraries(emulator PRIVATE unicorn phnt::phnt)
|
||||
|
||||
set_target_properties(client PROPERTIES OUTPUT_NAME "bird")
|
||||
set_property(GLOBAL PROPERTY VS_STARTUP_PROJECT emulator)
|
||||
|
||||
set_property(GLOBAL PROPERTY VS_STARTUP_PROJECT client)
|
||||
|
||||
momo_strip_target(client)
|
||||
momo_strip_target(emulator)
|
||||
|
||||
@@ -1,36 +1,76 @@
|
||||
#include "std_include.hpp"
|
||||
|
||||
#define X86_CODE32 "\x41\x4a" // INC ecx; DEC edx
|
||||
#define X86_CODE32 "\x65\x48\x8B\x04\x25\x60\x00\x00\x00" // INC ecx; DEC edx
|
||||
#define ADDRESS 0x1000000
|
||||
|
||||
#define GS_SEGMENT_ADDR 0x6000000ULL
|
||||
#define GS_SEGMENT_SIZE (20 << 20) // 20 MB
|
||||
|
||||
#define IA32_GS_BASE_MSR 0xC0000101
|
||||
|
||||
#define STACK_SIZE 0x40000
|
||||
|
||||
#include "unicorn.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
uint64_t align_down(const uint64_t value, const uint64_t alignment)
|
||||
{
|
||||
return value & ~(alignment - 1);
|
||||
}
|
||||
|
||||
uint64_t align_up(const uint64_t value, const uint64_t alignment)
|
||||
{
|
||||
return align_down(value + (alignment - 1), alignment);
|
||||
}
|
||||
|
||||
void setup_gs_segment(const unicorn& uc, const uint64_t segment_base, const size_t size)
|
||||
{
|
||||
const std::array<uint64_t, 2> value = {
|
||||
IA32_GS_BASE_MSR,
|
||||
segment_base
|
||||
};
|
||||
|
||||
e(uc_reg_write(uc, UC_X86_REG_MSR, value.data()));
|
||||
e(uc_mem_map(uc, segment_base, size, UC_PROT_READ | UC_PROT_WRITE));
|
||||
}
|
||||
|
||||
void setup_teb_and_peb(const unicorn& uc)
|
||||
{
|
||||
setup_gs_segment(uc, GS_SEGMENT_ADDR, GS_SEGMENT_SIZE);
|
||||
|
||||
constexpr auto teb_address = GS_SEGMENT_ADDR;
|
||||
const auto peb_address = align_up(teb_address + sizeof(TEB), 0x10);
|
||||
|
||||
TEB teb{};
|
||||
teb.NtTib.Self = reinterpret_cast<NT_TIB*>(teb_address);
|
||||
teb.ProcessEnvironmentBlock = reinterpret_cast<PEB*>(peb_address);
|
||||
|
||||
|
||||
PEB peb{};
|
||||
|
||||
e(uc_mem_write(uc, teb_address, &teb, sizeof(teb)));
|
||||
e(uc_mem_write(uc, peb_address, &peb, sizeof(peb)));
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
int r_ecx = 0x1234; // ECX register
|
||||
int r_edx = 0x7890; // EDX register
|
||||
|
||||
printf("Emulate i386 code\n");
|
||||
|
||||
const unicorn uc{UC_ARCH_X86, UC_MODE_32};
|
||||
const unicorn uc{UC_ARCH_X86, UC_MODE_64};
|
||||
|
||||
e(uc_mem_map(uc, ADDRESS, 0x1000, UC_PROT_ALL));
|
||||
e(uc_mem_write(uc, ADDRESS, X86_CODE32, sizeof(X86_CODE32) - 1));
|
||||
|
||||
e(uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx));
|
||||
e(uc_reg_write(uc, UC_X86_REG_EDX, &r_edx));
|
||||
|
||||
setup_teb_and_peb(uc);
|
||||
|
||||
e(uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32) - 1, 0, 0));
|
||||
|
||||
printf("Emulation done. Below is the CPU context\n");
|
||||
|
||||
e(uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx));
|
||||
e(uc_reg_read(uc, UC_X86_REG_EDX, &r_edx));
|
||||
uint64_t rax{};
|
||||
e(uc_reg_read(uc, UC_X86_REG_RAX, &rax));
|
||||
|
||||
printf(">>> ECX = 0x%x\n", r_ecx);
|
||||
printf(">>> EDX = 0x%x\n", r_edx);
|
||||
printf(">>> RAX = 0x%llX\n", rax);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user