add new API
This commit is contained in:
@@ -383,5 +383,13 @@ int main(int argc, char* argv[]) {
|
|||||||
printf("result: %d \n", result);
|
printf("result: %d \n", result);
|
||||||
//DetectMalwareInDirectory(filePath);
|
//DetectMalwareInDirectory(filePath);
|
||||||
*/
|
*/
|
||||||
|
auto peInfo = getPeInfo("x");
|
||||||
|
if (peInfo == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Sandbox se;
|
||||||
|
se.InitEnv(peInfo);
|
||||||
|
se.Run(0x7880);
|
||||||
|
//se.Run();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#define LOG_LEVEL 0
|
#define LOG_LEVEL 4
|
||||||
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|||||||
@@ -405,6 +405,8 @@ auto Api_LeaveCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
|
|||||||
-> void;
|
-> void;
|
||||||
auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
|
auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||||
-> void;
|
-> void;
|
||||||
|
auto Api_GetStartupInfoA(void* sandbox, uc_engine* uc, uint64_t address)
|
||||||
|
-> void;
|
||||||
auto Api_GetStdHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
auto Api_GetStdHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||||
auto Api_GetFileType(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
auto Api_GetFileType(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||||
auto Api_HeapCreate(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
auto Api_HeapCreate(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||||
@@ -471,6 +473,7 @@ auto Api_TlsFree(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
|||||||
auto Api_FlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
auto Api_FlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||||
auto Api_FlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
auto Api_FlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||||
auto Api__initterm_e(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
auto Api__initterm_e(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||||
|
auto Api__initterm(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||||
auto Api_getenv(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
auto Api_getenv(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||||
auto Api_GetStringTypeW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
auto Api_GetStringTypeW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||||
auto Api_CreateDirectoryW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
auto Api_CreateDirectoryW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||||
|
|||||||
@@ -858,7 +858,19 @@ auto Api_AdjustTokenPrivileges(void* sandbox, uc_engine* uc, uint64_t address)
|
|||||||
context->GetTeb32()->LastErrorValue = error;
|
context->GetTeb32()->LastErrorValue = error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto Api_GetTickCount(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||||||
|
auto context = static_cast<Sandbox*>(sandbox);
|
||||||
|
// 调用真实的 Windows API 获取当前系统启动以来的毫秒数
|
||||||
|
DWORD tick_count = GetTickCount();
|
||||||
|
// 将结果写入模拟器的返回值寄存器
|
||||||
|
// GetTickCount 返回的是 DWORD (32位),因此无论 x64 还是 x86,都写入 EAX
|
||||||
|
// 在 x64 架构中,EAX 是 RAX 的低 32 位
|
||||||
|
uint32_t result = tick_count;
|
||||||
|
uc_reg_write(uc,
|
||||||
|
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||||
|
&result);
|
||||||
|
printf("[*] GetTickCount called, returning 0x%x (%u)\n", tick_count, tick_count);
|
||||||
|
}
|
||||||
auto Sandbox::InitApiHooks() -> void {
|
auto Sandbox::InitApiHooks() -> void {
|
||||||
auto FakeApi_GetSystemTimeAsFileTime =
|
auto FakeApi_GetSystemTimeAsFileTime =
|
||||||
_fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1};
|
_fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1};
|
||||||
@@ -903,6 +915,8 @@ auto Sandbox::InitApiHooks() -> void {
|
|||||||
_fakeApi{.func = Api_LeaveCriticalSection, .paramCount = 1};
|
_fakeApi{.func = Api_LeaveCriticalSection, .paramCount = 1};
|
||||||
auto FakeApi_GetStartupInfoW =
|
auto FakeApi_GetStartupInfoW =
|
||||||
_fakeApi{.func = Api_GetStartupInfoW, .paramCount = 1};
|
_fakeApi{.func = Api_GetStartupInfoW, .paramCount = 1};
|
||||||
|
auto FakeApi_GetStartupInfoA =
|
||||||
|
_fakeApi{ .func = Api_GetStartupInfoA, .paramCount = 1 };
|
||||||
auto FakeApi_GetStdHandle =
|
auto FakeApi_GetStdHandle =
|
||||||
_fakeApi{.func = Api_GetStdHandle, .paramCount = 1};
|
_fakeApi{.func = Api_GetStdHandle, .paramCount = 1};
|
||||||
auto FakeApi_GetFileType =
|
auto FakeApi_GetFileType =
|
||||||
@@ -1038,13 +1052,15 @@ auto Sandbox::InitApiHooks() -> void {
|
|||||||
// *** 新增 LCMapStringEx ***
|
// *** 新增 LCMapStringEx ***
|
||||||
auto FakeApi_LCMapStringEx =
|
auto FakeApi_LCMapStringEx =
|
||||||
_fakeApi{.func = Api_LCMapStringEx, .paramCount = 9}; // LCMapStringEx 有 9 个参数
|
_fakeApi{.func = Api_LCMapStringEx, .paramCount = 9}; // LCMapStringEx 有 9 个参数
|
||||||
|
auto FakeApi_GetTickCount = _fakeApi{ .func = Api_GetTickCount, .paramCount = 0 }; // !!! 新增行 !!!
|
||||||
|
|
||||||
// 添加文件操作相关API
|
// 添加文件操作相关API
|
||||||
auto FakeApi_CreateFileW = _fakeApi{.func = Api_CreateFileW, .paramCount = 7};
|
auto FakeApi_CreateFileW = _fakeApi{.func = Api_CreateFileW, .paramCount = 7};
|
||||||
auto FakeApi_ReadFileA = _fakeApi{.func = Api_ReadFileA, .paramCount = 5};
|
auto FakeApi_ReadFileA = _fakeApi{.func = Api_ReadFileA, .paramCount = 5};
|
||||||
auto FakeApi_ReadFileW = _fakeApi{.func = Api_ReadFileW, .paramCount = 5};
|
auto FakeApi_ReadFileW = _fakeApi{.func = Api_ReadFileW, .paramCount = 5};
|
||||||
auto FakeApi_CloseFile = _fakeApi{.func = Api_CloseFile, .paramCount = 1};
|
auto FakeApi_CloseFile = _fakeApi{.func = Api_CloseFile, .paramCount = 1};
|
||||||
|
auto FakeApi__initterm =
|
||||||
|
_fakeApi{ .func = Api__initterm, .paramCount = 2 }; // 新增行
|
||||||
api_map = {
|
api_map = {
|
||||||
{"GetSystemTimeAsFileTime",
|
{"GetSystemTimeAsFileTime",
|
||||||
std::make_shared<_fakeApi>(FakeApi_GetSystemTimeAsFileTime)},
|
std::make_shared<_fakeApi>(FakeApi_GetSystemTimeAsFileTime)},
|
||||||
@@ -1082,6 +1098,8 @@ auto Sandbox::InitApiHooks() -> void {
|
|||||||
std::make_shared<_fakeApi>(FakeApi_LeaveCriticalSection)},
|
std::make_shared<_fakeApi>(FakeApi_LeaveCriticalSection)},
|
||||||
{"GetStartupInfoW",
|
{"GetStartupInfoW",
|
||||||
std::make_shared<_fakeApi>(FakeApi_GetStartupInfoW)},
|
std::make_shared<_fakeApi>(FakeApi_GetStartupInfoW)},
|
||||||
|
{"GetStartupInfoA",
|
||||||
|
std::make_shared<_fakeApi>(FakeApi_GetStartupInfoA)},
|
||||||
{"GetStdHandle", std::make_shared<_fakeApi>(FakeApi_GetStdHandle)},
|
{"GetStdHandle", std::make_shared<_fakeApi>(FakeApi_GetStdHandle)},
|
||||||
{"GetFileType", std::make_shared<_fakeApi>(FakeApi_GetFileType)},
|
{"GetFileType", std::make_shared<_fakeApi>(FakeApi_GetFileType)},
|
||||||
{"GetCommandLineA",
|
{"GetCommandLineA",
|
||||||
@@ -1176,6 +1194,7 @@ auto Sandbox::InitApiHooks() -> void {
|
|||||||
{"TlsFree", std::make_shared<_fakeApi>(FakeApi_TlsFree)},
|
{"TlsFree", std::make_shared<_fakeApi>(FakeApi_TlsFree)},
|
||||||
{"FlsAlloc", std::make_shared<_fakeApi>(FakeApi_FlsAlloc)},
|
{"FlsAlloc", std::make_shared<_fakeApi>(FakeApi_FlsAlloc)},
|
||||||
{"FlsGetValue", std::make_shared<_fakeApi>(FakeApi_FlsGetValue)},
|
{"FlsGetValue", std::make_shared<_fakeApi>(FakeApi_FlsGetValue)},
|
||||||
|
{"_initterm", std::make_shared<_fakeApi>(FakeApi__initterm) }, // 新增行
|
||||||
{"_initterm_e", std::make_shared<_fakeApi>(FakeApi__initterm_e)},
|
{"_initterm_e", std::make_shared<_fakeApi>(FakeApi__initterm_e)},
|
||||||
{"GetStringTypeW", std::make_shared<_fakeApi>(FakeApi_GetStringTypeW)},
|
{"GetStringTypeW", std::make_shared<_fakeApi>(FakeApi_GetStringTypeW)},
|
||||||
{"LCMapStringW", std::make_shared<_fakeApi>(FakeApi_LCMapStringW)},
|
{"LCMapStringW", std::make_shared<_fakeApi>(FakeApi_LCMapStringW)},
|
||||||
@@ -1194,6 +1213,8 @@ auto Sandbox::InitApiHooks() -> void {
|
|||||||
{"ReadFileA", std::make_shared<_fakeApi>(FakeApi_ReadFileA)},
|
{"ReadFileA", std::make_shared<_fakeApi>(FakeApi_ReadFileA)},
|
||||||
{"ReadFileW", std::make_shared<_fakeApi>(FakeApi_ReadFileW)},
|
{"ReadFileW", std::make_shared<_fakeApi>(FakeApi_ReadFileW)},
|
||||||
{"CloseFile", std::make_shared<_fakeApi>(FakeApi_CloseFile)},
|
{"CloseFile", std::make_shared<_fakeApi>(FakeApi_CloseFile)},
|
||||||
|
{ "GetTickCount", std::make_shared<_fakeApi>(FakeApi_GetTickCount) }, // !!! 新增行 !!!
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
|
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
|
||||||
|
|||||||
@@ -1450,71 +1450,81 @@ auto Api_LeaveCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
|
|||||||
|
|
||||||
printf("[*] LeaveCriticalSection: CS=0x%llx\n", lpCriticalSection);
|
printf("[*] LeaveCriticalSection: CS=0x%llx\n", lpCriticalSection);
|
||||||
}
|
}
|
||||||
|
auto GetStartupInfoHelper(void* sandbox, uc_engine* uc, uint64_t call_address, bool isWideChar) -> void {
|
||||||
auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
|
|
||||||
-> void {
|
|
||||||
auto context = static_cast<Sandbox*>(sandbox);
|
auto context = static_cast<Sandbox*>(sandbox);
|
||||||
uint64_t lpStartupInfo = 0;
|
uint64_t lpStartupInfo = 0;
|
||||||
printf("[*] GetStartupInfoW start dump vmenv\n");
|
// 获取 lpStartupInfo 参数 (A 和 W 版本通用)
|
||||||
// 获取参数
|
|
||||||
if (context->GetPeInfo()->isX64) {
|
if (context->GetPeInfo()->isX64) {
|
||||||
// x64: rcx = lpStartupInfo
|
// x64: 第一个参数在 RCX 寄存器
|
||||||
uc_reg_read(uc, UC_X86_REG_RCX, &lpStartupInfo);
|
uc_reg_read(uc, UC_X86_REG_RCX, &lpStartupInfo);
|
||||||
} else {
|
|
||||||
// x86: 从栈上读取参数
|
|
||||||
uint32_t esp_address = 0;
|
|
||||||
uint32_t temp_info = 0;
|
|
||||||
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
|
|
||||||
esp_address += 0x4; // 跳过返回地址
|
|
||||||
uc_mem_read(uc, esp_address, &temp_info, sizeof(uint32_t));
|
|
||||||
lpStartupInfo = temp_info;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (lpStartupInfo != 0) {
|
// x86: 参数在栈上,返回地址之后
|
||||||
if (context->GetPeInfo()->isX64) {
|
uint32_t esp_address = 0;
|
||||||
STARTUPINFOW si = {0};
|
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
|
||||||
|
esp_address += 0x4; // 跳过返回地址
|
||||||
|
uint32_t temp_startup_info = 0;
|
||||||
|
uc_mem_read(uc, esp_address, &temp_startup_info, sizeof(uint32_t));
|
||||||
|
lpStartupInfo = temp_startup_info;
|
||||||
|
}
|
||||||
|
if (lpStartupInfo == 0) {
|
||||||
|
printf("[-] GetStartupInfo%c: lpStartupInfo is NULL. Aborting.\n", isWideChar ? 'W' : 'A');
|
||||||
|
// 根据需要设置 LastError
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uc_err err = UC_ERR_OK;
|
||||||
|
size_t struct_size = 0;
|
||||||
|
printf("[*] GetStartupInfo%c called. Populating STARTUPINFO%c at 0x%llx\n",
|
||||||
|
isWideChar ? 'W' : 'A', isWideChar ? 'W' : 'A', lpStartupInfo);
|
||||||
|
if (context->GetPeInfo()->isX64) {
|
||||||
|
if (isWideChar) {
|
||||||
|
STARTUPINFOW si = { 0 };
|
||||||
si.cb = sizeof(STARTUPINFOW);
|
si.cb = sizeof(STARTUPINFOW);
|
||||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||||
si.wShowWindow = SW_SHOWNORMAL;
|
si.wShowWindow = SW_SHOWNORMAL; // 与你原有的 Api_GetStartupInfoW 保持一致
|
||||||
si.lpDesktop = nullptr;
|
// 其他字段保持为 nullptr/0
|
||||||
si.lpTitle = nullptr;
|
struct_size = sizeof(STARTUPINFOW);
|
||||||
si.dwX = 0;
|
err = uc_mem_write(uc, lpStartupInfo, &si, struct_size);
|
||||||
si.dwY = 0;
|
}
|
||||||
si.dwXSize = 0;
|
else {
|
||||||
si.dwYSize = 0;
|
STARTUPINFOA si = { 0 }; // 标准 WinAPI STARTUPINFOA for x64
|
||||||
si.dwXCountChars = 0;
|
si.cb = sizeof(STARTUPINFOA);
|
||||||
si.dwYCountChars = 0;
|
|
||||||
si.dwFillAttribute = 0;
|
|
||||||
si.cbReserved2 = 0;
|
|
||||||
si.lpReserved2 = nullptr;
|
|
||||||
si.hStdInput = nullptr;
|
|
||||||
si.hStdOutput = nullptr;
|
|
||||||
si.hStdError = nullptr;
|
|
||||||
uc_mem_write(uc, lpStartupInfo, &si, sizeof(STARTUPINFOW));
|
|
||||||
} else {
|
|
||||||
STARTUPINFOW32 si = {0};
|
|
||||||
si.cb = sizeof(STARTUPINFOW32);
|
|
||||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||||
si.wShowWindow = SW_SHOWNORMAL;
|
si.wShowWindow = SW_SHOWNORMAL;
|
||||||
si.lpDesktop = 0;
|
// 其他字段保持为 nullptr/0
|
||||||
si.lpTitle = 0;
|
struct_size = sizeof(STARTUPINFOA);
|
||||||
si.dwX = 0;
|
err = uc_mem_write(uc, lpStartupInfo, &si, struct_size);
|
||||||
si.dwY = 0;
|
|
||||||
si.dwXSize = 0;
|
|
||||||
si.dwYSize = 0;
|
|
||||||
si.dwXCountChars = 0;
|
|
||||||
si.dwYCountChars = 0;
|
|
||||||
si.dwFillAttribute = 0;
|
|
||||||
si.cbReserved2 = 0;
|
|
||||||
si.lpReserved2 = 0;
|
|
||||||
si.hStdInput = 0;
|
|
||||||
si.hStdOutput = 0;
|
|
||||||
si.hStdError = 0;
|
|
||||||
uc_mem_write(uc, lpStartupInfo, &si, sizeof(STARTUPINFOW32));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
printf("[*] GetStartupInfoW: lpStartupInfo=0x%llx\n", lpStartupInfo);
|
// x86 模式,使用 32 位结构体
|
||||||
|
STARTUPINFOW32 si_32 = { 0 }; // 使用 STARTUPINFOW32 作为 32 位通用结构体模板
|
||||||
|
si_32.cb = sizeof(STARTUPINFOW32); // 或 sizeof(STARTUPINFOA32) 如果你定义了它
|
||||||
|
si_32.dwFlags = STARTF_USESHOWWINDOW;
|
||||||
|
si_32.wShowWindow = SW_SHOWNORMAL;
|
||||||
|
// 其他字段保持为 0
|
||||||
|
struct_size = sizeof(STARTUPINFOW32);
|
||||||
|
err = uc_mem_write(uc, lpStartupInfo, &si_32, struct_size);
|
||||||
|
}
|
||||||
|
if (err != UC_ERR_OK) {
|
||||||
|
printf("[-] GetStartupInfo%c: Failed to write STARTUPINFO%c to guest memory at 0x%llx, error: %s\n",
|
||||||
|
isWideChar ? 'W' : 'A', isWideChar ? 'W' : 'A', lpStartupInfo, uc_strerror(err));
|
||||||
|
// 根据需要设置 LastError
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf(" Populated %zu bytes.\n", struct_size);
|
||||||
|
// 如果需要更详细的 dump,可以从模拟内存中读回并打印
|
||||||
|
}
|
||||||
|
// GetStartupInfoA/W 返回 void,所以不需要设置返回值寄存器
|
||||||
|
}
|
||||||
|
auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||||
|
-> void {
|
||||||
|
GetStartupInfoHelper(sandbox, uc, address, true); // 调用通用辅助函数,并标记为宽字符版本
|
||||||
|
}
|
||||||
|
// 新增 GetStartupInfoA
|
||||||
|
auto Api_GetStartupInfoA(void* sandbox, uc_engine* uc, uint64_t address)
|
||||||
|
-> void {
|
||||||
|
GetStartupInfoHelper(sandbox, uc, address, false); // 调用通用辅助函数,并标记为ANSI版本
|
||||||
}
|
}
|
||||||
|
|
||||||
// 实现 GetStdHandle API
|
// 实现 GetStdHandle API
|
||||||
@@ -2386,7 +2396,73 @@ auto Api_FlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
|||||||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||||
&return_value);
|
&return_value);
|
||||||
}
|
}
|
||||||
|
auto Api__initterm(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||||||
|
auto context = static_cast<Sandbox*>(sandbox);
|
||||||
|
uint64_t table_start = 0;
|
||||||
|
uint64_t table_end = 0;
|
||||||
|
// 获取参数:函数表的起始地址和结束地址
|
||||||
|
// _initterm 接收两个参数,与 _initterm_e 相同
|
||||||
|
if (context->GetPeInfo()->isX64) {
|
||||||
|
// x64: 参数在RCX和RDX中
|
||||||
|
uc_reg_read(uc, UC_X86_REG_RCX, &table_start);
|
||||||
|
uc_reg_read(uc, UC_X86_REG_RDX, &table_end);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// x86: 从栈上读取参数
|
||||||
|
uint32_t esp = 0;
|
||||||
|
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
|
||||||
|
esp += 0x4; // 跳过返回地址
|
||||||
|
uint32_t temp_start;
|
||||||
|
uc_mem_read(uc, esp, &temp_start, sizeof(uint32_t));
|
||||||
|
table_start = temp_start;
|
||||||
|
esp += 0x4;
|
||||||
|
uint32_t temp_end;
|
||||||
|
uc_mem_read(uc, esp, &temp_end, sizeof(uint32_t));
|
||||||
|
table_end = temp_end;
|
||||||
|
}
|
||||||
|
// 返回值,通常 _initterm 返回 void,但为保持与 _initterm_e 风格一致,
|
||||||
|
// 我们也返回 int32_t,表示成功(0)。
|
||||||
|
int32_t return_value = 0;
|
||||||
|
// 遍历函数表并“调用”每个初始化函数
|
||||||
|
printf("[*] _initterm: Initializing functions from 0x%llx to 0x%llx\n", table_start,
|
||||||
|
table_end);
|
||||||
|
// 只有当表的起始地址和结束地址有效且顺序正确时才进行处理
|
||||||
|
if (table_start < table_end) {
|
||||||
|
uint64_t current = table_start;
|
||||||
|
uint64_t ptr_size = context->GetPeInfo()->isX64 ? 8 : 4; // 根据架构确定指针大小
|
||||||
|
// 遍历函数表
|
||||||
|
while (current < table_end) {
|
||||||
|
uint64_t function_ptr = 0;
|
||||||
|
// 读取当前表项中的函数指针
|
||||||
|
uc_err err = uc_mem_read(uc, current, &function_ptr, ptr_size);
|
||||||
|
if (err != UC_ERR_OK) {
|
||||||
|
printf("[-] _initterm: Failed to read function pointer at 0x%llx, error: %s\n", current, uc_strerror(err));
|
||||||
|
return_value = -1; // 模拟错误
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// 非空函数指针才“调用”
|
||||||
|
if (function_ptr != 0) {
|
||||||
|
printf("[*] _initterm: Simulating call to initializer function at 0x%llx\n",
|
||||||
|
function_ptr);
|
||||||
|
// 在沙箱环境中,通常我们不会真正地跳转到并执行这些初始化函数,
|
||||||
|
// 而是记录它们的调用。
|
||||||
|
// 如果需要更深度的模拟,可以在这里使用 uc_emu_start
|
||||||
|
// 来模拟执行这些函数,然后跳回当前位置。
|
||||||
|
// 但对于多数初始化例程,简单的记录就足够了。
|
||||||
|
// 例如:
|
||||||
|
// uc_emu_start(uc, function_ptr, function_ptr + some_size, 0, 0);
|
||||||
|
// 或
|
||||||
|
// context->EmulateApi(uc, function_ptr, some_return_address, "CustomInitializer");
|
||||||
|
}
|
||||||
|
// 移动到下一个表项
|
||||||
|
current += ptr_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 设置返回值
|
||||||
|
uc_reg_write(uc,
|
||||||
|
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||||
|
&return_value);
|
||||||
|
}
|
||||||
auto Api__initterm_e(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
auto Api__initterm_e(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||||||
auto context = static_cast<Sandbox*>(sandbox);
|
auto context = static_cast<Sandbox*>(sandbox);
|
||||||
uint64_t table_start = 0;
|
uint64_t table_start = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user