vmp完整源码分析-010-指令处理实现

# VMProtect 指令处理实现详解

20260402111256268-image

 

## 1. Intel 指令类实现

### IntelCommand 类结构

“`cpp
class IntelCommand : public BaseCommand {
public:
// 构造函数
IntelCommand(IFunction *owner, OperandSize size, uint64_t address);
IntelCommand(IFunction *owner, OperandSize size, IntelCommandType type,
IntelOperand operand1, IntelOperand operand2, IntelOperand operand3);
IntelCommand(IFunction *owner, OperandSize size, const std::string &value);
IntelCommand(IFunction *owner, const IntelCommand &src);

~IntelCommand();

// 初始化
void Init(IntelCommandType type, IntelOperand operand1,
IntelOperand operand2, IntelOperand operand3);
void Init(const Data &data);
void InitUnknown();

// 克隆
IntelCommand *Clone(IFunction *owner) const;

// 属性
uint64_t address() const { return address_; }
void set_address(uint64_t address) { address_ = address; }

OperandSize size() const { return size_; }
IntelCommandType type() const { return type_; }
void set_type(IntelCommandType type) { type_ = type; }

uint8_t flags() const { return flags_; }
void set_flags(uint8_t flags) { flags_ = flags; }

CommandOption options() const;
void include_option(CommandOption option);
void exclude_option(CommandOption option);

// 操作数
IntelOperand *operand(size_t index) { return &operand_[index]; }
const IntelOperand *operand(size_t index) const { return &operand_[index]; }

// 反汇编文本
std::string text() const;

// 判断指令类型
bool is_data() const;
bool is_end() const;
bool is_jmp() const;
bool is_call() const;
bool is_conditional_jmp() const;

private:
uint64_t address_; // 指令地址
OperandSize size_; // 操作数大小
IntelCommandType type_; // 指令类型
uint8_t flags_; // 标志位
IntelCommandType preffix_command_; // 前缀指令
SegmentRegistr base_segment_; // 段寄存器
IntelOperand operand_[3]; // 操作数(最多3个)
size_t command_pos_; // 在函数中的位置
size_t original_dump_size_; // 原始代码大小
uint32_t section_options_; // 节选项
uint8_t vex_operand_; // VEX 前缀操作数

// VM 相关
IVMEntry *ext_vm_entry_; // 外部 VM 入口
ICryptor *begin_section_cryptor_; // 节开始加密器
ICryptor *end_section_cryptor_; // 节结束加密器
ICommand *seh_handler_; // SEH 处理程序

IntelCommandInfoList *vm_command_info_list_; // VM 指令信息列表
};
“`

### 指令类型判断

“`cpp
bool IntelCommand::is_data() const {
return (type_ == cmDB || type_ == cmDW || type_ == cmDD ||
type_ == cmDQ || type_ == cmSleb || type_ == cmUleb ||
type_ == cmDC);
}

bool IntelCommand::is_end() const {
return (type_ == cmRet || type_ == cmIret || type_ == cmJmp ||
((type_ == cmCall || type_ == cmJmpWithFlag) &&
(options() & roUseAsJmp)) || is_data());
}

bool IntelCommand::is_jmp() const {
return (type_ == cmJmp || type_ == cmJmpWithFlag);
}

bool IntelCommand::is_call() const {
return (type_ == cmCall);
}

bool IntelCommand::is_conditional_jmp() const {
return (type_ == cmJmpWithFlag && flags_ != 0);
}
“`

## 2. 操作数处理

### IntelOperand 结构

“`cpp
struct IntelOperand {
OperandType type; // 操作数类型
OperandSize size; // 操作数大小
OperandSize address_size; // 地址大小
OperandSize value_size; // 立即数大小

// 寄存器相关
uint8_t registr; // 寄存器编号
uint8_t base_registr; // 基址寄存器
uint8_t scale_registr; // 比例寄存器
uint8_t scale; // 比例因子

// 立即数/地址
int64_t value; // 立即数值

// 标志
bool show_size; // 是否显示大小

void Clear() {
type = otNone;
size = osDefault;
address_size = osDefault;
value_size = osDefault;
registr = 0;
base_registr = 0;
scale_registr = 0;
scale = 0;
value = 0;
show_size = false;
}
};
“`

