|
本帖最后由 LingMo 于 2025-1-20 21:05 编辑
理论
判断是否为垃圾指令:(insn是指令)
def[insn] ∩ out[insn] = ∅ <==> insn 是垃圾指令
代码演示
使用x86汇编代码做例子
代码使用了capstone反汇编库,自己设置下capstone的include目录和lib目录,然后导入lib就可以运行了
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <capstone/capstone.h>
#pragma comment(lib, "capstone.lib")
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
template <typename T>
std::vector<T> my_set_diff(std::vector<T> a, std::vector<T> b) {
if (a.empty()) {
return {};
}
if (b.empty()) {
return a;
}
std::vector<T> tem;
tem.resize(max(a.size(), b.size()));
std::sort(a.begin(), a.end());
std::sort(b.begin(), b.end());
auto temLast = set_difference(a.begin(), a.end(), b.begin(), b.end(), tem.begin());
std::vector<T> ret;
for (auto it = tem.begin(); it != temLast; it++) {
ret.push_back(*it);
}
return ret;
}
template <typename T>
std::vector<T> my_set_union(std::vector<T> a, std::vector<T> b) {
if (a.empty()) {
return b;
}
if (b.empty()) {
return a;
}
std::vector<T> tem;
tem.resize(a.size() + b.size());
std::sort(a.begin(), a.end());
std::sort(b.begin(), b.end());
auto temLast = set_union(a.begin(), a.end(), b.begin(), b.end(), tem.begin());
std::vector<T> ret;
for (auto it = tem.begin(); it != temLast; it++) {
ret.push_back(*it);
}
return ret;
}
template <typename T>
std::vector<T> my_set_intersection(std::vector<T> a, std::vector<T> b) {
if (a.empty()) {
return {};
}
if (b.empty()) {
return {};
}
std::vector<T> tem;
tem.resize(min(a.size(), b.size()));
std::sort(a.begin(), a.end());
std::sort(b.begin(), b.end());
auto temLast = set_intersection(a.begin(), a.end(), b.begin(), b.end(), tem.begin());
std::vector<T> ret;
for (auto it = tem.begin(); it != temLast; it++) {
ret.push_back(*it);
}
return ret;
}
cs_err disasm(csh hCs, const uint8_t* codePtr, uint64_t virAddr, uint64_t codeSize, cs_insn* insn, cs_detail* detail) {
cs_insn* _insn = 0;
size_t err = 0;
if ((err = cs_disasm(hCs, codePtr, codeSize, virAddr, 1, &_insn)) <= 0) {
return cs_errno(hCs);
}
memcpy(insn, _insn, sizeof(cs_insn));
if (detail != NULL) {
memcpy(detail, _insn->detail, sizeof(cs_detail));
}
insn->detail = detail;
cs_free(_insn, 1);
return cs_errno(hCs);
}
cs_err disasm_iter(csh hCs, uint8_t*& codePtr, uint64_t& virAddr, uint64_t& codeSize, cs_insn* insn, cs_detail* detail) {
cs_err status = CS_ERR_OK;
if ((status = disasm(hCs, codePtr, virAddr, codeSize, insn, detail)) != CS_ERR_OK) {
return status;
}
codePtr += insn->size;
virAddr += insn->size;
codeSize -= insn->size;
return status;
}
using regs = std::vector<uint16_t>;
struct accessRegs {
regs reads;
regs writes;
};
accessRegs get_regs_access(csh hCs, cs_insn* insn) {
cs_regs read_regs{};
uint8_t read_num = 0;
cs_regs write_regs{};
uint8_t write_num = 0;
cs_regs_access(hCs, insn, read_regs, &read_num, write_regs, &write_num);
regs reads = {};
regs writes = {};
for (uint8_t i = 0; i < read_num; i++) {
reads.push_back(read_regs[i]);
}
for (uint8_t i = 0; i < write_num; i++) {
writes.push_back(write_regs[i]);
}
return { reads, writes };
}
struct Insn {
uint8_t addr[16];
size_t size;
uint64_t viraddr;
std::string opstr;
};
enum class x86_flag : uint8_t { AF, CF, SF, ZF, PF, OF, TF, IF, DF, NT, RF };
enum class x86_fpuflag : uint8_t { C0, C1, C2, C3 };
std::vector<x86_flag> calc_eflags_use(csh hCs, const Insn& ins);
std::vector<x86_flag> calc_eflags_def(csh hCs, const Insn& ins);
std::vector<x86_fpuflag> calc_fpuflags_use(csh hCs, const Insn& ins);
std::vector<x86_fpuflag> calc_fpuflags_def(csh hCs, const Insn& ins);
void RemoveDeadCode(char* x86code, size_t codesize, bool is64, uint64_t virtualAddressBegin) {
csh hCs = 0;
if (!cs_support(CS_ARCH_X86)) {
std::cout << "当前Capstone不支持X86架构" << std::endl;
return;
}
if (cs_open(CS_ARCH_X86, ((is64) ? CS_MODE_64 : CS_MODE_32), &hCs) != CS_ERR_OK) {
std::cout << "打开Capstone句柄失败" << std::endl;
return;
}
if (cs_option(hCs, CS_OPT_DETAIL, CS_OPT_ON) != CS_ERR_OK) {
std::cout << "无法开启Detail" << std::endl;
return;
}
uint8_t* addr = (uint8_t*)x86code;
size_t size = codesize;
uint64_t virAddr = virtualAddressBegin;
std::vector<Insn> bb;
std::vector<std::vector<Insn>> bbs;
while (size > 0 && (virAddr < (virtualAddressBegin + codesize))) {
cs_insn cinsn{};
cs_detail cdetail{};
cs_err err = CS_ERR_OK;
if ((err = disasm_iter(hCs, addr, virAddr, size, &cinsn, &cdetail)) != CS_ERR_OK) {
std::cout << "反汇编发生错误: " << err << std::endl;
break;
}
bool end_sign1 = (cs_insn_group(hCs, &cinsn, X86_GRP_JUMP) ||
cs_insn_group(hCs, &cinsn, X86_GRP_BRANCH_RELATIVE) ||
cs_insn_group(hCs, &cinsn, X86_GRP_CALL) && cinsn.id != X86_INS_CALL);
bool end_sign2 = (cinsn.id == X86_INS_RET || cinsn.id == X86_INS_RETF ||
cinsn.id == X86_INS_RETFQ || cs_insn_group(hCs, &cinsn, X86_GRP_INT));
bool end_sign3 = cs_insn_group(hCs, &cinsn, X86_GRP_PRIVILEGE);
if (end_sign1 || end_sign2 || end_sign3) {
if (!bb.empty()) {
bbs.push_back(bb);
bb = {};
}
}
else {
std::string opstr = cinsn.mnemonic;
opstr += "\t";
opstr += cinsn.op_str;
Insn ins = {};
ins.opstr = opstr;
ins.size = cinsn.size;
ins.viraddr = cinsn.address;
memcpy(&ins.addr, cinsn.bytes, cinsn.size);
bb.push_back(ins);
}
}
if (!bb.empty()) {
bbs.push_back(bb);
bb = {};
}
std::cout << "\"---->\" 表示该指令可以被删除" << std::endl;
bool changed = false;
for (std::vector<Insn> mbb : bbs) {
std::cout << "@@@-------------------------------------------------------";
std::cout << std::endl;
std::vector<bool> delList;
delList.resize(mbb.size());
do {
changed = false;
if (mbb.empty()) {
continue;
}
std::vector<std::vector<uint16_t>> use;
std::vector<std::vector<uint16_t>> def;
std::vector<std::vector<x86_flag>> use_flags;
std::vector<std::vector<x86_flag>> def_flags;
std::vector<std::vector<x86_fpuflag>> use_fpuflags;
std::vector<std::vector<x86_fpuflag>> def_fpuflags;
for (size_t i = 0; i < mbb.size(); i++) {
cs_insn cinsn{};
cs_detail cdetail{};
disasm(hCs, mbb[i].addr, mbb[i].viraddr, mbb[i].size, &cinsn, &cdetail);
auto access = get_regs_access(hCs, &cinsn);
use.push_back(my_set_diff(access.reads, { X86_REG_EFLAGS }));
def.push_back(my_set_diff(access.writes, { X86_REG_EFLAGS }));
use_flags.push_back(calc_eflags_use(hCs, mbb[i]));
def_flags.push_back(calc_eflags_def(hCs, mbb[i]));
use_fpuflags.push_back(calc_fpuflags_use(hCs, mbb[i]));
def_fpuflags.push_back(calc_fpuflags_def(hCs, mbb[i]));
}
std::vector<std::vector<uint16_t>> in;
std::vector<std::vector<uint16_t>> out;
std::vector<std::vector<x86_flag>> in_flags;
std::vector<std::vector<x86_flag>> out_flags;
std::vector<std::vector<x86_fpuflag>> in_fpuflags;
std::vector<std::vector<x86_fpuflag>> out_fpuflags;
in.resize(mbb.size());
out.resize(mbb.size());
in_flags.resize(mbb.size());
out_flags.resize(mbb.size());
in_fpuflags.resize(mbb.size());
out_fpuflags.resize(mbb.size());
out.back() = { X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_BH, X86_REG_BL,
X86_REG_BP, X86_REG_BPL, X86_REG_BX, X86_REG_CH, X86_REG_CL,
X86_REG_CS, X86_REG_CX, X86_REG_DH, X86_REG_DI, X86_REG_DIL,
X86_REG_DL, X86_REG_DS, X86_REG_DX, X86_REG_EAX, X86_REG_EBP,
X86_REG_EBX, X86_REG_ECX, X86_REG_EDI, X86_REG_EDX,
X86_REG_EIP, X86_REG_EIZ, X86_REG_ES, X86_REG_ESI, X86_REG_ESP,
X86_REG_FPSW, X86_REG_FS, X86_REG_GS, X86_REG_IP, X86_REG_RAX,
X86_REG_RBP, X86_REG_RBX, X86_REG_RCX, X86_REG_RDI, X86_REG_RDX,
X86_REG_RIP, X86_REG_RIZ, X86_REG_RSI, X86_REG_RSP, X86_REG_SI,
X86_REG_SIL, X86_REG_SP, X86_REG_SPL, X86_REG_SS, X86_REG_CR0,
X86_REG_CR1, X86_REG_CR2, X86_REG_CR3, X86_REG_CR4, X86_REG_CR5,
X86_REG_CR6, X86_REG_CR7, X86_REG_CR8, X86_REG_CR9, X86_REG_CR10,
X86_REG_CR11, X86_REG_CR12, X86_REG_CR13, X86_REG_CR14, X86_REG_CR15,
X86_REG_DR0, X86_REG_DR1, X86_REG_DR2, X86_REG_DR3, X86_REG_DR4,
X86_REG_DR5, X86_REG_DR6, X86_REG_DR7, X86_REG_DR8, X86_REG_DR9,
X86_REG_DR10, X86_REG_DR11, X86_REG_DR12, X86_REG_DR13, X86_REG_DR14,
X86_REG_DR15, X86_REG_FP0, X86_REG_FP1, X86_REG_FP2, X86_REG_FP3,
X86_REG_FP4, X86_REG_FP5, X86_REG_FP6, X86_REG_FP7,
X86_REG_K0, X86_REG_K1, X86_REG_K2, X86_REG_K3, X86_REG_K4,
X86_REG_K5, X86_REG_K6, X86_REG_K7, X86_REG_MM0, X86_REG_MM1,
X86_REG_MM2, X86_REG_MM3, X86_REG_MM4, X86_REG_MM5, X86_REG_MM6,
X86_REG_MM7, X86_REG_R8, X86_REG_R9, X86_REG_R10, X86_REG_R11,
X86_REG_R12, X86_REG_R13, X86_REG_R14, X86_REG_R15,
X86_REG_ST0, X86_REG_ST1, X86_REG_ST2, X86_REG_ST3,
X86_REG_ST4, X86_REG_ST5, X86_REG_ST6, X86_REG_ST7,
X86_REG_XMM0, X86_REG_XMM1, X86_REG_XMM2, X86_REG_XMM3, X86_REG_XMM4,
X86_REG_XMM5, X86_REG_XMM6, X86_REG_XMM7, X86_REG_XMM8, X86_REG_XMM9,
X86_REG_XMM10, X86_REG_XMM11, X86_REG_XMM12, X86_REG_XMM13, X86_REG_XMM14,
X86_REG_XMM15, X86_REG_XMM16, X86_REG_XMM17, X86_REG_XMM18, X86_REG_XMM19,
X86_REG_XMM20, X86_REG_XMM21, X86_REG_XMM22, X86_REG_XMM23, X86_REG_XMM24,
X86_REG_XMM25, X86_REG_XMM26, X86_REG_XMM27, X86_REG_XMM28, X86_REG_XMM29,
X86_REG_XMM30, X86_REG_XMM31, X86_REG_YMM0, X86_REG_YMM1, X86_REG_YMM2,
X86_REG_YMM3, X86_REG_YMM4, X86_REG_YMM5, X86_REG_YMM6, X86_REG_YMM7,
X86_REG_YMM8, X86_REG_YMM9, X86_REG_YMM10, X86_REG_YMM11, X86_REG_YMM12,
X86_REG_YMM13, X86_REG_YMM14, X86_REG_YMM15, X86_REG_YMM16, X86_REG_YMM17,
X86_REG_YMM18, X86_REG_YMM19, X86_REG_YMM20, X86_REG_YMM21, X86_REG_YMM22,
X86_REG_YMM23, X86_REG_YMM24, X86_REG_YMM25, X86_REG_YMM26, X86_REG_YMM27,
X86_REG_YMM28, X86_REG_YMM29, X86_REG_YMM30, X86_REG_YMM31, X86_REG_ZMM0,
X86_REG_ZMM1, X86_REG_ZMM2, X86_REG_ZMM3, X86_REG_ZMM4, X86_REG_ZMM5,
X86_REG_ZMM6, X86_REG_ZMM7, X86_REG_ZMM8, X86_REG_ZMM9, X86_REG_ZMM10,
X86_REG_ZMM11, X86_REG_ZMM12, X86_REG_ZMM13, X86_REG_ZMM14, X86_REG_ZMM15,
X86_REG_ZMM16, X86_REG_ZMM17, X86_REG_ZMM18, X86_REG_ZMM19, X86_REG_ZMM20,
X86_REG_ZMM21, X86_REG_ZMM22, X86_REG_ZMM23, X86_REG_ZMM24, X86_REG_ZMM25,
X86_REG_ZMM26, X86_REG_ZMM27, X86_REG_ZMM28, X86_REG_ZMM29, X86_REG_ZMM30,
X86_REG_ZMM31, X86_REG_R8B, X86_REG_R9B, X86_REG_R10B, X86_REG_R11B,
X86_REG_R12B, X86_REG_R13B, X86_REG_R14B, X86_REG_R15B, X86_REG_R8D,
X86_REG_R9D, X86_REG_R10D, X86_REG_R11D, X86_REG_R12D, X86_REG_R13D,
X86_REG_R14D, X86_REG_R15D, X86_REG_R8W, X86_REG_R9W, X86_REG_R10W,
X86_REG_R11W, X86_REG_R12W, X86_REG_R13W, X86_REG_R14W, X86_REG_R15W,
X86_REG_BND0, X86_REG_BND1, X86_REG_BND2, X86_REG_BND3,
};
out_flags.back() = { x86_flag::AF, x86_flag::CF, x86_flag::SF, x86_flag::ZF,
x86_flag::PF, x86_flag::OF, x86_flag::TF, x86_flag::IF, x86_flag::DF,
x86_flag::NT, x86_flag::RF
};
out_fpuflags.back() = { x86_fpuflag::C0, x86_fpuflag::C1, x86_fpuflag::C2, x86_fpuflag::C3 };
for (size_t i = 0; i < mbb.size(); i++) {
size_t j = (mbb.size() - 1) - i;
std::vector<uint16_t> tem = my_set_diff(out[j], def[j]);
in[j] = my_set_union(use[j], tem);
std::vector<x86_flag> tem_flag = my_set_diff(out_flags[j], def_flags[j]);
in_flags[j] = my_set_union(use_flags[j], tem_flag);
std::vector<x86_fpuflag> tem_fpuflag = my_set_diff(out_fpuflags[j], def_fpuflags[j]);
in_fpuflags[j] = my_set_union(use_fpuflags[j], tem_fpuflag);
if (j != 0) {
out[j - 1] = in[j];
out_flags[j - 1] = in_flags[j];
out_fpuflags[j - 1] = in_fpuflags[j];
}
}
for (size_t i = 0; i < mbb.size(); i++) {
if (def[i].empty() && def_flags[i].empty() && def_fpuflags[i].empty()) {
continue;
}
if (delList[i]) {
continue;
}
if (my_set_intersection(def[i], out[i]).empty() &&
my_set_intersection(def_flags[i], out_flags[i]).empty() &&
my_set_intersection(def_fpuflags[i], out_fpuflags[i]).empty()) {
changed = true;
delList[i] = true;
}
}
} while (changed);
for (size_t i = 0; i < mbb.size(); i++) {
if (delList[i]) {
std::cout << "| ---->";
}
else {
std::cout << "| ";
}
std::cout << std::hex << std::uppercase;
std::cout << "\t0x" << mbb[i].viraddr << "\t\t" << mbb[i].opstr << std::endl;
}
std::cout << "--------------------------------------------------------@@@";
std::cout << std::endl << std::endl;
}
cs_close(&hCs);
}
int main() {
char x86code[] = "\xB8\x05\x00\x00\x00\xBB\x10\x00\x00\x00\x01\xD8\xB9\x20\x00\x00\x00\xBA\x30\x00\x00\x00\x01\xD8\xBA\x10\x00\x00\x00\xCC\xF9\xF8\xFC\xFD";
bool is64 = false;
uint64_t virtualAddressBegin = 0x00000000;
RemoveDeadCode(x86code, sizeof(x86code) - 1, is64, virtualAddressBegin);
return 0;
}
std::vector<x86_flag> calc_eflags_use(csh hCs, const Insn& ins) {
cs_insn cinsn{};
cs_detail cdetail{};
disasm(hCs, ins.addr, ins.viraddr, ins.size, &cinsn, &cdetail);
uint64_t eflags = cdetail.x86.eflags;
std::vector<x86_flag> ret = {};
std::vector<uint64_t> useChecks = { X86_EFLAGS_TEST_OF, X86_EFLAGS_TEST_SF, X86_EFLAGS_TEST_ZF,
X86_EFLAGS_TEST_PF, X86_EFLAGS_TEST_CF, X86_EFLAGS_TEST_NT, X86_EFLAGS_TEST_DF,
X86_EFLAGS_TEST_RF, X86_EFLAGS_TEST_IF, X86_EFLAGS_TEST_TF, X86_EFLAGS_TEST_AF
};
for (uint64_t check : useChecks) {
if (eflags & check) {
x86_flag ret_flag;
switch (check){
case X86_EFLAGS_TEST_OF: ret_flag = x86_flag::OF; break;
case X86_EFLAGS_TEST_SF: ret_flag = x86_flag::SF; break;
case X86_EFLAGS_TEST_ZF: ret_flag = x86_flag::ZF; break;
case X86_EFLAGS_TEST_PF: ret_flag = x86_flag::PF; break;
case X86_EFLAGS_TEST_CF: ret_flag = x86_flag::CF; break;
case X86_EFLAGS_TEST_NT: ret_flag = x86_flag::NT; break;
case X86_EFLAGS_TEST_DF: ret_flag = x86_flag::DF; break;
case X86_EFLAGS_TEST_RF: ret_flag = x86_flag::RF; break;
case X86_EFLAGS_TEST_IF: ret_flag = x86_flag::IF; break;
case X86_EFLAGS_TEST_TF: ret_flag = x86_flag::TF; break;
case X86_EFLAGS_TEST_AF: ret_flag = x86_flag::AF; break;
}
ret.push_back(ret_flag);
}
}
return ret;
}
std::vector<x86_flag> calc_eflags_def(csh hCs, const Insn& ins) {
cs_insn cinsn{};
cs_detail cdetail{};
disasm(hCs, ins.addr, ins.viraddr, ins.size, &cinsn, &cdetail);
uint64_t eflags = cdetail.x86.eflags;
std::vector<x86_flag> ret = {};
std::vector<uint64_t> defChecks = { X86_EFLAGS_PRIOR_OF, X86_EFLAGS_PRIOR_SF, X86_EFLAGS_PRIOR_ZF,
X86_EFLAGS_PRIOR_AF, X86_EFLAGS_PRIOR_PF, X86_EFLAGS_PRIOR_CF, X86_EFLAGS_PRIOR_TF,
X86_EFLAGS_PRIOR_IF, X86_EFLAGS_PRIOR_DF, X86_EFLAGS_PRIOR_NT, X86_EFLAGS_MODIFY_AF,
X86_EFLAGS_MODIFY_CF, X86_EFLAGS_MODIFY_SF, X86_EFLAGS_MODIFY_ZF, X86_EFLAGS_MODIFY_PF,
X86_EFLAGS_MODIFY_OF, X86_EFLAGS_MODIFY_TF, X86_EFLAGS_MODIFY_IF, X86_EFLAGS_MODIFY_DF,
X86_EFLAGS_MODIFY_NT, X86_EFLAGS_MODIFY_RF, X86_EFLAGS_SET_CF, X86_EFLAGS_SET_DF,
X86_EFLAGS_SET_IF, X86_EFLAGS_SET_OF, X86_EFLAGS_SET_SF, X86_EFLAGS_SET_ZF, X86_EFLAGS_SET_AF,
X86_EFLAGS_SET_PF, X86_EFLAGS_RESET_OF, X86_EFLAGS_RESET_CF, X86_EFLAGS_RESET_DF,
X86_EFLAGS_RESET_IF, X86_EFLAGS_RESET_SF, X86_EFLAGS_RESET_AF, X86_EFLAGS_RESET_TF,
X86_EFLAGS_RESET_NT, X86_EFLAGS_RESET_PF, X86_EFLAGS_RESET_RF, X86_EFLAGS_RESET_ZF };
for (uint64_t check : defChecks) {
if (eflags & check) {
x86_flag ret_flag;
switch (check) {
case X86_EFLAGS_MODIFY_AF: ret_flag = x86_flag::AF; break;
case X86_EFLAGS_MODIFY_CF: ret_flag = x86_flag::CF; break;
case X86_EFLAGS_MODIFY_SF: ret_flag = x86_flag::SF; break;
case X86_EFLAGS_MODIFY_ZF: ret_flag = x86_flag::ZF; break;
case X86_EFLAGS_MODIFY_PF: ret_flag = x86_flag::PF; break;
case X86_EFLAGS_MODIFY_OF: ret_flag = x86_flag::OF; break;
case X86_EFLAGS_MODIFY_TF: ret_flag = x86_flag::TF; break;
case X86_EFLAGS_MODIFY_IF: ret_flag = x86_flag::IF; break;
case X86_EFLAGS_MODIFY_DF: ret_flag = x86_flag::DF; break;
case X86_EFLAGS_MODIFY_NT: ret_flag = x86_flag::NT; break;
case X86_EFLAGS_MODIFY_RF: ret_flag = x86_flag::RF; break;
case X86_EFLAGS_PRIOR_OF: ret_flag = x86_flag::OF; break;
case X86_EFLAGS_PRIOR_SF: ret_flag = x86_flag::SF; break;
case X86_EFLAGS_PRIOR_ZF: ret_flag = x86_flag::ZF; break;
case X86_EFLAGS_PRIOR_AF: ret_flag = x86_flag::AF; break;
case X86_EFLAGS_PRIOR_PF: ret_flag = x86_flag::PF; break;
case X86_EFLAGS_PRIOR_CF: ret_flag = x86_flag::CF; break;
case X86_EFLAGS_PRIOR_TF: ret_flag = x86_flag::TF; break;
case X86_EFLAGS_PRIOR_IF: ret_flag = x86_flag::IF; break;
case X86_EFLAGS_PRIOR_DF: ret_flag = x86_flag::DF; break;
case X86_EFLAGS_PRIOR_NT: ret_flag = x86_flag::NT; break;
case X86_EFLAGS_SET_CF: ret_flag = x86_flag::CF; break;
case X86_EFLAGS_SET_DF: ret_flag = x86_flag::DF; break;
case X86_EFLAGS_SET_IF: ret_flag = x86_flag::IF; break;
case X86_EFLAGS_SET_OF: ret_flag = x86_flag::OF; break;
case X86_EFLAGS_SET_SF: ret_flag = x86_flag::SF; break;
case X86_EFLAGS_SET_ZF: ret_flag = x86_flag::ZF; break;
case X86_EFLAGS_SET_AF: ret_flag = x86_flag::AF; break;
case X86_EFLAGS_SET_PF: ret_flag = x86_flag::PF; break;
case X86_EFLAGS_RESET_OF: ret_flag = x86_flag::OF; break;
case X86_EFLAGS_RESET_CF: ret_flag = x86_flag::CF; break;
case X86_EFLAGS_RESET_DF: ret_flag = x86_flag::DF; break;
case X86_EFLAGS_RESET_IF: ret_flag = x86_flag::IF; break;
case X86_EFLAGS_RESET_SF: ret_flag = x86_flag::SF; break;
case X86_EFLAGS_RESET_AF: ret_flag = x86_flag::AF; break;
case X86_EFLAGS_RESET_TF: ret_flag = x86_flag::TF; break;
case X86_EFLAGS_RESET_NT: ret_flag = x86_flag::NT; break;
case X86_EFLAGS_RESET_PF: ret_flag = x86_flag::PF; break;
case X86_EFLAGS_RESET_RF: ret_flag = x86_flag::RF; break;
case X86_EFLAGS_RESET_ZF: ret_flag = x86_flag::ZF; break;
}
ret.push_back(ret_flag);
}
}
return ret;
}
std::vector<x86_fpuflag> calc_fpuflags_use(csh hCs, const Insn& ins) {
cs_insn cinsn{};
cs_detail cdetail{};
disasm(hCs, ins.addr, ins.viraddr, ins.size, &cinsn, &cdetail);
uint64_t fpuflags = cdetail.x86.fpu_flags;
std::vector<x86_fpuflag> ret = {};
std::vector<uint32_t> useChecks = {
X86_FPU_FLAGS_TEST_C0, X86_FPU_FLAGS_TEST_C1, X86_FPU_FLAGS_TEST_C2, X86_FPU_FLAGS_TEST_C3
};
for (uint32_t check : useChecks) {
if (fpuflags & check) {
x86_fpuflag ret_flag;
switch (check) {
case X86_FPU_FLAGS_TEST_C0: ret_flag = x86_fpuflag::C0; break;
case X86_FPU_FLAGS_TEST_C1: ret_flag = x86_fpuflag::C1; break;
case X86_FPU_FLAGS_TEST_C2: ret_flag = x86_fpuflag::C2; break;
case X86_FPU_FLAGS_TEST_C3: ret_flag = x86_fpuflag::C3; break;
}
ret.push_back(ret_flag);
}
}
return ret;
}
std::vector<x86_fpuflag> calc_fpuflags_def(csh hCs, const Insn& ins) {
cs_insn cinsn{};
cs_detail cdetail{};
disasm(hCs, ins.addr, ins.viraddr, ins.size, &cinsn, &cdetail);
uint64_t fpuflags = cdetail.x86.fpu_flags;
std::vector<x86_fpuflag> ret = {};
std::vector<uint32_t> defChecks = {
X86_FPU_FLAGS_MODIFY_C0, X86_FPU_FLAGS_MODIFY_C1, X86_FPU_FLAGS_MODIFY_C2, X86_FPU_FLAGS_MODIFY_C3,
X86_FPU_FLAGS_RESET_C0, X86_FPU_FLAGS_RESET_C1, X86_FPU_FLAGS_RESET_C2, X86_FPU_FLAGS_RESET_C3,
X86_FPU_FLAGS_SET_C0, X86_FPU_FLAGS_SET_C1, X86_FPU_FLAGS_SET_C2, X86_FPU_FLAGS_SET_C3
};
for (uint32_t check : defChecks) {
if (fpuflags & check) {
x86_fpuflag ret_flag;
switch (check) {
case X86_FPU_FLAGS_MODIFY_C0: ret_flag = x86_fpuflag::C0; break;
case X86_FPU_FLAGS_MODIFY_C1: ret_flag = x86_fpuflag::C1; break;
case X86_FPU_FLAGS_MODIFY_C2: ret_flag = x86_fpuflag::C2; break;
case X86_FPU_FLAGS_MODIFY_C3: ret_flag = x86_fpuflag::C3; break;
case X86_FPU_FLAGS_RESET_C0: ret_flag = x86_fpuflag::C0; break;
case X86_FPU_FLAGS_RESET_C1: ret_flag = x86_fpuflag::C1; break;
case X86_FPU_FLAGS_RESET_C2: ret_flag = x86_fpuflag::C2; break;
case X86_FPU_FLAGS_RESET_C3: ret_flag = x86_fpuflag::C3; break;
case X86_FPU_FLAGS_SET_C0: ret_flag = x86_fpuflag::C0; break;
case X86_FPU_FLAGS_SET_C1: ret_flag = x86_fpuflag::C1; break;
case X86_FPU_FLAGS_SET_C2: ret_flag = x86_fpuflag::C2; break;
case X86_FPU_FLAGS_SET_C3: ret_flag = x86_fpuflag::C3; break;
}
ret.push_back(ret_flag);
}
}
return ret;
}
运行结果图:
关于 EFlags
对于eflags,capstone是写了一堆宏,然后让我们自行与detail->x86.eflags 来判断,所以...只好自己写了各个标志位的enum
enum class x86_flag : uint8_t { AF, CF, SF, ZF, PF, OF, TF, IF, DF, NT, RF };
然后intel规定一条指令对eflags的影响有7种形式,分别是:(来自Volume 1 -> Appendix A EFLAGES Cross-Reference)
- T Instruction tests flag.
- M Instruction modifies flag (either sets or resets depending on operands).
- 0 Instruction resets flag.
- 1 Instruction sets flag.
- — Instruction's effect on flag is undefined.
- R Instruction restores prior value of flag.
-
Blank Instruction does not affect flag.
按照其内容,我将 T 归为了 use
std::vector<x86_flag> calc_eflags_use(csh hCs, const Insn& ins) {
cs_insn cinsn{};
cs_detail cdetail{};
disasm(hCs, ins.addr, ins.viraddr, ins.size, &cinsn, &cdetail);
uint64_t eflags = cdetail.x86.eflags;
std::vector<x86_flag> ret = {};
std::vector<uint64_t> useChecks = { X86_EFLAGS_TEST_OF, X86_EFLAGS_TEST_SF, X86_EFLAGS_TEST_ZF,
X86_EFLAGS_TEST_PF, X86_EFLAGS_TEST_CF, X86_EFLAGS_TEST_NT, X86_EFLAGS_TEST_DF,
X86_EFLAGS_TEST_RF, X86_EFLAGS_TEST_IF, X86_EFLAGS_TEST_TF, X86_EFLAGS_TEST_AF
};
for (uint64_t check : useChecks) {
if (eflags & check) {
x86_flag ret_flag;
switch (check){
case X86_EFLAGS_TEST_OF: ret_flag = x86_flag::OF; break;
case X86_EFLAGS_TEST_SF: ret_flag = x86_flag::SF; break;
case X86_EFLAGS_TEST_ZF: ret_flag = x86_flag::ZF; break;
case X86_EFLAGS_TEST_PF: ret_flag = x86_flag::PF; break;
case X86_EFLAGS_TEST_CF: ret_flag = x86_flag::CF; break;
case X86_EFLAGS_TEST_NT: ret_flag = x86_flag::NT; break;
case X86_EFLAGS_TEST_DF: ret_flag = x86_flag::DF; break;
case X86_EFLAGS_TEST_RF: ret_flag = x86_flag::RF; break;
case X86_EFLAGS_TEST_IF: ret_flag = x86_flag::IF; break;
case X86_EFLAGS_TEST_TF: ret_flag = x86_flag::TF; break;
case X86_EFLAGS_TEST_AF: ret_flag = x86_flag::AF; break;
}
ret.push_back(ret_flag);
}
}
return ret;
}
而对于M 、R 、1 、0 ,我则将它们 归为了 def
std::vector<x86_flag> calc_eflags_def(csh hCs, const Insn& ins) {
cs_insn cinsn{};
cs_detail cdetail{};
disasm(hCs, ins.addr, ins.viraddr, ins.size, &cinsn, &cdetail);
uint64_t eflags = cdetail.x86.eflags;
std::vector<x86_flag> ret = {};
std::vector<uint64_t> defChecks = { X86_EFLAGS_PRIOR_OF, X86_EFLAGS_PRIOR_SF, X86_EFLAGS_PRIOR_ZF,
X86_EFLAGS_PRIOR_AF, X86_EFLAGS_PRIOR_PF, X86_EFLAGS_PRIOR_CF, X86_EFLAGS_PRIOR_TF,
X86_EFLAGS_PRIOR_IF, X86_EFLAGS_PRIOR_DF, X86_EFLAGS_PRIOR_NT, X86_EFLAGS_MODIFY_AF,
X86_EFLAGS_MODIFY_CF, X86_EFLAGS_MODIFY_SF, X86_EFLAGS_MODIFY_ZF, X86_EFLAGS_MODIFY_PF,
X86_EFLAGS_MODIFY_OF, X86_EFLAGS_MODIFY_TF, X86_EFLAGS_MODIFY_IF, X86_EFLAGS_MODIFY_DF,
X86_EFLAGS_MODIFY_NT, X86_EFLAGS_MODIFY_RF, X86_EFLAGS_SET_CF, X86_EFLAGS_SET_DF,
X86_EFLAGS_SET_IF, X86_EFLAGS_SET_OF, X86_EFLAGS_SET_SF, X86_EFLAGS_SET_ZF, X86_EFLAGS_SET_AF,
X86_EFLAGS_SET_PF, X86_EFLAGS_RESET_OF, X86_EFLAGS_RESET_CF, X86_EFLAGS_RESET_DF,
X86_EFLAGS_RESET_IF, X86_EFLAGS_RESET_SF, X86_EFLAGS_RESET_AF, X86_EFLAGS_RESET_TF,
X86_EFLAGS_RESET_NT, X86_EFLAGS_RESET_PF, X86_EFLAGS_RESET_RF, X86_EFLAGS_RESET_ZF };
for (uint64_t check : defChecks) {
if (eflags & check) {
x86_flag ret_flag;
switch (check) {
case X86_EFLAGS_MODIFY_AF: ret_flag = x86_flag::AF; break;
case X86_EFLAGS_MODIFY_CF: ret_flag = x86_flag::CF; break;
case X86_EFLAGS_MODIFY_SF: ret_flag = x86_flag::SF; break;
case X86_EFLAGS_MODIFY_ZF: ret_flag = x86_flag::ZF; break;
case X86_EFLAGS_MODIFY_PF: ret_flag = x86_flag::PF; break;
case X86_EFLAGS_MODIFY_OF: ret_flag = x86_flag::OF; break;
case X86_EFLAGS_MODIFY_TF: ret_flag = x86_flag::TF; break;
case X86_EFLAGS_MODIFY_IF: ret_flag = x86_flag::IF; break;
case X86_EFLAGS_MODIFY_DF: ret_flag = x86_flag::DF; break;
case X86_EFLAGS_MODIFY_NT: ret_flag = x86_flag::NT; break;
case X86_EFLAGS_MODIFY_RF: ret_flag = x86_flag::RF; break;
case X86_EFLAGS_PRIOR_OF: ret_flag = x86_flag::OF; break;
case X86_EFLAGS_PRIOR_SF: ret_flag = x86_flag::SF; break;
case X86_EFLAGS_PRIOR_ZF: ret_flag = x86_flag::ZF; break;
case X86_EFLAGS_PRIOR_AF: ret_flag = x86_flag::AF; break;
case X86_EFLAGS_PRIOR_PF: ret_flag = x86_flag::PF; break;
case X86_EFLAGS_PRIOR_CF: ret_flag = x86_flag::CF; break;
case X86_EFLAGS_PRIOR_TF: ret_flag = x86_flag::TF; break;
case X86_EFLAGS_PRIOR_IF: ret_flag = x86_flag::IF; break;
case X86_EFLAGS_PRIOR_DF: ret_flag = x86_flag::DF; break;
case X86_EFLAGS_PRIOR_NT: ret_flag = x86_flag::NT; break;
case X86_EFLAGS_SET_CF: ret_flag = x86_flag::CF; break;
case X86_EFLAGS_SET_DF: ret_flag = x86_flag::DF; break;
case X86_EFLAGS_SET_IF: ret_flag = x86_flag::IF; break;
case X86_EFLAGS_SET_OF: ret_flag = x86_flag::OF; break;
case X86_EFLAGS_SET_SF: ret_flag = x86_flag::SF; break;
case X86_EFLAGS_SET_ZF: ret_flag = x86_flag::ZF; break;
case X86_EFLAGS_SET_AF: ret_flag = x86_flag::AF; break;
case X86_EFLAGS_SET_PF: ret_flag = x86_flag::PF; break;
case X86_EFLAGS_RESET_OF: ret_flag = x86_flag::OF; break;
case X86_EFLAGS_RESET_CF: ret_flag = x86_flag::CF; break;
case X86_EFLAGS_RESET_DF: ret_flag = x86_flag::DF; break;
case X86_EFLAGS_RESET_IF: ret_flag = x86_flag::IF; break;
case X86_EFLAGS_RESET_SF: ret_flag = x86_flag::SF; break;
case X86_EFLAGS_RESET_AF: ret_flag = x86_flag::AF; break;
case X86_EFLAGS_RESET_TF: ret_flag = x86_flag::TF; break;
case X86_EFLAGS_RESET_NT: ret_flag = x86_flag::NT; break;
case X86_EFLAGS_RESET_PF: ret_flag = x86_flag::PF; break;
case X86_EFLAGS_RESET_RF: ret_flag = x86_flag::RF; break;
case X86_EFLAGS_RESET_ZF: ret_flag = x86_flag::ZF; break;
}
ret.push_back(ret_flag);
}
}
return ret;
}
紧接类似地,用这些去创建eflags的use、def、in、out集合,和寄存器一样的流程去解析它们的use、def,去计算它们的in、out;最后再和寄存器的def/out的交集结果用&&连起来判断就可以了
if (my_set_intersection(def[i], out[i]).empty() &&
my_set_intersection(def_flags[i], out_flags[i]).empty() &&
my_set_intersection(def_fpuflags[i], out_fpuflags[i]).empty()) {
changed = true;
delList[i] = true;
}
关于 fpu flags
这是只是我顺手写的,为了保证最大兼容性,写一下这个应该也无妨
参考
【利用活跃变量分析来去掉vmp的大部分垃圾指令】 https://bbs.kanxue.com/thread-265950.htm
【C++利用活跃变量分析清除基本块中的垃圾指令】
https://bbs.kanxue.com/thread-277825.htm
【中南大学 编译原理 - 课时42: 数据流分析(2) 】
https://www.bilibili.com/video/BV1jU4y1W7vG
|
免费评分
-
查看全部评分
|