初步增加32位支持(没加全)

This commit is contained in:
huoji
2025-03-19 20:47:26 +08:00
parent 9b970ce8a2
commit 232a7abcba
9 changed files with 819 additions and 137 deletions

View File

@@ -651,7 +651,7 @@ auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
if (!peconv::load_imports(m_peInfo->peBuffer, &importFixer)) {
throw std::runtime_error("Failed to fix imports");
}
//给所有导入表加c3
// 给所有导入表加c3
for (const auto& module : this->GetModuleList()) {
// 遍历导出函数查找对应名称
for (const auto& exp : module->export_function) {
@@ -751,8 +751,8 @@ auto Sandbox::Run(uint64_t address) -> void {
}
// 系统调用钩子
err = uc_hook_add(m_ucEngine, &hook_syscall, UC_HOOK_INTR | UC_HOOK_INSN,
reinterpret_cast<void*>(sandboxCallbacks::handleSyscall),
this, 1, 0, UC_X86_INS_SYSCALL);
reinterpret_cast<void*>(sandboxCallbacks::handleSyscall),
this, 1, 0, UC_X86_INS_SYSCALL);
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to add syscall hook");
}
@@ -773,9 +773,38 @@ auto Sandbox::Run(uint64_t address) -> void {
// 1.入口点是必须跑的
if (m_peInfo->isDll) {
// 给rcx和rdx设置dll应该设置的
auto dll_fdwReason = 1;
uc_reg_write(m_ucEngine, UC_X86_REG_RCX, &m_peInfo->RecImageBase);
uc_reg_write(m_ucEngine, UC_X86_REG_RDX, &dll_fdwReason);
auto dll_fdwReason = 1; // DLL_PROCESS_ATTACH
if (m_peInfo->isX64) {
uc_reg_write(m_ucEngine, UC_X86_REG_RCX, &m_peInfo->RecImageBase);
uc_reg_write(m_ucEngine, UC_X86_REG_RDX, &dll_fdwReason);
} else {
// 32位使用栈传参而不是寄存器传参
uint32_t rsp;
uc_reg_read(m_ucEngine, UC_X86_REG_ESP, &rsp);
// 为参数腾出空间
rsp -= 3 * 4; // 三个参数hinstDLL, fdwReason, lpvReserved
uc_reg_write(m_ucEngine, UC_X86_REG_ESP, &rsp);
// 按照从右到左的顺序压栈
uint32_t lpvReserved = 0; // 第三个参数为NULL
uint32_t reason = dll_fdwReason; // DLL_PROCESS_ATTACH
uint32_t imageBase = static_cast<uint32_t>(m_peInfo->RecImageBase);
// 按照从右到左的调用约定写入参数到栈上
uc_mem_write(m_ucEngine, rsp, &lpvReserved,
sizeof(uint32_t)); // lpvReserved (最右侧参数最先入栈)
uc_mem_write(m_ucEngine, rsp + 4, &reason,
sizeof(uint32_t)); // fdwReason (中间参数次之入栈)
uc_mem_write(m_ucEngine, rsp + 8, &imageBase,
sizeof(uint32_t)); // hinstDLL (最左侧参数最后入栈)
// 在Windows下DLL的返回地址也需要压栈
uint32_t returnAddress = 0xABABABAB; // 虚拟的返回地址
rsp -= 4; // 为返回地址腾出空间
uc_reg_write(m_ucEngine, UC_X86_REG_ESP, &rsp);
uc_mem_write(m_ucEngine, rsp, &returnAddress, sizeof(uint32_t));
}
}
err = uc_emu_start(m_ucEngine, entryPoint, m_peInfo->imageEnd, timeout, 0);
// 2. 有自定义地址 再跑自定义地址