Permalink
Browse files

Add range checks for operand access (fixes #1750) (#1751)

* DBG: added range checks to operand access
- previously, some instructions could trigger the `DebugBreak` path in `Zydis::operator[]`
* GUI: removed redundant semicolon
  • Loading branch information...
athre0z authored and mrexodia committed Oct 10, 2017
1 parent aee7a2e commit c5c3358c529c37988991d998bbbe9b2147fa6af4
View
@@ -803,7 +803,7 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
return 0;
}
});
if(cp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
if(cp.OpCount() && cp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
#ifdef _WIN64
auto const tebseg = ZYDIS_REGISTER_GS;
@@ -215,27 +215,30 @@ void LinearPass::AnalysisWorker(duint Start, duint End, BBlockArray* Blocks)
block->SetFlag(BASIC_BLOCK_FLAG_ABSJMP);
// Figure out the operand type(s)
const auto & operand = disasm[0];
if(operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
{
// Branch target immediate
block->Target = (duint)operand.imm.value.u;
}
else
if(disasm.OpCount() > 0)
{
// Indirects (no operand, register, or memory)
block->SetFlag(BASIC_BLOCK_FLAG_INDIRECT);
const auto & operand = disasm[0];
if(operand.type == ZYDIS_OPERAND_TYPE_MEMORY &&
operand.mem.base == ZYDIS_REGISTER_RIP &&
operand.mem.index == ZYDIS_REGISTER_NONE &&
operand.mem.scale == 1)
if(operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
{
// Branch target immediate
block->Target = (duint)operand.imm.value.u;
}
else
{
/*
block->SetFlag(BASIC_BLOCK_FLAG_INDIRPTR);
block->Target = (duint)operand.mem.disp;
*/
// Indirects (no operand, register, or memory)
block->SetFlag(BASIC_BLOCK_FLAG_INDIRECT);
if(operand.type == ZYDIS_OPERAND_TYPE_MEMORY &&
operand.mem.base == ZYDIS_REGISTER_RIP &&
operand.mem.index == ZYDIS_REGISTER_NONE &&
operand.mem.scale == 1)
{
/*
block->SetFlag(BASIC_BLOCK_FLAG_INDIRPTR);
block->Target = (duint)operand.mem.disp;
*/
}
}
}
}
@@ -86,7 +86,7 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
if(mCp.Disassemble(start, translateAddr(start), MAX_DISASM_BUFFER))
{
//JMP [123456] ; import
if(mCp.IsJump() && mCp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
if(mCp.IsJump() && mCp.OpCount() && mCp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
return 0;
}
@@ -100,10 +100,9 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
if(addr + mCp.Size() > maxaddr) //we went past the maximum allowed address
break;
const auto & op = mCp[0];
if((mCp.IsJump() || mCp.IsLoop()) && op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
if((mCp.IsJump() || mCp.IsLoop()) && mCp.OpCount() && mCp[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
{
auto dest = duint(op.imm.value.u);
auto dest = duint(mCp[0].imm.value.u);
if(dest >= maxaddr) //jump across function boundaries
{
@@ -124,7 +124,7 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
node.brfalse = node.end + mCp.Size();
//consider register/memory branches as terminal nodes
if(mCp[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE)
if(mCp.OpCount() && mCp[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE)
{
//jmp ptr [index * sizeof(duint) + switchTable]
if(mCp[0].type == ZYDIS_OPERAND_TYPE_MEMORY && mCp[0].mem.base == ZYDIS_REGISTER_NONE && mCp[0].mem.index != ZYDIS_REGISTER_NONE
@@ -335,10 +335,9 @@ bool cbInstrVisualize(int argc, char* argv[])
if(addr + _cp.Size() > maxaddr) //we went past the maximum allowed address
break;
const auto & operand = _cp[0];
if((_cp.IsJump() || _cp.IsLoop()) && operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
if((_cp.IsJump() || _cp.IsLoop()) && _cp.OpCount() && _cp[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
{
duint dest = (duint)operand.imm.value.u;
duint dest = (duint)_cp[0].imm.value.u;
if(dest >= maxaddr) //jump across function boundaries
{
@@ -419,7 +419,7 @@ bool CapstoneTokenizer::tokenizeMnemonic()
else if(_cp.IsUnusual())
_mnemonicType = TokenType::MnemonicUnusual;
return tokenizeMnemonic(_mnemonicType, mnemonic);;
return tokenizeMnemonic(_mnemonicType, mnemonic);
}
bool CapstoneTokenizer::tokenizeMnemonic(TokenType type, const QString & mnemonic)

0 comments on commit c5c3358

Please sign in to comment.