### 操作数文本生成

“`cpp
// 寄存器名称表
static const char *registr_name[4][22] = {
// 8位寄存器
{“al”,”cl”,”dl”,”bl”,”spl”,”bpl”,”sil”,”dil”,
“r8b”,”r9b”,”r10b”,”r11b”,”r12b”,”r13b”,”r14b”,”r15b”,
“fl”,”tl”,”rl”,”il”,”kl”,”el”},
// 16位寄存器
{“ax”,”cx”,”dx”,”bx”,”sp”,”bp”,”si”,”di”,
“r8w”,”r9w”,”r10w”,”r11w”,”r12w”,”r13w”,”r14w”,”r15w”,
“fx”,”tx”,”rx”,”ix”,”kx”,”ex”},
// 32位寄存器
{“eax”,”ecx”,”edx”,”ebx”,”esp”,”ebp”,”esi”,”edi”,
“r8d”,”r9d”,”r10d”,”r11d”,”r12d”,”r13d”,”r14d”,”r15d”,
“efx”,”etx”,”erx”,”eix”,”ekx”,”eex”},
// 64位寄存器
{“rax”,”rcx”,”rdx”,”rbx”,”rsp”,”rbp”,”rsi”,”rdi”,
“r8″,”r9″,”r10″,”r11″,”r12″,”r13″,”r14″,”r15”,
“rfx”,”rtx”,”rrx”,”rix”,”rkx”,”rex”}
};

bool IntelCommand::GetOperandText(std::string &str, size_t index) const {
const IntelOperand *operand = &operand_[index];

if (operand->type == otNone)
return false;

str.clear();

// 内存操作数
if (operand->type & otMemory) {
if (operand->show_size)
str.append(size_name[operand->size]).append(” ptr “);

if (base_segment_ != segDefault && type_ != cmLea)
str.append(segment_name[base_segment_]).append(“:”);

str.append(“[“);

if (operand->type & otBaseRegistr)
str.append(registr_name[operand->address_size][operand->base_registr]);
}

// 寄存器
if (operand->type & otRegistr) {
if (operand->type & otMemory) {
if (operand->type & otBaseRegistr)
str.append(“+”);
str.append(registr_name[operand->address_size][operand->registr]);
if (operand->scale_registr)
str.append(string_format(“*%d”, 2 << (operand->scale_registr – 1)));
} else {
str.append(operand->size > osQWord ? “???” :
registr_name[operand->size][operand->registr]);
}
}
// FPU 寄存器
else if (operand->type & otFPURegistr) {
str.append(string_format(“st%d”, operand->registr));
}
// 段寄存器
else if (operand->type & otSegmentRegistr) {
str.append(operand->registr > segGS ? “???” :
segment_name[operand->registr]);
}
// 控制寄存器
else if (operand->type & otControlRegistr) {
str.append(string_format(“cr%d”, operand->registr));
}
// 调试寄存器
else if (operand->type & otDebugRegistr) {
str.append(string_format(“dr%d”, operand->registr));
}
// MMX 寄存器
else if (operand->type & otMMXRegistr) {
str.append(string_format(“mm%d”, operand->registr));
}
// XMM/YMM 寄存器
else if (operand->type & otXMMRegistr) {
str.append(string_format((operand->size == osYMMWord) ?
“ymm%d” : “xmm%d”, operand->registr));
}

// 立即数
if (operand->type & otValue) {
int64_t value = operand->value;
bool is_neg = (value < 0 && (operand->size > operand->value_size ||
(operand->type & (otMemory | otRegistr | otBaseRegistr)) > otMemory));
if (is_neg) {
str.append(“-“);
value = -value;
} else if (operand->type & (otRegistr | otBaseRegistr)) {
str.append(“+”);
}

// 格式化输出
switch (operand->value_size) {
case osByte:
str.append(string_format(“%.2X”, static_cast<uint8_t>(value)));
break;
case osWord:
str.append(string_format(“%.4X”, static_cast<uint16_t>(value)));
break;
case osDWord:
str.append(string_format(“%.8X”, static_cast<uint32_t>(value)));
break;
case osQWord:
str.append(string_format(“%.16llX”, value));
break;
}
}

if (operand->type & otMemory)
str.append(“]”);

return true;
}
“`

