This commit is contained in:
Huoji's
2025-03-09 03:19:40 +08:00
parent 1cea516cf7
commit defe59ffe8
7 changed files with 337 additions and 59 deletions

View File

@@ -2173,6 +2173,83 @@ auto Api_VirtualProtect(void* sandbox, uc_engine* uc, uint64_t address)
&result);
}
auto Api___set_app_type(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
int32_t appType = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = appType
uint64_t temp_type;
uc_reg_read(uc, UC_X86_REG_RCX, &temp_type);
appType = static_cast<int32_t>(temp_type);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &appType, sizeof(int32_t));
}
// 简单地返回0表示成功
int32_t result = 0;
printf("[*] __set_app_type: AppType=%d\n", appType);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
}
auto Api___p__fmode(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto sb = static_cast<Sandbox*>(sandbox);
// 检查是否已经创建了 _fmode 变量
static uint64_t fmode_address = 0;
static int32_t fmode_value = 0; // 默认为文本模式 (_O_TEXT)
if (fmode_address == 0) {
// 为 _fmode 变量分配内存
// 使用特定堆地址,与其他 API 一致
uint64_t heap_handle =
sb->GetPeInfo()->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32;
// 在堆上分配空间
HeapSegment* segment = nullptr;
auto it = sb->m_heapSegments.find(heap_handle);
if (it != sb->m_heapSegments.end()) {
segment = it->second;
} else {
// 创建新的堆段
segment = sb->CreateHeapSegment(heap_handle, 0x10000);
sb->m_heapSegments[heap_handle] = segment;
}
if (segment) {
fmode_address = sb->AllocateFromSegment(segment, sizeof(int32_t));
if (fmode_address) {
// 初始化 _fmode 为文本模式
uc_mem_write(uc, fmode_address, &fmode_value, sizeof(int32_t));
printf(
"[*] __p__fmode: Allocated _fmode at 0x%llx with value "
"%d\n",
fmode_address, fmode_value);
}
}
}
// 返回 _fmode 变量的地址
printf("[*] __p__fmode: Returning address 0x%llx\n", fmode_address);
// 设置返回值
if (sb->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RAX, &fmode_address);
} else {
uint32_t eax = static_cast<uint32_t>(fmode_address);
uc_reg_write(uc, UC_X86_REG_EAX, &eax);
}
}
auto Sandbox::InitApiHooks() -> void {
auto FakeApi_GetSystemTimeAsFileTime =
_fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1};
@@ -2241,6 +2318,9 @@ auto Sandbox::InitApiHooks() -> void {
_fakeApi{.func = Api_SetUnhandledExceptionFilter, .paramCount = 1};
auto FakeApi_VirtualProtect =
_fakeApi{.func = Api_VirtualProtect, .paramCount = 4};
auto FakeApi___set_app_type =
_fakeApi{.func = Api___set_app_type, .paramCount = 1};
auto FakeApi___p__fmode = _fakeApi{.func = Api___p__fmode, .paramCount = 0};
api_map = {
{"GetSystemTimeAsFileTime",
@@ -2300,6 +2380,8 @@ auto Sandbox::InitApiHooks() -> void {
{"SetUnhandledExceptionFilter",
std::make_shared<_fakeApi>(FakeApi_SetUnhandledExceptionFilter)},
{"VirtualProtect", std::make_shared<_fakeApi>(FakeApi_VirtualProtect)},
{"__set_app_type", std::make_shared<_fakeApi>(FakeApi___set_app_type)},
{"__p__fmode", std::make_shared<_fakeApi>(FakeApi___p__fmode)},
};
}
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
@@ -2310,16 +2392,13 @@ auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
// 获取参数数量
int paramCount = it->second->paramCount;
// 获取当前的栈指针
uint32_t esp;
uint64_t rsp;
uc_reg_read(uc,
this->GetPeInfo()->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP,
&rsp);
// 从栈上读取返回地址
uint64_t return_address;
if (this->GetPeInfo()->isX64) { // 64位系统
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
// 读取8字节的返回地址
uc_mem_read(uc, rsp, &return_address, 8);
@@ -2332,21 +2411,24 @@ auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
uc_reg_write(uc, UC_X86_REG_RIP, &return_address);
} else { // 32位系统
// 读取4字节的返回地址
uint32_t return_address_32;
uc_mem_read(uc, rsp, &return_address_32, 4);
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
uc_mem_read(uc, esp, &return_address, 4);
uint32_t return_address_32;
uc_mem_read(uc, esp, &return_address_32, 4);
printf("return_address_32: %x\n", return_address_32);
// x86下所有参数都通过栈传递
// 调整栈指针每个参数4字节 + 返回地址4字节
rsp += (paramCount * 4) + 4;
esp += (paramCount * 4) + 4;
// 设置EIP为返回地址
uc_reg_write(uc, UC_X86_REG_EIP, &return_address_32);
}
if (this->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RSP, &rsp);
} else {
uc_reg_write(uc, UC_X86_REG_ESP, &esp);
}
// 更新栈指针,使用正确的寄存器
uc_reg_write(uc,
this->GetPeInfo()->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP,
&rsp);
return;
}
printf("ApiName: %s not found\n", ApiName.c_str());