#include "VmpTrace2x.h"
#include "unicorn/unicorn.h"
#include <pro.h>
#include <ua.hpp>
#include <allins.hpp>
#include <segment.hpp>
#include "../Utils/Utils.h"
VmpTrace2x::~VmpTrace2x()
{
uc_hook_del(uc, hook_code);
uc_hook_del(uc, hook_mem);
if (uc) {
uc_close(uc);
uc = nullptr;
}
}
int reg_arg[10] = { UC_X86_REG_EAX, UC_X86_REG_ECX, UC_X86_REG_EDX, UC_X86_REG_EBX,UC_X86_REG_ESP,UC_X86_REG_EBP,
UC_X86_REG_ESI,UC_X86_REG_EDI,UC_X86_REG_EIP,UC_X86_REG_EFLAGS };
uc_err write_reg_context(uc_engine* uc, reg_context& regContext)
{
void* ptrs[10];
unsigned int* pRegAddr = ®Context.Eax;
for (int n = 0; n < 10; n++) {
ptrs[n] = pRegAddr++;
}
return uc_reg_write_batch(uc, reg_arg, ptrs, 10);
}
uc_err read_reg_context(uc_engine* uc, reg_context& outContext)
{
void* ptrs[10];
unsigned int* pRegAddr = &outContext.Eax;
for (int n = 0; n < 10; n++) {
ptrs[n] = pRegAddr++;
}
return uc_reg_read_batch(uc, reg_arg, ptrs, 10);
}
//在执行每条指令之前
void unicorn_hook_code(uc_engine* uc, uint64_t address, uint32_t size,
void* user_data)
{
VmpTrace2x* pVmpMonitor = (VmpTrace2x*)user_data;
insn_t tmpIns;
int insLen = decode_insn(&tmpIns, address);
if (insLen == -1) {
uc_emu_stop(uc);
return;
}
//检查退出条件
if (pVmpMonitor->checkQuitCondition(address)) {
uc_emu_stop(uc);
return;
}
auto err = read_reg_context(uc, pVmpMonitor->regContext);
pVmpMonitor->traceList.push_back(address);
msg("execute addr:%a\n", address);
qstring logStr;
logStr.sprnt("eip=%a,eax=%a,ecx=%a,edx=%a,ebx=%a,esp=%a,ebp=%a,esi=%a,edi=%a\n", pVmpMonitor->regContext.Eip,
pVmpMonitor->regContext.Eax, pVmpMonitor->regContext.Ecx, pVmpMonitor->regContext.Edx, pVmpMonitor->regContext.Ebx,
pVmpMonitor->regContext.Esp, pVmpMonitor->regContext.Ebp, pVmpMonitor->regContext.Esi, pVmpMonitor->regContext.Edi);
pVmpMonitor->logStream << logStr.c_str();
}
void unicorn_hook_mem(uc_engine* uc, uc_mem_type type,
uint64_t address, int size, int64_t value,
void* user_data)
{
VmpTrace2x* pVmpMonitor = (VmpTrace2x*)user_data;
if (type == UC_MEM_FETCH_UNMAPPED) {
if (pVmpMonitor->handleErr_MEM_FETCH_UNMAPPED() == false) {
pVmpMonitor->regContext.Eip = -1;
}
return;
}
if (type == UC_MEM_READ_UNMAPPED) {
if (pVmpMonitor->handleErr_MEM_READ_UNMAPPED() == false) {
pVmpMonitor->regContext.Eip = -1;
}
return;
}
if (type == UC_MEM_WRITE_UNMAPPED) {
if (pVmpMonitor->handleErr_MEM_WRITE_UNMAPPED() == false) {
pVmpMonitor->regContext.Eip = -1;
}
return;
}
}
VmpTrace2x::VmpTrace2x()
{
uc_err err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err != UC_ERR_OK) {
return;
}
uc_hook_add(uc, &hook_code, UC_HOOK_CODE, unicorn_hook_code, this, 0x0, 0xFFFFFFFF);
uc_hook_add(uc, &hook_mem, UC_HOOK_MEM_FETCH_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_READ_UNMAPPED, unicorn_hook_mem, this, 0x0, 0xFFFFFFFF);
}
bool VmpTrace2x::checkQuitCondition(unsigned int addr)
{
//当前地址属于用户代码段
if (iTextSeg != get_segm_num(addr)) {
return false;
}
//跟踪代码数量小于10
if (traceList.size() <= 10) {
return false;
}
insn_t tmpIns;
int insLen = decode_insn(&tmpIns, traceList[traceList.size() - 1]);
if (insLen == -1) {
return true;
}
//vmp的最后一条指令一定是ret?
if (tmpIns.itype == NN_retn) {
return true;
}
return false;
}
void unicorn_hook_intr(uc_engine* uc, uint32_t intno,
void* user_data)
{
//unsigned int currentEIP;
//uc_err err = uc_reg_read(uc, UC_X86_REG_EIP, ¤tEIP);
//msg("execute addr:%a\n", intno);
int a = 0;
}
bool VmpTrace2x::handleErr_MEM_FETCH_UNMAPPED()
{
//insn_t tmpIns;
//int iLen = decode_insn(&tmpIns, this->regContext.Eip);
//if (!iLen) {
// return false;
//}
////FF 15
//if (tmpIns.itype == NN_callni) {
// auto callAddr = tmpIns.ops[0].addr;
// qstring funcName = get_name(callAddr);
// //先不处理吧
// this->regContext.Eip = this->regContext.Eip + iLen;
// return true;
//}
return false;
}
bool VmpTrace2x::handleErr_MEM_READ_UNMAPPED()
{
insn_t tmpIns;
int iLen = decode_insn(&tmpIns, this->regContext.Eip);
if (!iLen) {
return false;
}
//mov指令略
if (tmpIns.itype == NN_mov) {
this->regContext.Eip = this->regContext.Eip + iLen;
return true;
}
return false;
}
bool VmpTrace2x::handleErr_MEM_WRITE_UNMAPPED()
{
insn_t tmpIns;
int iLen = decode_insn(&tmpIns, this->regContext.Eip);
if (!iLen) {
return false;
}
//mov指令略
if (tmpIns.itype == NN_mov) {
this->regContext.Eip = this->regContext.Eip + iLen;
return true;
}
return false;
}
bool VmpTrace2x::fillStack()
{
//模拟堆栈
uc_mem_unmap(uc, UC_DefaultStack, UC_DefaultStackSize);
auto err = uc_mem_map(uc, UC_DefaultStack, UC_DefaultStackSize, UC_PROT_ALL);
if (err != UC_ERR_OK) {
return false;
}
return true;
}
bool VmpTrace2x::fillMemoryMap()
{
////获取程序大小
unsigned int programSize = alignMemory(get_last_seg()->end_ea - get_first_seg()->start_ea, 0x1000);
uc_err err = uc_mem_map(uc, get_first_seg()->start_ea, programSize, UC_PROT_ALL);
if (err != UC_ERR_OK) {
return false;
}
for (unsigned int n = 0; n < get_segm_qty(); n++) {
segment_t* pSegment = getnseg(n);
if (!pSegment) {
break;
}
std::vector<unsigned char> tmpSegData;
tmpSegData.resize(pSegment->size(), 0x0);
get_bytes(&tmpSegData[0], pSegment->size(), pSegment->start_ea, GMB_READALL);
err = uc_mem_write(uc, pSegment->start_ea, tmpSegData.data(), tmpSegData.size());
if (err != UC_ERR_OK) {
return false;
}
}
return true;
}
std::vector<ea_t> VmpTrace2x::StartTrace(size_t startAddr)
{
if (!fillMemoryMap()) {
return traceList;
}
if (!fillStack()) {
return traceList;
}
logStream.open("C:\\Work\\vm.txt");
iTextSeg = get_segm_num(startAddr);
//设置好esp
unsigned int currentEsp = UC_DefaultStack + UC_DefaultStackSize - 0x1000;
uc_reg_write(uc, UC_X86_REG_ESP, ¤tEsp);
uc_hook hooker2;
uc_hook_add(uc, &hooker2, UC_HOOK_INTR, unicorn_hook_intr, 0x0, 0x0, 0xFFFFFFFF);
this->regContext.Eip = startAddr;
while (true) {
uc_err err = uc_emu_start(uc, this->regContext.Eip, -1, 0, 0);
if (err == UC_ERR_OK) {
break;
}
//分析不下去了
if (this->regContext.Eip == -1) {
break;
}
err = write_reg_context(uc, this->regContext);
if (err != UC_ERR_OK) {
break;
}
reg_context context;
err = read_reg_context(uc, context);
}
logStream.flush();
logStream.close();
return traceList;
}
没有合适的资源?快使用搜索试试~ 我知道了~
新手学习Vmp之控制流程图生成
共6个文件
h:3个
cpp:3个
需积分: 5 2 下载量 65 浏览量
2023-06-17
16:39:33
上传
评论
收藏 5KB 7Z 举报
温馨提示
新手学习Vmp之控制流程图生成
资源推荐
资源详情
资源评论
收起资源包目录
TestVmp.7z (6个子文件)
TestVmp
VmpTraceFlowGraph.h 1KB
DisasmManager.h 349B
DisasmManager.cpp 930B
VmpTrace2x.h 908B
VmpTraceFlowGraph.cpp 6KB
VmpTrace2x.cpp 7KB
共 6 条
- 1
资源评论
夜栩
- 粉丝: 749
- 资源: 19
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功