## 3. 指令反汇编文本生成

“`cpp
std::string IntelCommand::text() const {
std::string res, operand_text;
size_t i;

// 数据定义
if (type_ == cmDB) {
res.append(intel_command_name[type_]);
for (i = 0; i < dump_size(); i++) {
if (i > 0) res.append(“,”);
res.append(string_format(” %.2X”, dump(i)));
}
return res;
}

// Lock 前缀
if (options() & roLockPrefix)
res.append(“lock “);

// 重复前缀
if (preffix_command_ != cmUnknown)
res.append(intel_command_name[preffix_command_]).append(” “);

// VEX 前缀
if (options() & roVexPrefix)
res.append(“v”);

// 条件跳转特殊处理
if (type_ == cmJCXZ && operand_[1].size > osWord) {
res.append(operand_[1].size == osDWord ? “jecxz” : “jrcxz”);
} else {
res.append(intel_command_name[type_]);
}

// 条件标志
if (flags_) {
if (options() & roInverseFlag)
res.append(“n”);
switch (flags_) {
case fl_O: res.append(“o”); break;
case fl_C: res.append(“b”); break;
case fl_Z: res.append(“z”); break;
case fl_C | fl_Z: res.append(“be”); break;
case fl_P: res.append(“p”); break;
case fl_S | fl_O: res.append(“l”); break;
case fl_S: res.append(“s”); break;
case fl_Z | fl_S | fl_O: res.append(“le”); break;
default: res.append(“?”); break;
}
}

// 字符串操作指令后缀
switch (type_) {
case cmLods:
case cmScas:
case cmCmps:
case cmMovs:
case cmStos:
case cmIns:
case cmOuts:
res.append(std::string(size_name[operand_[0].size], 1));
break;
case cmPusha:
case cmPopa:
case cmPushf:
case cmPopf:
case cmIret:
if (operand_[0].size > osWord)
res.append(std::string(size_name[operand_[0].size], 1));
break;
case cmXlat:
res.append(std::string(size_name[osByte], 1));
break;
case cmRet:
if ((options() & roFar) != 0)
res.append(“f”);
break;
}

// 操作数
for (i = 0; i < _countof(operand_); i++) {
// VEX 操作数
if (vex_operand_ && (vex_operand_ & 0x3) == i) {
res.append(“, “);
res.append(string_format((vex_operand_ & 4) ? “ymm%d” : “xmm%d”,
(vex_operand_ >> 4) & 0x0f));
}

if (!GetOperandText(operand_text, i))
break;

if (i > 0) res.append(“,”);
res.append(” “).append(operand_text);
}

return res;
}
“`

## 4. 函数信息处理

### AddressRange 类

“`cpp
class AddressRange : public IObject {
public:
AddressRange(FunctionInfo *owner, uint64_t begin, uint64_t end,
ICommand *begin_entry, ICommand *end_entry, ICommand *size_entry);
AddressRange(FunctionInfo *owner, const AddressRange &src);
~AddressRange();

AddressRange *Clone(FunctionInfo *owner) const;

// 属性
uint64_t begin() const { return begin_; }
uint64_t end() const { return end_; }
uint64_t original_begin() const { return original_begin_; }
uint64_t original_end() const { return original_end_; }

// 修改范围
void Add(uint64_t address, size_t size);
void Prepare();
void Rebase(uint64_t delta_base);

private:
FunctionInfo *owner_;
uint64_t begin_; // 开始地址
uint64_t end_; // 结束地址
uint64_t original_begin_; // 原始开始地址
uint64_t original_end_; // 原始结束地址
ICommand *begin_entry_; // 开始入口
ICommand *end_entry_; // 结束入口
ICommand *size_entry_; // 大小入口
LinkInfo *link_info_; // 链接信息
std::vector<AddressRange*> link_list_; // 链接列表
};
“`

### 范围添加

“`cpp
void AddressRange::Add(uint64_t address, size_t size) {
// 更新开始地址
if (!begin_ || begin_ > address)
begin_ = address;

// 更新结束地址
if (!end_ || end_ < address + size)
end_ = address + size;

// 传播到链接的范围
for (size_t i = 0; i < link_list_.size(); i++) {
link_list_[i]->Add(address, size);
}
}
“`

