fix up
This commit is contained in:
@@ -2047,6 +2047,132 @@ auto Api_SetUnhandledExceptionFilter(void* sandbox, uc_engine* uc,
|
||||
&prev_filter);
|
||||
}
|
||||
|
||||
// 将Windows VirtualProtect保护标志转换为Unicorn内存保护标志
|
||||
uint32_t WindowsToUnicornProtect(uint32_t windowsProtect) {
|
||||
uint32_t unicornProtect = UC_PROT_NONE;
|
||||
|
||||
// 转换基本属性
|
||||
if (windowsProtect & (PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ |
|
||||
PAGE_EXECUTE_READWRITE)) {
|
||||
unicornProtect |= UC_PROT_READ;
|
||||
}
|
||||
|
||||
if (windowsProtect & (PAGE_READWRITE | PAGE_WRITECOPY |
|
||||
PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) {
|
||||
unicornProtect |= UC_PROT_WRITE;
|
||||
}
|
||||
|
||||
if (windowsProtect & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
|
||||
PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) {
|
||||
unicornProtect |= UC_PROT_EXEC;
|
||||
}
|
||||
|
||||
// 如果没有有效标志,至少给予读权限以防崩溃
|
||||
if (unicornProtect == UC_PROT_NONE && windowsProtect != PAGE_NOACCESS) {
|
||||
unicornProtect = UC_PROT_READ;
|
||||
}
|
||||
|
||||
return unicornProtect;
|
||||
}
|
||||
|
||||
auto Api_VirtualProtect(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
uint64_t lpAddress = 0;
|
||||
uint64_t dwSize = 0;
|
||||
uint32_t flNewProtect = 0;
|
||||
uint64_t lpflOldProtect = 0;
|
||||
|
||||
// 获取参数
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
// x64: rcx = lpAddress, rdx = dwSize, r8 = flNewProtect, r9 =
|
||||
// lpflOldProtect
|
||||
uc_reg_read(uc, UC_X86_REG_RCX, &lpAddress);
|
||||
uc_reg_read(uc, UC_X86_REG_RDX, &dwSize);
|
||||
uint64_t temp_protect;
|
||||
uc_reg_read(uc, UC_X86_REG_R8, &temp_protect);
|
||||
flNewProtect = static_cast<uint32_t>(temp_protect);
|
||||
uc_reg_read(uc, UC_X86_REG_R9, &lpflOldProtect);
|
||||
} else {
|
||||
// x86: 从栈上读取参数
|
||||
uint32_t esp_address = 0;
|
||||
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
|
||||
esp_address += 0x4; // 跳过返回地址
|
||||
|
||||
uint32_t temp_address;
|
||||
uc_mem_read(uc, esp_address, &temp_address, sizeof(uint32_t));
|
||||
lpAddress = temp_address;
|
||||
esp_address += 0x4;
|
||||
|
||||
uint32_t temp_size;
|
||||
uc_mem_read(uc, esp_address, &temp_size, sizeof(uint32_t));
|
||||
dwSize = temp_size;
|
||||
esp_address += 0x4;
|
||||
|
||||
uc_mem_read(uc, esp_address, &flNewProtect, sizeof(uint32_t));
|
||||
esp_address += 0x4;
|
||||
|
||||
uint32_t temp_old_protect;
|
||||
uc_mem_read(uc, esp_address, &temp_old_protect, sizeof(uint32_t));
|
||||
lpflOldProtect = temp_old_protect;
|
||||
}
|
||||
|
||||
// 检查参数有效性
|
||||
if (lpAddress == 0 || dwSize == 0 || lpflOldProtect == 0) {
|
||||
uint64_t result = 0; // FALSE
|
||||
uc_reg_write(
|
||||
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&result);
|
||||
|
||||
// 设置错误码 - ERROR_INVALID_PARAMETER
|
||||
DWORD error = ERROR_INVALID_PARAMETER;
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
context->GetTeb64()->LastErrorValue = error;
|
||||
} else {
|
||||
context->GetTeb32()->LastErrorValue = error;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查地址范围是否已映射
|
||||
uint32_t unicornProtect = WindowsToUnicornProtect(flNewProtect);
|
||||
uc_err err = uc_mem_protect(uc, lpAddress, dwSize, unicornProtect);
|
||||
if (err != UC_ERR_OK) {
|
||||
uint64_t result = 0; // FALSE
|
||||
uc_reg_write(
|
||||
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&result);
|
||||
|
||||
// 设置错误码 - ERROR_INVALID_ADDRESS
|
||||
DWORD error = ERROR_INVALID_ADDRESS;
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
context->GetTeb64()->LastErrorValue = error;
|
||||
} else {
|
||||
context->GetTeb32()->LastErrorValue = error;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 模拟的旧保护属性,这里简化为一个默认值
|
||||
// 实际应用中,应该从内存映射表中获取
|
||||
uint32_t oldProtect = PAGE_READWRITE;
|
||||
|
||||
// 写入旧保护值到lpflOldProtect指向的内存
|
||||
uc_mem_write(uc, lpflOldProtect, &oldProtect, sizeof(uint32_t));
|
||||
|
||||
// 调试输出
|
||||
printf(
|
||||
"[*] VirtualProtect: Address=0x%llx, Size=0x%llx, WindowsProtect=0x%x, "
|
||||
"UnicornProtect=0x%x, OldProtect=0x%x\n",
|
||||
lpAddress, dwSize, flNewProtect, unicornProtect, oldProtect);
|
||||
|
||||
// 设置返回值为TRUE
|
||||
uint64_t result = 1; // TRUE
|
||||
uc_reg_write(uc,
|
||||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&result);
|
||||
}
|
||||
|
||||
auto Sandbox::InitApiHooks() -> void {
|
||||
auto FakeApi_GetSystemTimeAsFileTime =
|
||||
_fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1};
|
||||
@@ -2113,6 +2239,8 @@ auto Sandbox::InitApiHooks() -> void {
|
||||
_fakeApi{.func = Api_FreeEnvironmentStringsW, .paramCount = 1};
|
||||
auto FakeApi_SetUnhandledExceptionFilter =
|
||||
_fakeApi{.func = Api_SetUnhandledExceptionFilter, .paramCount = 1};
|
||||
auto FakeApi_VirtualProtect =
|
||||
_fakeApi{.func = Api_VirtualProtect, .paramCount = 4};
|
||||
|
||||
api_map = {
|
||||
{"GetSystemTimeAsFileTime",
|
||||
@@ -2171,6 +2299,7 @@ auto Sandbox::InitApiHooks() -> void {
|
||||
std::make_shared<_fakeApi>(FakeApi_FreeEnvironmentStringsW)},
|
||||
{"SetUnhandledExceptionFilter",
|
||||
std::make_shared<_fakeApi>(FakeApi_SetUnhandledExceptionFilter)},
|
||||
{"VirtualProtect", std::make_shared<_fakeApi>(FakeApi_VirtualProtect)},
|
||||
};
|
||||
}
|
||||
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
|
||||
|
||||
Reference in New Issue
Block a user