Prepare PEB/TEB

This commit is contained in:
momo5502
2024-08-17 15:30:57 +02:00
parent 654646c97f
commit bb2ba42de4
3 changed files with 59 additions and 21 deletions

View File

@@ -17,7 +17,7 @@ set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
##########################################
project(bird LANGUAGES C CXX)
project(emulator LANGUAGES C CXX)
##########################################

View File

@@ -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)

View File

@@ -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);
}
}