### FunctionInfo 类

“`cpp
class FunctionInfo : public ObjectList<AddressRange> {
public:
FunctionInfo();
FunctionInfo(FunctionInfoList *owner, uint64_t begin, uint64_t end,
AddressBaseType base_type, uint64_t base_value,
size_t prolog_size, uint8_t frame_registr,
IRuntimeFunction *source, ICommand *entry);
FunctionInfo(FunctionInfoList *owner, const FunctionInfo &src);
~FunctionInfo();

FunctionInfo *Clone(FunctionInfoList *owner) const;

// 属性
uint64_t begin() const { return begin_; }
uint64_t end() const { return end_; }
ICommand *entry() const { return entry_; }

// 地址范围操作
AddressRange *Add(uint64_t begin, uint64_t end,
ICommand *begin_entry, ICommand *end_entry,
ICommand *size_entry);
AddressRange *GetRangeByAddress(uint64_t address) const;

// 编译
void Prepare();
void Compile();
void WriteToFile(IArchitecture &file);
void Rebase(uint64_t delta_base);

private:
FunctionInfoList *owner_;
uint64_t begin_; // 函数开始地址
uint64_t end_; // 函数结束地址
AddressBaseType base_type_; // 基址类型
uint64_t base_value_; // 基址值
size_t prolog_size_; // 序言大小
ICommand *entry_; // 入口指令
uint8_t frame_registr_; // 帧寄存器
IRuntimeFunction *source_; // 源运行时函数
ICommand *data_entry_; // 数据入口
std::vector<ICommand*> unwind_opcodes_; // 展开操作码
};
“`

### 函数编译

“`cpp
void FunctionInfo::Compile() {
begin_ = 0;
end_ = 0;

// 计算函数的实际范围
for (size_t i = 0; i < count(); i++) {
AddressRange *range = item(i);
if (!range->begin()) continue;

if (!begin_ || begin_ > range->begin())
begin_ = range->begin();
if (!end_ || end_ < range->end())
end_ = range->end();
}
}
“`

## 5. 虚拟指令转换

### VM 指令信息

“`cpp
struct VMCommandInfo {
VMCommandType type; // VM 指令类型
uint64_t operand[3]; // 操作数
OperandSize size; // 操作数大小
uint32_t flags; // 标志
};

class IntelCommandInfoList : public ObjectList<VMCommandInfo> {
public:
IntelCommandInfoList(OperandSize size) : size_(size) {}

void Add(VMCommandType type, uint64_t op1 = 0, uint64_t op2 = 0,
uint64_t op3 = 0, uint32_t flags = 0);

private:
OperandSize size_;
};
“`

### 指令转换流程

“`cpp
bool IntelFunction::Compile() {
// 1. 分析控制流
if (!AnalyzeControlFlow()) return false;

// 2. 对每个基本块
for (auto &block : blocks_) {
// 2.1 清除之前的 VM 信息
for (size_t i = 0; i < block->count(); i++) {
block->item(i)->vm_command_info_list()->clear();
}

// 2.2 转换每条指令
for (size_t i = 0; i < block->count(); i++) {
IntelCommand *cmd = block->item(i);

switch (cmd->type()) {
case cmMov:
CompileMov(cmd);
break;
case cmAdd:
CompileAdd(cmd);
break;
case cmSub:
CompileSub(cmd);
break;
case cmJmp:
CompileJmp(cmd);
break;
case cmCall:
CompileCall(cmd);
break;
case cmRet:
CompileRet(cmd);
break;
// … 其他指令
default:
CompileGeneric(cmd);
break;
}
}
}

// 3. 生成 VM 字节码
return GenerateVMBytecode();
}
“`

### 具体指令编译示例

