1
0
Fork 0

QBeaEngine: Implemented reg & flag info again

This commit is contained in:
Joel Höner 2017-09-24 03:10:52 +02:00 committed by Duncan Ogilvie
parent af0ff55df3
commit 16942049b3
2 changed files with 44 additions and 53 deletions

View File

@ -223,40 +223,46 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
wInst.branchType = branchType;
wInst.tokens = cap;
if(success)
if(!success)
return wInst;
auto instr = cp.GetInstr();
cp.RegInfo(reginfo);
for(ZydisCPUFlag i = 0; i <= ZYDIS_CPUFLAG_MAX_VALUE; ++i)
{
/* TODO
auto instr = cp.GetInstr();
cp.RegInfo(reginfo);
auto flagAction = instr->accessedFlags[i].action;
if(flagAction == ZYDIS_CPUFLAG_ACTION_NONE)
continue;
auto flaginfo2reginfo = [](uint8_t info)
Zydis::RegAccessInfo rai;
switch(flagAction)
{
auto result = 0;
#define checkFlag(test, reg) result |= (info & test) == test ? reg : 0
checkFlag(Capstone::Modify, Capstone::Write);
checkFlag(Capstone::Prior, Capstone::None);
checkFlag(Capstone::Reset, Capstone::Write);
checkFlag(Capstone::Set, Capstone::Write);
checkFlag(Capstone::Test, Capstone::Read);
checkFlag(Capstone::Undefined, Capstone::None);
#undef checkFlag
return result;
};
case ZYDIS_CPUFLAG_ACTION_MODIFIED:
case ZYDIS_CPUFLAG_ACTION_SET_0:
case ZYDIS_CPUFLAG_ACTION_SET_1:
rai = Zydis::RAIWrite;
break;
case ZYDIS_CPUFLAG_ACTION_TESTED:
rai = Zydis::RAIRead;
break;
default:
rai = Zydis::RAINone;
break;
}
for(uint8_t i = Capstone::FLAG_INVALID; i < Capstone::FLAG_ENDING; i++)
if(flaginfo[i])
{
reginfo[ZYDIS_REGISTER_FLAGS] = Capstone::None;
wInst.regsReferenced.push_back({cp.FlagName(Capstone::Flag(i)), flaginfo2reginfo(flaginfo[i])});
}
reginfo[ZYDIS_REGISTER_RFLAGS] = Zydis::RAINone;
reginfo[ZYDIS_REGISTER_EFLAGS] = Zydis::RAINone;
reginfo[ZYDIS_REGISTER_FLAGS] = Zydis::RAINone;
reginfo[ArchValue(ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_RIP)] = Capstone::None;
for(uint8_t i = ZYDIS_REGISTER_NONE; i < ZYDIS_REGISTER_ENUM_COUNT; i++)
if(reginfo[i])
wInst.regsReferenced.push_back({cp.RegName(x86_reg(i)), reginfo[i]});
*/
wInst.regsReferenced.emplace_back(cp.FlagName(i), rai);
}
reginfo[ArchValue(ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_RIP)] = Zydis::RAINone;
for(ZydisRegister i = ZYDIS_REGISTER_NONE; i <= ZYDIS_REGISTER_MAX_VALUE; ++i)
if(reginfo[i])
wInst.regsReferenced.emplace_back(cp.RegName(ZydisRegister(i)), reginfo[i]);
return wInst;
}

View File

@ -546,7 +546,7 @@ std::string Zydis::Mnemonic() const
std::string Zydis::MnemonicId() const
{
// hax
// Zydis doesn't have instruction IDs.
return Mnemonic();
}
@ -789,9 +789,11 @@ void Zydis::RegInfo(uint8_t regs[ZYDIS_REGISTER_MAX_VALUE + 1]) const
memset(regs, 0, sizeof(uint8_t) * (ZYDIS_REGISTER_MAX_VALUE + 1));
if(!Success() || IsNop())
return;
for(int i = 0; i < OpCount(); i++)
for(int i = 0; i < mInstr.operandCount; ++i)
{
const auto & op = mInstr.operands[i];
switch(op.type)
{
case ZYDIS_OPERAND_TYPE_REGISTER:
@ -800,35 +802,18 @@ void Zydis::RegInfo(uint8_t regs[ZYDIS_REGISTER_MAX_VALUE + 1]) const
regs[op.reg.value] |= RAIRead;
if(op.action & ZYDIS_OPERAND_ACTION_MASK_WRITE)
regs[op.reg.value] |= RAIWrite;
regs[op.reg.value] |= op.visibility != ZYDIS_OPERAND_VISIBILITY_HIDDEN ?
RAIExplicit : RAIImplicit;
regs[op.reg.value] |= op.visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN ?
RAIImplicit : RAIExplicit;
}
break;
case ZYDIS_OPERAND_TYPE_MEMORY:
{
if(op.mem.segment == ZYDIS_REGISTER_NONE)
{
switch(op.mem.base)
{
#ifdef _WIN64
case ZYDIS_REGISTER_RSP:
case ZYDIS_REGISTER_RBP:
#else //x86
case ZYDIS_REGISTER_ESP:
case ZYDIS_REGISTER_EBP:
#endif //_WIN64
regs[ZYDIS_REGISTER_SS] |= RAIRead | RAIExplicit;
break;
default:
regs[ZYDIS_REGISTER_DS] |= RAIRead | RAIExplicit;
break;
}
}
else
regs[op.mem.segment] |= RAIRead | RAIExplicit;
regs[op.mem.base] |= RAIRead | RAIExplicit;
regs[op.mem.index] |= RAIRead | RAIExplicit;
regs[op.mem.segment] |= RAIRead | RAIExplicit;
if(op.mem.base != ZYDIS_REGISTER_NONE)
regs[op.mem.base] |= RAIRead | RAIExplicit;
if(op.mem.base != ZYDIS_REGISTER_NONE)
regs[op.mem.index] |= RAIRead | RAIExplicit;
}
break;