New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from Oct 10, 2017
Jump to file or symbol
Failed to load files and symbols.
+29 −28
Diff settings

Always

Just for now

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)
ProTip! Use n and p to navigate between commits in a pull request.