“`cpp
void IntelFunction::CompileMov(IntelCommand *cmd) {
IntelOperand *dst = cmd->operand(0);
IntelOperand *src = cmd->operand(1);

VMCommandInfoList *vm_info = cmd->vm_command_info_list();

if (dst->type & otRegistr && src->type & otRegistr) {
// 寄存器到寄存器: mov reg, reg
vm_info->Add(vmcMovRegReg, dst->registr, src->registr, 0, cmd->flags());
}
else if (dst->type & otRegistr && src->type & otMemory) {
// 内存到寄存器: mov reg, [mem]
if (src->type & otValue) {
// 直接地址
vm_info->Add(vmcMovRegMem, dst->registr, src->value, 0, cmd->flags());
} else {
// 间接地址
vm_info->Add(vmcMovRegMemReg, dst->registr, src->base_registr,
src->scale_registr, cmd->flags());
}
}
else if (dst->type & otMemory && src->type & otRegistr) {
// 寄存器到内存: mov [mem], reg
vm_info->Add(vmcMovMemReg, dst->base_registr, src->registr, 0, cmd->flags());
}
else if (dst->type & otRegistr && src->type & otValue) {
// 立即数到寄存器: mov reg, imm
vm_info->Add(vmcMovRegImm, dst->registr, src->value, 0, cmd->flags());
}
}

void IntelFunction::CompileJmp(IntelCommand *cmd) {
VMCommandInfoList *vm_info = cmd->vm_command_info_list();

if (cmd->type() == cmJmpWithFlag) {
// 条件跳转
vm_info->Add(vmcJcc, cmd->operand(0)->value, 0, 0, cmd->flags());
} else {
// 无条件跳转
vm_info->Add(vmcJmp, cmd->operand(0)->value, 0, 0, cmd->flags());
}
}
“`

## 6. 控制流分析

### 基本块检测

“`cpp
bool IntelFunction::AnalyzeControlFlow() {
blocks_.clear();

// 1. 标记所有跳转目标
std::set<uint64_t> targets;
targets.insert(entry_point_); // 入口点是跳转目标

for (size_t i = 0; i < count(); i++) {
IntelCommand *cmd = item(i);

if (cmd->is_jmp() || cmd->is_call()) {
// 直接跳转
if (cmd->operand(0)->type & otValue) {
targets.insert(cmd->operand(0)->value);
}
// 间接跳转(无法确定目标)
}

// 跳转指令后面的指令也是跳转目标
if (cmd->is_jmp() && i + 1 < count()) {
targets.insert(item(i + 1)->address());
}
}

// 2. 分割基本块
CommandBlock *current_block = nullptr;
for (size_t i = 0; i < count(); i++) {
IntelCommand *cmd = item(i);

// 如果是跳转目标,开始新块
if (targets.find(cmd->address()) != targets.end()) {
if (current_block) {
blocks_.push_back(current_block);
}
current_block = new CommandBlock();
}

if (!current_block) {
current_block = new CommandBlock();
}

current_block->Add(cmd);

// 如果是指令结束符,开始新块
if (cmd->is_end()) {
blocks_.push_back(current_block);
current_block = nullptr;
}
}

if (current_block) {
blocks_.push_back(current_block);
}

// 3. 建立块间连接
LinkBlocks();

return true;
}
“`

### 块连接

“`cpp
void IntelFunction::LinkBlocks() {
for (size_t i = 0; i < blocks_.size(); i++) {
CommandBlock *block = blocks_[i];
IntelCommand *last_cmd = block->last();

if (!last_cmd) continue;

if (last_cmd->type() == cmJmp) {
// 无条件跳转
CommandBlock *target = FindBlockByAddress(
last_cmd->operand(0)->value);
if (target) {
block->AddLink(target, ltJmp);
}
}
else if (last_cmd->type() == cmJmpWithFlag) {
// 条件跳转
CommandBlock *target = FindBlockByAddress(
last_cmd->operand(0)->value);
if (target) {
block->AddLink(target, ltJmpWithFlag);
}
// fall-through
if (i + 1 < blocks_.size()) {
block->AddLink(blocks_[i + 1], ltJmpWithFlagNSFS);
}
}
else if (last_cmd->type() == cmCall) {
// 调用
CommandBlock *target = FindBlockByAddress(
last_cmd->operand(0)->value);
if (target) {
block->AddLink(target, ltCall);
}
// 继续执行
if (i + 1 < blocks_.size()) {
block->AddLink(blocks_[i + 1], ltNone);
}
}
else if (!last_cmd->is_end()) {
// 顺序执行
if (i + 1 < blocks_.size()) {
block->AddLink(blocks_[i + 1], ltNone);
}
}
}
}
“`

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容