diff options
| author | Rusty Wagner <rusty@vector35.com> | 2017-11-27 17:15:03 -0500 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2017-11-27 17:15:03 -0500 |
| commit | c24b1bd108ee2885d7164cecd15f75aa1715a8df (patch) | |
| tree | 29dd59ac7c2ad4d7d77d36c89dd5f26ab270ea6e /lowlevelilinstruction.cpp | |
| parent | d5db0ddb807265b295bb6b4ff07613776945c92b (diff) | |
Register stack adjustments in calling conventions
Diffstat (limited to 'lowlevelilinstruction.cpp')
| -rw-r--r-- | lowlevelilinstruction.cpp | 172 |
1 files changed, 150 insertions, 22 deletions
diff --git a/lowlevelilinstruction.cpp b/lowlevelilinstruction.cpp index 91af36b1..8259426a 100644 --- a/lowlevelilinstruction.cpp +++ b/lowlevelilinstruction.cpp @@ -74,12 +74,13 @@ unordered_map<LowLevelILOperandUsage, LowLevelILOperandType> {FlagConditionLowLevelOperandUsage, FlagConditionLowLevelOperand}, {OutputSSARegistersLowLevelOperandUsage, SSARegisterListLowLevelOperand}, {OutputMemoryVersionLowLevelOperandUsage, IndexLowLevelOperand}, - {ParameterSSARegistersLowLevelOperandUsage, SSARegisterListLowLevelOperand}, + {ParameterExprsLowLevelOperandUsage, ExprListLowLevelOperand}, {SourceSSARegistersLowLevelOperandUsage, SSARegisterListLowLevelOperand}, {SourceSSARegisterStacksLowLevelOperandUsage, SSARegisterStackListLowLevelOperand}, {SourceSSAFlagsLowLevelOperandUsage, SSAFlagListLowLevelOperand}, {SourceMemoryVersionsLowLevelOperandUsage, IndexListLowLevelOperand}, - {TargetListLowLevelOperandUsage, IndexListLowLevelOperand} + {TargetListLowLevelOperandUsage, IndexListLowLevelOperand}, + {RegisterStackAdjustmentsLowLevelOperandUsage, RegisterStackAdjustmentsLowLevelOperand} }; @@ -133,7 +134,8 @@ unordered_map<BNLowLevelILOperation, vector<LowLevelILOperandUsage>> {LLIL_JUMP, {DestExprLowLevelOperandUsage}}, {LLIL_JUMP_TO, {DestExprLowLevelOperandUsage, TargetListLowLevelOperandUsage}}, {LLIL_CALL, {DestExprLowLevelOperandUsage}}, - {LLIL_CALL_STACK_ADJUST, {DestExprLowLevelOperandUsage, StackAdjustmentLowLevelOperandUsage}}, + {LLIL_CALL_STACK_ADJUST, {DestExprLowLevelOperandUsage, StackAdjustmentLowLevelOperandUsage, + RegisterStackAdjustmentsLowLevelOperandUsage}}, {LLIL_RET, {DestExprLowLevelOperandUsage}}, {LLIL_IF, {ConditionExprLowLevelOperandUsage, TrueTargetLowLevelOperandUsage, FalseTargetLowLevelOperandUsage}}, @@ -142,10 +144,10 @@ unordered_map<BNLowLevelILOperation, vector<LowLevelILOperandUsage>> {LLIL_TRAP, {VectorLowLevelOperandUsage}}, {LLIL_CALL_SSA, {OutputSSARegistersLowLevelOperandUsage, OutputMemoryVersionLowLevelOperandUsage, DestExprLowLevelOperandUsage, StackSSARegisterLowLevelOperandUsage, - StackMemoryVersionLowLevelOperandUsage, ParameterSSARegistersLowLevelOperandUsage}}, + StackMemoryVersionLowLevelOperandUsage, ParameterExprsLowLevelOperandUsage}}, {LLIL_SYSCALL_SSA, {OutputSSARegistersLowLevelOperandUsage, OutputMemoryVersionLowLevelOperandUsage, StackSSARegisterLowLevelOperandUsage, StackMemoryVersionLowLevelOperandUsage, - ParameterSSARegistersLowLevelOperandUsage}}, + ParameterExprsLowLevelOperandUsage}}, {LLIL_REG_PHI, {DestSSARegisterLowLevelOperandUsage, SourceSSARegistersLowLevelOperandUsage}}, {LLIL_REG_STACK_PHI, {DestSSARegisterStackLowLevelOperandUsage, SourceSSARegisterStacksLowLevelOperandUsage}}, {LLIL_FLAG_PHI, {DestSSAFlagLowLevelOperandUsage, SourceSSAFlagsLowLevelOperandUsage}}, @@ -239,7 +241,7 @@ static unordered_map<BNLowLevelILOperation, unordered_map<LowLevelILOperandUsage // Represented as subexpression, so only takes one slot even though it is an SSA register operand++; break; - case ParameterSSARegistersLowLevelOperandUsage: + case ParameterExprsLowLevelOperandUsage: // Represented as subexpression, so only takes one slot even though it is a list operand++; break; @@ -262,6 +264,7 @@ static unordered_map<BNLowLevelILOperation, unordered_map<LowLevelILOperandUsage case SSARegisterListLowLevelOperand: case SSARegisterStackListLowLevelOperand: case SSAFlagListLowLevelOperand: + case RegisterStackAdjustmentsLowLevelOperand: // SSA registers/flags and lists take two operand slots operand += 2; break; @@ -580,6 +583,64 @@ LowLevelILIndexList::operator vector<size_t>() const } +const LowLevelILInstruction LowLevelILInstructionList::ListIterator::operator*() +{ + return LowLevelILInstruction(pos.GetFunction(), pos.GetFunction()->GetRawExpr((size_t)*pos), + (size_t)*pos, instructionIndex); +} + + +LowLevelILInstructionList::LowLevelILInstructionList(LowLevelILFunction* func, + const BNLowLevelILInstruction& instr, size_t count, size_t instrIndex): + m_list(func, instr, count), m_instructionIndex(instrIndex) +{ +} + + +LowLevelILInstructionList::const_iterator LowLevelILInstructionList::begin() const +{ + const_iterator result; + result.pos = m_list.begin(); + result.instructionIndex = m_instructionIndex; + return result; +} + + +LowLevelILInstructionList::const_iterator LowLevelILInstructionList::end() const +{ + const_iterator result; + result.pos = m_list.end(); + result.instructionIndex = m_instructionIndex; + return result; +} + + +size_t LowLevelILInstructionList::size() const +{ + return m_list.size(); +} + + +const LowLevelILInstruction LowLevelILInstructionList::operator[](size_t i) const +{ + if (i >= size()) + throw LowLevelILInstructionAccessException(); + auto iter = begin(); + for (size_t j = 0; j < i; j++) + ++iter; + return *iter; +} + + +LowLevelILInstructionList::operator vector<LowLevelILInstruction>() const +{ + vector<LowLevelILInstruction> result; + for (auto i : *this) + result.push_back(i); + return result; +} + + const SSARegister LowLevelILSSARegisterList::ListIterator::operator*() { LowLevelILIntegerList::const_iterator cur = pos; @@ -864,14 +925,20 @@ LowLevelILIndexList LowLevelILOperand::GetIndexList() const } +LowLevelILInstructionList LowLevelILOperand::GetExprList() const +{ + if (m_type != ExprListLowLevelOperand) + throw LowLevelILInstructionAccessException(); + return m_instr.GetRawOperandAsExpr(m_operandIndex).GetRawOperandAsExprList(0); +} + + LowLevelILSSARegisterList LowLevelILOperand::GetSSARegisterList() const { if (m_type != SSARegisterListLowLevelOperand) throw LowLevelILInstructionAccessException(); if (m_usage == OutputSSARegistersLowLevelOperandUsage) return m_instr.GetRawOperandAsExpr(m_operandIndex).GetRawOperandAsSSARegisterList(1); - if (m_usage == ParameterSSARegistersLowLevelOperandUsage) - return m_instr.GetRawOperandAsExpr(m_operandIndex).GetRawOperandAsSSARegisterList(0); return m_instr.GetRawOperandAsSSARegisterList(m_operandIndex); } @@ -892,6 +959,14 @@ LowLevelILSSAFlagList LowLevelILOperand::GetSSAFlagList() const } +map<uint32_t, int32_t> LowLevelILOperand::GetRegisterStackAdjustments() const +{ + if (m_type != RegisterStackAdjustmentsLowLevelOperand) + throw LowLevelILInstructionAccessException(); + return m_instr.GetRawOperandAsRegisterStackAdjustments(m_operandIndex); +} + + const LowLevelILOperand LowLevelILOperandList::ListIterator::operator*() { LowLevelILOperandUsage usage = *pos; @@ -1073,6 +1148,13 @@ LowLevelILIndexList LowLevelILInstructionBase::GetRawOperandAsIndexList(size_t o } +LowLevelILInstructionList LowLevelILInstructionBase::GetRawOperandAsExprList(size_t operand) const +{ + return LowLevelILInstructionList(function, function->GetRawExpr(operands[operand + 1]), operands[operand], + instructionIndex); +} + + LowLevelILSSARegisterList LowLevelILInstructionBase::GetRawOperandAsSSARegisterList(size_t operand) const { return LowLevelILSSARegisterList(function, function->GetRawExpr(operands[operand + 1]), operands[operand]); @@ -1091,6 +1173,24 @@ LowLevelILSSAFlagList LowLevelILInstructionBase::GetRawOperandAsSSAFlagList(size } +map<uint32_t, int32_t> LowLevelILInstructionBase::GetRawOperandAsRegisterStackAdjustments(size_t operand) const +{ + LowLevelILIntegerList list(function, function->GetRawExpr(operands[operand + 1]), operands[operand]); + map<uint32_t, int32_t> result; + for (auto i = list.begin(); i != list.end(); ) + { + uint32_t regStack = (uint32_t)*i; + ++i; + if (i == list.end()) + break; + int32_t adjust = (int32_t)*i; + ++i; + result[regStack] = adjust; + } + return result; +} + + void LowLevelILInstructionBase::UpdateRawOperand(size_t operandIndex, ExprId value) { operands[operandIndex] = value; @@ -1385,6 +1485,12 @@ void LowLevelILInstruction::VisitExprs(const std::function<bool(const LowLevelIL break; case LLIL_CALL_SSA: GetDestExpr<LLIL_CALL_SSA>().VisitExprs(func); + for (auto& i : GetParameterExprs<LLIL_CALL_SSA>()) + i.VisitExprs(func); + break; + case LLIL_SYSCALL_SSA: + for (auto& i : GetParameterExprs<LLIL_CALL_SSA>()) + i.VisitExprs(func); break; case LLIL_RET: GetDestExpr<LLIL_RET>().VisitExprs(func); @@ -1478,6 +1584,7 @@ ExprId LowLevelILInstruction::CopyTo(LowLevelILFunction* dest, const std::function<ExprId(const LowLevelILInstruction& subExpr)>& subExprHandler) const { vector<BNLowLevelILLabel*> labelList; + vector<ExprId> params; BNLowLevelILLabel* labelA; BNLowLevelILLabel* labelB; switch (operation) @@ -1576,7 +1683,7 @@ ExprId LowLevelILInstruction::CopyTo(LowLevelILFunction* dest, return dest->Call(subExprHandler(GetDestExpr<LLIL_CALL>()), *this); case LLIL_CALL_STACK_ADJUST: return dest->CallStackAdjust(subExprHandler(GetDestExpr<LLIL_CALL_STACK_ADJUST>()), - GetStackAdjustment<LLIL_CALL_STACK_ADJUST>(), *this); + GetStackAdjustment<LLIL_CALL_STACK_ADJUST>(), GetRegisterStackAdjustments<LLIL_CALL_STACK_ADJUST>(), *this); case LLIL_RET: return dest->Return(subExprHandler(GetDestExpr<LLIL_RET>()), *this); case LLIL_JUMP_TO: @@ -1607,13 +1714,17 @@ ExprId LowLevelILInstruction::CopyTo(LowLevelILFunction* dest, case LLIL_TRAP: return dest->Trap(GetVector<LLIL_TRAP>(), *this); case LLIL_CALL_SSA: + for (auto& i : GetParameterExprs<LLIL_CALL_SSA>()) + params.push_back(subExprHandler(i)); return dest->CallSSA(GetOutputSSARegisters<LLIL_CALL_SSA>(), subExprHandler(GetDestExpr<LLIL_CALL_SSA>()), - GetParameterSSARegisters<LLIL_CALL_SSA>(), GetStackSSARegister<LLIL_CALL_SSA>(), - GetDestMemoryVersion<LLIL_CALL_SSA>(), GetSourceMemoryVersion<LLIL_CALL_SSA>(), *this); + params, GetStackSSARegister<LLIL_CALL_SSA>(), GetDestMemoryVersion<LLIL_CALL_SSA>(), + GetSourceMemoryVersion<LLIL_CALL_SSA>(), *this); case LLIL_SYSCALL_SSA: + for (auto& i : GetParameterExprs<LLIL_SYSCALL_SSA>()) + params.push_back(subExprHandler(i)); return dest->SystemCallSSA(GetOutputSSARegisters<LLIL_SYSCALL_SSA>(), - GetParameterSSARegisters<LLIL_SYSCALL_SSA>(), GetStackSSARegister<LLIL_SYSCALL_SSA>(), - GetDestMemoryVersion<LLIL_SYSCALL_SSA>(), GetSourceMemoryVersion<LLIL_SYSCALL_SSA>(), *this); + params, GetStackSSARegister<LLIL_SYSCALL_SSA>(), GetDestMemoryVersion<LLIL_SYSCALL_SSA>(), + GetSourceMemoryVersion<LLIL_SYSCALL_SSA>(), *this); case LLIL_REG_PHI: return dest->RegisterPhi(GetDestSSARegister<LLIL_REG_PHI>(), GetSourceSSARegisters<LLIL_REG_PHI>(), *this); case LLIL_REG_STACK_PHI: @@ -2055,11 +2166,11 @@ LowLevelILSSARegisterList LowLevelILInstruction::GetOutputSSARegisters() const } -LowLevelILSSARegisterList LowLevelILInstruction::GetParameterSSARegisters() const +LowLevelILInstructionList LowLevelILInstruction::GetParameterExprs() const { size_t operandIndex; - if (GetOperandIndexForUsage(ParameterSSARegistersLowLevelOperandUsage, operandIndex)) - return GetRawOperandAsExpr(operandIndex).GetRawOperandAsSSARegisterList(0); + if (GetOperandIndexForUsage(ParameterExprsLowLevelOperandUsage, operandIndex)) + return GetRawOperandAsExpr(operandIndex).GetRawOperandAsExprList(0); throw LowLevelILInstructionAccessException(); } @@ -2109,6 +2220,15 @@ LowLevelILIndexList LowLevelILInstruction::GetTargetList() const } +map<uint32_t, int32_t> LowLevelILInstruction::GetRegisterStackAdjustments() const +{ + size_t operandIndex; + if (GetOperandIndexForUsage(RegisterStackAdjustmentsLowLevelOperandUsage, operandIndex)) + return GetRawOperandAsRegisterStackAdjustments(operandIndex); + throw LowLevelILInstructionAccessException(); +} + + ExprId LowLevelILFunction::Nop(const ILSourceLocation& loc) { return AddExprWithLocation(LLIL_NOP, loc, 0, 0); @@ -2578,13 +2698,21 @@ ExprId LowLevelILFunction::Call(ExprId dest, const ILSourceLocation& loc) } -ExprId LowLevelILFunction::CallStackAdjust(ExprId dest, size_t adjust, const ILSourceLocation& loc) +ExprId LowLevelILFunction::CallStackAdjust(ExprId dest, size_t adjust, + const std::map<uint32_t, int32_t>& regStackAdjust, const ILSourceLocation& loc) { - return AddExprWithLocation(LLIL_CALL_STACK_ADJUST, loc, 0, 0, dest, adjust); + vector<size_t> list; + for (auto& i : regStackAdjust) + { + list.push_back(i.first); + list.push_back(i.second); + } + return AddExprWithLocation(LLIL_CALL_STACK_ADJUST, loc, 0, 0, dest, adjust, list.size(), + AddIndexList(list)); } -ExprId LowLevelILFunction::CallSSA(const vector<SSARegister>& output, ExprId dest, const vector<SSARegister>& params, +ExprId LowLevelILFunction::CallSSA(const vector<SSARegister>& output, ExprId dest, const vector<ExprId>& params, const SSARegister& stack, size_t newMemoryVer, size_t prevMemoryVer, const ILSourceLocation& loc) { return AddExprWithLocation(LLIL_CALL_SSA, loc, 0, 0, @@ -2592,11 +2720,11 @@ ExprId LowLevelILFunction::CallSSA(const vector<SSARegister>& output, ExprId des output.size() * 2, AddSSARegisterList(output)), dest, AddExprWithLocation(LLIL_CALL_STACK_SSA, loc, 0, 0, stack.reg, stack.version, prevMemoryVer), AddExprWithLocation(LLIL_CALL_PARAM_SSA, loc, 0, 0, - params.size() * 2, AddSSARegisterList(params))); + params.size(), AddOperandList(params))); } -ExprId LowLevelILFunction::SystemCallSSA(const vector<SSARegister>& output, const vector<SSARegister>& params, +ExprId LowLevelILFunction::SystemCallSSA(const vector<SSARegister>& output, const vector<ExprId>& params, const SSARegister& stack, size_t newMemoryVer, size_t prevMemoryVer, const ILSourceLocation& loc) { return AddExprWithLocation(LLIL_SYSCALL_SSA, loc, 0, 0, @@ -2604,7 +2732,7 @@ ExprId LowLevelILFunction::SystemCallSSA(const vector<SSARegister>& output, cons output.size() * 2, AddSSARegisterList(output)), AddExprWithLocation(LLIL_CALL_STACK_SSA, loc, 0, 0, stack.reg, stack.version, prevMemoryVer), AddExprWithLocation(LLIL_CALL_PARAM_SSA, loc, 0, 0, - params.size() * 2, AddSSARegisterList(params))); + params.size(), AddOperandList(params))); } |
