// Copyright (c) 2017-2025 Vector 35 Inc
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
#include "binaryninjaapi.h"
#include "mediumlevelilinstruction.h"
using namespace BinaryNinja;
using namespace std;
MediumLevelILLabel::MediumLevelILLabel()
{
BNMediumLevelILInitLabel(this);
}
MediumLevelILFunction::MediumLevelILFunction(Architecture* arch, Function* func)
{
m_object = BNCreateMediumLevelILFunction(arch->GetObject(), func ? func->GetObject() : nullptr);
}
MediumLevelILFunction::MediumLevelILFunction(BNMediumLevelILFunction* func)
{
m_object = func;
}
Ref MediumLevelILFunction::GetFunction() const
{
BNFunction* func = BNGetMediumLevelILOwnerFunction(m_object);
if (!func)
return nullptr;
return new Function(func);
}
Ref MediumLevelILFunction::GetArchitecture() const
{
Ref func = GetFunction();
if (!func)
return nullptr;
return func->GetArchitecture();
}
uint64_t MediumLevelILFunction::GetCurrentAddress() const
{
return BNMediumLevelILGetCurrentAddress(m_object);
}
void MediumLevelILFunction::SetCurrentAddress(Architecture* arch, uint64_t addr)
{
BNMediumLevelILSetCurrentAddress(m_object, arch ? arch->GetObject() : nullptr, addr);
}
size_t MediumLevelILFunction::GetInstructionStart(Architecture* arch, uint64_t addr)
{
return BNMediumLevelILGetInstructionStart(m_object, arch ? arch->GetObject() : nullptr, addr);
}
void MediumLevelILFunction::PrepareToCopyFunction(MediumLevelILFunction* func)
{
BNPrepareToCopyMediumLevelILFunction(m_object, func->GetObject());
}
void MediumLevelILFunction::PrepareToCopyBlock(BasicBlock* block)
{
BNPrepareToCopyMediumLevelILBasicBlock(m_object, block->GetObject());
}
BNMediumLevelILLabel* MediumLevelILFunction::GetLabelForSourceInstruction(size_t i)
{
return BNGetLabelForMediumLevelILSourceInstruction(m_object, i);
}
size_t MediumLevelILFunction::CachePossibleValueSet(const PossibleValueSet& pvs)
{
BNPossibleValueSet ugh = pvs.ToAPIObject();
return BNCacheMediumLevelILPossibleValueSet(m_object, &ugh);
}
PossibleValueSet MediumLevelILFunction::GetCachedPossibleValueSet(size_t idx)
{
BNPossibleValueSet api = BNGetCachedMediumLevelILPossibleValueSet(m_object, idx);
return PossibleValueSet::FromAPIObject(api);
}
ExprId MediumLevelILFunction::AddExpr(
BNMediumLevelILOperation operation, size_t size, ExprId a, ExprId b, ExprId c, ExprId d, ExprId e)
{
return BNMediumLevelILAddExpr(m_object, operation, size, a, b, c, d, e);
}
ExprId MediumLevelILFunction::AddExprWithLocation(BNMediumLevelILOperation operation, uint64_t addr,
uint32_t sourceOperand, size_t size, ExprId a, ExprId b, ExprId c, ExprId d, ExprId e)
{
return BNMediumLevelILAddExprWithLocation(m_object, operation, addr, sourceOperand, size, a, b, c, d, e);
}
ExprId MediumLevelILFunction::AddExprWithLocation(BNMediumLevelILOperation operation, const ILSourceLocation& loc,
size_t size, ExprId a, ExprId b, ExprId c, ExprId d, ExprId e)
{
if (loc.valid)
{
return BNMediumLevelILAddExprWithLocation(
m_object, operation, loc.address, loc.sourceOperand, size, a, b, c, d, e);
}
return BNMediumLevelILAddExpr(m_object, operation, size, a, b, c, d, e);
}
ExprId MediumLevelILFunction::AddInstruction(size_t expr)
{
return BNMediumLevelILAddInstruction(m_object, expr);
}
ExprId MediumLevelILFunction::Goto(BNMediumLevelILLabel& label, const ILSourceLocation& loc)
{
if (loc.valid)
return BNMediumLevelILGotoWithLocation(m_object, &label, loc.address, loc.sourceOperand);
return BNMediumLevelILGoto(m_object, &label);
}
ExprId MediumLevelILFunction::If(
ExprId operand, BNMediumLevelILLabel& t, BNMediumLevelILLabel& f, const ILSourceLocation& loc)
{
if (loc.valid)
return BNMediumLevelILIfWithLocation(m_object, operand, &t, &f, loc.address, loc.sourceOperand);
return BNMediumLevelILIf(m_object, operand, &t, &f);
}
void MediumLevelILFunction::MarkLabel(BNMediumLevelILLabel& label)
{
BNMediumLevelILMarkLabel(m_object, &label);
}
vector MediumLevelILFunction::GetOperandList(ExprId expr, size_t listOperand)
{
size_t count;
uint64_t* operands = BNMediumLevelILGetOperandList(m_object, expr, listOperand, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(operands[i]);
BNMediumLevelILFreeOperandList(operands);
return result;
}
ExprId MediumLevelILFunction::AddLabelMap(const map& labels)
{
uint64_t* valueList = new uint64_t[labels.size()];
BNMediumLevelILLabel** labelList = new BNMediumLevelILLabel*[labels.size()];
size_t i = 0;
for (auto& j : labels)
{
valueList[i] = j.first;
labelList[i] = j.second;
i++;
}
ExprId result = (ExprId)BNMediumLevelILAddLabelMap(m_object, valueList, labelList, labels.size());
delete[] valueList;
delete[] labelList;
return result;
}
ExprId MediumLevelILFunction::AddOperandList(const vector operands)
{
uint64_t* operandList = new uint64_t[operands.size()];
for (size_t i = 0; i < operands.size(); i++)
operandList[i] = operands[i];
ExprId result = (ExprId)BNMediumLevelILAddOperandList(m_object, operandList, operands.size());
delete[] operandList;
return result;
}
ExprId MediumLevelILFunction::AddIndexList(const vector& operands)
{
uint64_t* operandList = new uint64_t[operands.size()];
for (size_t i = 0; i < operands.size(); i++)
operandList[i] = operands[i];
ExprId result = (ExprId)BNMediumLevelILAddOperandList(m_object, operandList, operands.size());
delete[] operandList;
return result;
}
ExprId MediumLevelILFunction::AddVariableList(const vector& vars)
{
uint64_t* operandList = new uint64_t[vars.size()];
for (size_t i = 0; i < vars.size(); i++)
operandList[i] = vars[i].ToIdentifier();
ExprId result = (ExprId)BNMediumLevelILAddOperandList(m_object, operandList, vars.size());
delete[] operandList;
return result;
}
ExprId MediumLevelILFunction::AddSSAVariableList(const vector& vars)
{
uint64_t* operandList = new uint64_t[vars.size() * 2];
for (size_t i = 0; i < vars.size(); i++)
{
operandList[i * 2] = vars[i].var.ToIdentifier();
operandList[(i * 2) + 1] = vars[i].version;
}
ExprId result = (ExprId)BNMediumLevelILAddOperandList(m_object, operandList, vars.size() * 2);
delete[] operandList;
return result;
}
BNMediumLevelILInstruction MediumLevelILFunction::GetRawExpr(size_t i) const
{
return BNGetMediumLevelILByIndex(m_object, i);
}
MediumLevelILInstruction MediumLevelILFunction::operator[](size_t i)
{
return GetInstruction(i);
}
MediumLevelILInstruction MediumLevelILFunction::GetInstruction(size_t i)
{
size_t expr = GetIndexForInstruction(i);
return MediumLevelILInstruction(this, GetRawExpr(expr), expr, i);
}
MediumLevelILInstruction MediumLevelILFunction::GetExpr(size_t i)
{
return MediumLevelILInstruction(this, GetRawExpr(i), i, GetInstructionForExpr(i));
}
size_t MediumLevelILFunction::GetIndexForInstruction(size_t i) const
{
return BNGetMediumLevelILIndexForInstruction(m_object, i);
}
size_t MediumLevelILFunction::GetInstructionForExpr(size_t expr) const
{
return BNGetMediumLevelILInstructionForExpr(m_object, expr);
}
size_t MediumLevelILFunction::GetInstructionCount() const
{
return BNGetMediumLevelILInstructionCount(m_object);
}
size_t MediumLevelILFunction::GetExprCount() const
{
return BNGetMediumLevelILExprCount(m_object);
}
void MediumLevelILFunction::UpdateInstructionOperand(size_t i, size_t operandIndex, ExprId value)
{
BNUpdateMediumLevelILOperand(m_object, i, operandIndex, value);
}
void MediumLevelILFunction::MarkInstructionForRemoval(size_t i)
{
BNMarkMediumLevelILInstructionForRemoval(m_object, i);
}
void MediumLevelILFunction::ReplaceInstruction(size_t i, ExprId expr)
{
BNReplaceMediumLevelILInstruction(m_object, i, expr);
}
void MediumLevelILFunction::ReplaceExpr(size_t expr, size_t newExpr)
{
BNReplaceMediumLevelILExpr(m_object, expr, newExpr);
}
void MediumLevelILFunction::SetExprAttributes(size_t expr, uint32_t attributes)
{
BNSetMediumLevelILExprAttributes(m_object, expr, attributes);
}
void MediumLevelILFunction::Finalize()
{
BNFinalizeMediumLevelILFunction(m_object);
}
void MediumLevelILFunction::GenerateSSAForm(bool analyzeConditionals, bool handleAliases,
const set& knownNotAliases, const set& knownAliases)
{
BNVariable* knownNotAlias = new BNVariable[knownNotAliases.size()];
BNVariable* knownAlias = new BNVariable[knownAliases.size()];
size_t i = 0;
for (auto& j : knownNotAliases)
{
knownNotAlias[i].type = j.type;
knownNotAlias[i].index = j.index;
knownNotAlias[i].storage = j.storage;
i++;
}
i = 0;
for (auto& j : knownAliases)
{
knownAlias[i].type = j.type;
knownAlias[i].index = j.index;
knownAlias[i].storage = j.storage;
i++;
}
BNGenerateMediumLevelILSSAForm(m_object, analyzeConditionals, handleAliases, knownNotAlias, knownNotAliases.size(),
knownAlias, knownAliases.size());
delete[] knownNotAlias;
delete[] knownAlias;
}
bool MediumLevelILFunction::GetExprText(
Architecture* arch, ExprId expr, vector& tokens, DisassemblySettings* settings)
{
size_t count;
BNInstructionTextToken* list;
if (!BNGetMediumLevelILExprText(
m_object, arch->GetObject(), expr, &list, &count, settings ? settings->GetObject() : nullptr))
return false;
tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(list, count);
return true;
}
bool MediumLevelILFunction::GetInstructionText(Function* func, Architecture* arch, size_t instr,
vector& tokens, DisassemblySettings* settings)
{
size_t count;
BNInstructionTextToken* list;
if (!BNGetMediumLevelILInstructionText(m_object, func ? func->GetObject() : nullptr, arch->GetObject(), instr,
&list, &count, settings ? settings->GetObject() : nullptr))
return false;
tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(list, count);
return true;
}
void MediumLevelILFunction::VisitInstructions(
const function& func)
{
for (auto& i : GetBasicBlocks())
for (size_t j = i->GetStart(); j < i->GetEnd(); j++)
func(i, GetInstruction(j));
}
void MediumLevelILFunction::VisitAllExprs(
const function& func)
{
VisitInstructions([&](BasicBlock* block, const MediumLevelILInstruction& instr) {
instr.VisitExprs([&](const MediumLevelILInstruction& expr) { return func(block, expr); });
});
}
vector[> MediumLevelILFunction::GetBasicBlocks() const
{
size_t count;
BNBasicBlock** blocks = BNGetMediumLevelILBasicBlockList(m_object, &count);
vector][> result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new BasicBlock(BNNewBasicBlockReference(blocks[i])));
BNFreeBasicBlockList(blocks, count);
return result;
}
Ref MediumLevelILFunction::GetBasicBlockForInstruction(size_t i) const
{
BNBasicBlock* block = BNGetMediumLevelILBasicBlockForInstruction(m_object, i);
if (!block)
return nullptr;
return new BasicBlock(block);
}
Ref MediumLevelILFunction::GetSSAForm() const
{
BNMediumLevelILFunction* func = BNGetMediumLevelILSSAForm(m_object);
if (!func)
return nullptr;
return new MediumLevelILFunction(func);
}
Ref MediumLevelILFunction::GetNonSSAForm() const
{
BNMediumLevelILFunction* func = BNGetMediumLevelILNonSSAForm(m_object);
if (!func)
return nullptr;
return new MediumLevelILFunction(func);
}
size_t MediumLevelILFunction::GetSSAInstructionIndex(size_t instr) const
{
return BNGetMediumLevelILSSAInstructionIndex(m_object, instr);
}
size_t MediumLevelILFunction::GetNonSSAInstructionIndex(size_t instr) const
{
return BNGetMediumLevelILNonSSAInstructionIndex(m_object, instr);
}
size_t MediumLevelILFunction::GetSSAExprIndex(size_t expr) const
{
return BNGetMediumLevelILSSAExprIndex(m_object, expr);
}
size_t MediumLevelILFunction::GetNonSSAExprIndex(size_t expr) const
{
return BNGetMediumLevelILNonSSAExprIndex(m_object, expr);
}
size_t MediumLevelILFunction::GetSSAVarDefinition(const SSAVariable& var) const
{
return BNGetMediumLevelILSSAVarDefinition(m_object, &var.var, var.version);
}
size_t MediumLevelILFunction::GetSSAMemoryDefinition(size_t version) const
{
return BNGetMediumLevelILSSAMemoryDefinition(m_object, version);
}
set MediumLevelILFunction::GetSSAVarUses(const SSAVariable& var) const
{
size_t count;
size_t* instrs = BNGetMediumLevelILSSAVarUses(m_object, &var.var, var.version, &count);
set result;
for (size_t i = 0; i < count; i++)
result.insert(instrs[i]);
BNFreeILInstructionList(instrs);
return result;
}
set MediumLevelILFunction::GetSSAMemoryUses(size_t version) const
{
size_t count;
size_t* instrs = BNGetMediumLevelILSSAMemoryUses(m_object, version, &count);
set result;
for (size_t i = 0; i < count; i++)
result.insert(instrs[i]);
BNFreeILInstructionList(instrs);
return result;
}
bool MediumLevelILFunction::IsSSAVarLive(const SSAVariable& var) const
{
return BNIsMediumLevelILSSAVarLive(m_object, &var.var, var.version);
}
bool MediumLevelILFunction::IsSSAVarLiveAt(const SSAVariable& var, const size_t instr) const
{
return BNIsMediumLevelILSSAVarLiveAt(m_object, &var.var, var.version, instr);
}
bool MediumLevelILFunction::IsVarLiveAt(const Variable& var, const size_t instr) const
{
return BNIsMediumLevelILVarLiveAt(m_object, &var, instr);
}
set MediumLevelILFunction::GetVariableSSAVersions(const Variable& var) const
{
size_t count;
size_t* versions = BNGetMediumLevelILVariableSSAVersions(m_object, &var, &count);
set result;
for (size_t i = 0; i < count; i++)
result.insert(versions[i]);
BNFreeILInstructionList(versions);
return result;
}
set MediumLevelILFunction::GetVariableDefinitions(const Variable& var) const
{
size_t count;
size_t* instrs = BNGetMediumLevelILVariableDefinitions(m_object, &var, &count);
set result;
for (size_t i = 0; i < count; i++)
result.insert(instrs[i]);
BNFreeILInstructionList(instrs);
return result;
}
set MediumLevelILFunction::GetVariableUses(const Variable& var) const
{
size_t count;
size_t* instrs = BNGetMediumLevelILVariableUses(m_object, &var, &count);
set result;
for (size_t i = 0; i < count; i++)
result.insert(instrs[i]);
BNFreeILInstructionList(instrs);
return result;
}
RegisterValue MediumLevelILFunction::GetSSAVarValue(const SSAVariable& var)
{
BNRegisterValue value = BNGetMediumLevelILSSAVarValue(m_object, &var.var, var.version);
return RegisterValue::FromAPIObject(value);
}
RegisterValue MediumLevelILFunction::GetExprValue(size_t expr)
{
BNRegisterValue value = BNGetMediumLevelILExprValue(m_object, expr);
return RegisterValue::FromAPIObject(value);
}
RegisterValue MediumLevelILFunction::GetExprValue(const MediumLevelILInstruction& expr)
{
return GetExprValue(expr.exprIndex);
}
PossibleValueSet MediumLevelILFunction::GetPossibleSSAVarValues(
const SSAVariable& var, size_t instr, const set& options)
{
BNDataFlowQueryOption* optionArray = new BNDataFlowQueryOption[options.size()];
size_t idx = 0;
for (auto i : options)
optionArray[idx++] = i;
BNPossibleValueSet value =
BNGetMediumLevelILPossibleSSAVarValues(m_object, &var.var, var.version, instr, optionArray, options.size());
delete[] optionArray;
return PossibleValueSet::FromAPIObject(value);
}
PossibleValueSet MediumLevelILFunction::GetPossibleExprValues(size_t expr, const set& options)
{
BNDataFlowQueryOption* optionArray = new BNDataFlowQueryOption[options.size()];
size_t idx = 0;
for (auto i : options)
optionArray[idx++] = i;
BNPossibleValueSet value = BNGetMediumLevelILPossibleExprValues(m_object, expr, optionArray, options.size());
delete[] optionArray;
return PossibleValueSet::FromAPIObject(value);
}
PossibleValueSet MediumLevelILFunction::GetPossibleExprValues(
const MediumLevelILInstruction& expr, const set& options)
{
return GetPossibleExprValues(expr.exprIndex, options);
}
size_t MediumLevelILFunction::GetSSAVarVersionAtInstruction(const Variable& var, size_t instr) const
{
return BNGetMediumLevelILSSAVarVersionAtILInstruction(m_object, &var, instr);
}
size_t MediumLevelILFunction::GetSSAVarVersionAfterInstruction(const Variable& var, size_t instr) const
{
return BNGetMediumLevelILSSAVarVersionAfterILInstruction(m_object, &var, instr);
}
size_t MediumLevelILFunction::GetSSAMemoryVersionAtInstruction(size_t instr) const
{
return BNGetMediumLevelILSSAMemoryVersionAtILInstruction(m_object, instr);
}
size_t MediumLevelILFunction::GetSSAMemoryVersionAfterInstruction(size_t instr) const
{
return BNGetMediumLevelILSSAMemoryVersionAfterILInstruction(m_object, instr);
}
Variable MediumLevelILFunction::GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const
{
return BNGetMediumLevelILVariableForRegisterAtInstruction(m_object, reg, instr);
}
Variable MediumLevelILFunction::GetVariableForRegisterAfterInstruction(uint32_t reg, size_t instr) const
{
return BNGetMediumLevelILVariableForRegisterAfterInstruction(m_object, reg, instr);
}
Variable MediumLevelILFunction::GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const
{
return BNGetMediumLevelILVariableForFlagAtInstruction(m_object, flag, instr);
}
Variable MediumLevelILFunction::GetVariableForFlagAfterInstruction(uint32_t flag, size_t instr) const
{
return BNGetMediumLevelILVariableForFlagAfterInstruction(m_object, flag, instr);
}
Variable MediumLevelILFunction::GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const
{
return BNGetMediumLevelILVariableForStackLocationAtInstruction(m_object, offset, instr);
}
Variable MediumLevelILFunction::GetVariableForStackLocationAfterInstruction(int64_t offset, size_t instr) const
{
return BNGetMediumLevelILVariableForStackLocationAfterInstruction(m_object, offset, instr);
}
RegisterValue MediumLevelILFunction::GetRegisterValueAtInstruction(uint32_t reg, size_t instr)
{
BNRegisterValue value = BNGetMediumLevelILRegisterValueAtInstruction(m_object, reg, instr);
return RegisterValue::FromAPIObject(value);
}
RegisterValue MediumLevelILFunction::GetRegisterValueAfterInstruction(uint32_t reg, size_t instr)
{
BNRegisterValue value = BNGetMediumLevelILRegisterValueAfterInstruction(m_object, reg, instr);
return RegisterValue::FromAPIObject(value);
}
PossibleValueSet MediumLevelILFunction::GetPossibleRegisterValuesAtInstruction(
uint32_t reg, size_t instr, const set& options)
{
BNDataFlowQueryOption* optionArray = new BNDataFlowQueryOption[options.size()];
size_t idx = 0;
for (auto i : options)
optionArray[idx++] = i;
BNPossibleValueSet value =
BNGetMediumLevelILPossibleRegisterValuesAtInstruction(m_object, reg, instr, optionArray, options.size());
delete[] optionArray;
return PossibleValueSet::FromAPIObject(value);
}
PossibleValueSet MediumLevelILFunction::GetPossibleRegisterValuesAfterInstruction(
uint32_t reg, size_t instr, const set& options)
{
BNDataFlowQueryOption* optionArray = new BNDataFlowQueryOption[options.size()];
size_t idx = 0;
for (auto i : options)
optionArray[idx++] = i;
BNPossibleValueSet value =
BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(m_object, reg, instr, optionArray, options.size());
delete[] optionArray;
return PossibleValueSet::FromAPIObject(value);
}
RegisterValue MediumLevelILFunction::GetFlagValueAtInstruction(uint32_t flag, size_t instr)
{
BNRegisterValue value = BNGetMediumLevelILFlagValueAtInstruction(m_object, flag, instr);
return RegisterValue::FromAPIObject(value);
}
RegisterValue MediumLevelILFunction::GetFlagValueAfterInstruction(uint32_t flag, size_t instr)
{
BNRegisterValue value = BNGetMediumLevelILFlagValueAfterInstruction(m_object, flag, instr);
return RegisterValue::FromAPIObject(value);
}
PossibleValueSet MediumLevelILFunction::GetPossibleFlagValuesAtInstruction(
uint32_t flag, size_t instr, const set& options)
{
BNDataFlowQueryOption* optionArray = new BNDataFlowQueryOption[options.size()];
size_t idx = 0;
for (auto i : options)
optionArray[idx++] = i;
BNPossibleValueSet value =
BNGetMediumLevelILPossibleFlagValuesAtInstruction(m_object, flag, instr, optionArray, options.size());
delete[] optionArray;
return PossibleValueSet::FromAPIObject(value);
}
PossibleValueSet MediumLevelILFunction::GetPossibleFlagValuesAfterInstruction(
uint32_t flag, size_t instr, const set& options)
{
BNDataFlowQueryOption* optionArray = new BNDataFlowQueryOption[options.size()];
size_t idx = 0;
for (auto i : options)
optionArray[idx++] = i;
BNPossibleValueSet value =
BNGetMediumLevelILPossibleFlagValuesAfterInstruction(m_object, flag, instr, optionArray, options.size());
delete[] optionArray;
return PossibleValueSet::FromAPIObject(value);
}
RegisterValue MediumLevelILFunction::GetStackContentsAtInstruction(int32_t offset, size_t len, size_t instr)
{
BNRegisterValue value = BNGetMediumLevelILStackContentsAtInstruction(m_object, offset, len, instr);
return RegisterValue::FromAPIObject(value);
}
RegisterValue MediumLevelILFunction::GetStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr)
{
BNRegisterValue value = BNGetMediumLevelILStackContentsAfterInstruction(m_object, offset, len, instr);
return RegisterValue::FromAPIObject(value);
}
PossibleValueSet MediumLevelILFunction::GetPossibleStackContentsAtInstruction(
int32_t offset, size_t len, size_t instr, const set& options)
{
BNDataFlowQueryOption* optionArray = new BNDataFlowQueryOption[options.size()];
size_t idx = 0;
for (auto i : options)
optionArray[idx++] = i;
BNPossibleValueSet value =
BNGetMediumLevelILPossibleStackContentsAtInstruction(m_object, offset, len, instr, optionArray, options.size());
delete[] optionArray;
return PossibleValueSet::FromAPIObject(value);
}
PossibleValueSet MediumLevelILFunction::GetPossibleStackContentsAfterInstruction(
int32_t offset, size_t len, size_t instr, const set& options)
{
BNDataFlowQueryOption* optionArray = new BNDataFlowQueryOption[options.size()];
size_t idx = 0;
for (auto i : options)
optionArray[idx++] = i;
BNPossibleValueSet value = BNGetMediumLevelILPossibleStackContentsAfterInstruction(
m_object, offset, len, instr, optionArray, options.size());
delete[] optionArray;
return PossibleValueSet::FromAPIObject(value);
}
BNILBranchDependence MediumLevelILFunction::GetBranchDependenceAtInstruction(size_t curInstr, size_t branchInstr) const
{
return BNGetMediumLevelILBranchDependence(m_object, curInstr, branchInstr);
}
unordered_map MediumLevelILFunction::GetAllBranchDependenceAtInstruction(
size_t instr) const
{
size_t count;
BNILBranchInstructionAndDependence* deps = BNGetAllMediumLevelILBranchDependence(m_object, instr, &count);
unordered_map result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result[deps[i].branch] = deps[i].dependence;
BNFreeILBranchDependenceList(deps);
return result;
}
Ref MediumLevelILFunction::GetLowLevelIL() const
{
BNLowLevelILFunction* func = BNGetLowLevelILForMediumLevelIL(m_object);
if (!func)
return nullptr;
return new LowLevelILFunction(func);
}
size_t MediumLevelILFunction::GetLowLevelILInstructionIndex(size_t instr) const
{
return BNGetLowLevelILInstructionIndex(m_object, instr);
}
size_t MediumLevelILFunction::GetLowLevelILExprIndex(size_t expr) const
{
return BNGetLowLevelILExprIndex(m_object, expr);
}
set MediumLevelILFunction::GetLowLevelILExprIndexes(size_t expr) const
{
size_t count;
size_t* exprs = BNGetLowLevelILExprIndexes(m_object, expr, &count);
set result;
for (size_t i = 0; i < count; i++)
result.insert(exprs[i]);
BNFreeILInstructionList(exprs);
return result;
}
Ref MediumLevelILFunction::GetHighLevelIL() const
{
BNHighLevelILFunction* func = BNGetHighLevelILForMediumLevelIL(m_object);
if (!func)
return nullptr;
return new HighLevelILFunction(func);
}
size_t MediumLevelILFunction::GetHighLevelILInstructionIndex(size_t instr) const
{
return BNGetHighLevelILInstructionIndex(m_object, instr);
}
size_t MediumLevelILFunction::GetHighLevelILExprIndex(size_t expr) const
{
return BNGetHighLevelILExprIndex(m_object, expr);
}
set MediumLevelILFunction::GetHighLevelILExprIndexes(size_t expr) const
{
size_t count;
size_t* exprs = BNGetHighLevelILExprIndexes(m_object, expr, &count);
set result;
for (size_t i = 0; i < count; i++)
result.insert(exprs[i]);
BNFreeILInstructionList(exprs);
return result;
}
Confidence][> MediumLevelILFunction::GetExprType(size_t expr)
{
BNTypeWithConfidence result = BNGetMediumLevelILExprType(m_object, expr);
if (!result.type)
return nullptr;
return Confidence][>(new Type(result.type), result.confidence);
}
Confidence][> MediumLevelILFunction::GetExprType(const MediumLevelILInstruction& expr)
{
return GetExprType(expr.exprIndex);
}
void MediumLevelILFunction::SetExprType(size_t expr, const Confidence][>& type)
{
BNTypeWithConfidence tc;
tc.type = type->GetObject();
tc.confidence = type.GetConfidence();
BNSetMediumLevelILExprType(m_object, expr, &tc);
}
void MediumLevelILFunction::SetExprType(const BinaryNinja::MediumLevelILInstruction& expr,
const Confidence][>& type)
{
SetExprType(expr.exprIndex, type);
}
Ref MediumLevelILFunction::CreateFunctionGraph(DisassemblySettings* settings)
{
BNFlowGraph* graph = BNCreateMediumLevelILFunctionGraph(m_object, settings ? settings->GetObject() : nullptr);
return new CoreFlowGraph(graph);
}
set MediumLevelILFunction::GetLiveInstructionsForVariable(const Variable& var, bool includeLastUse)
{
size_t count;
size_t* instrs = BNGetMediumLevelILLiveInstructionsForVariable(m_object, &var, includeLastUse, &count);
set result;
for (size_t i = 0; i < count; i++)
result.insert(instrs[i]);
BNFreeILInstructionList(instrs);
return result;
}
Variable MediumLevelILFunction::GetSplitVariableForDefinition(const Variable& var, size_t instrIndex)
{
return Variable(
var.type, BNGetDefaultIndexForMediumLevelILVariableDefinition(m_object, &var, instrIndex), var.storage);
}
]