diff options
-rw-r--r-- | tools/veridex/flow_analysis.cc | 37 | ||||
-rw-r--r-- | tools/veridex/hidden_api_finder.cc | 9 |
2 files changed, 38 insertions, 8 deletions
diff --git a/tools/veridex/flow_analysis.cc b/tools/veridex/flow_analysis.cc index 65f236325e..2a8b8a0522 100644 --- a/tools/veridex/flow_analysis.cc +++ b/tools/veridex/flow_analysis.cc @@ -47,6 +47,9 @@ bool VeriFlowAnalysis::IsBranchTarget(uint32_t dex_pc) { } bool VeriFlowAnalysis::MergeRegisterValues(uint32_t dex_pc) { + if (dex_pc >= code_item_accessor_.InsnsSizeInCodeUnits()) { + return false; + } // TODO: Do the merging. Right now, just return that we should continue // the iteration if the instruction has not been visited. if (!instruction_infos_[dex_pc].has_been_visited) { @@ -85,9 +88,14 @@ void VeriFlowAnalysis::FindBranches() { } // Iterate over all instructions and find branching instructions. + const uint32_t max_pc = code_item_accessor_.InsnsSizeInCodeUnits(); for (const DexInstructionPcPair& pair : code_item_accessor_) { const uint32_t dex_pc = pair.DexPc(); const Instruction& instruction = pair.Inst(); + if (dex_pc >= max_pc) { + // We need to prevent abnormal access for outside of code + break; + } if (instruction.IsBranch()) { SetAsBranchTarget(dex_pc + instruction.GetTargetOffset()); @@ -107,22 +115,32 @@ void VeriFlowAnalysis::UpdateRegister(uint32_t dex_register, RegisterSource kind, VeriClass* cls, uint32_t source_id) { - current_registers_[dex_register] = RegisterValue( - kind, DexFileReference(&resolver_->GetDexFile(), source_id), cls); + // veridex doesn't do any code verification, so it can be that there are bogus dex + // instructions that update a non-existent register. + if (dex_register < current_registers_.size()) { + current_registers_[dex_register] = RegisterValue( + kind, DexFileReference(&resolver_->GetDexFile(), source_id), cls); + } } void VeriFlowAnalysis::UpdateRegister(uint32_t dex_register, const RegisterValue& value) { - current_registers_[dex_register] = value; + if (dex_register < current_registers_.size()) { + current_registers_[dex_register] = value; + } } void VeriFlowAnalysis::UpdateRegister(uint32_t dex_register, const VeriClass* cls) { - current_registers_[dex_register] = - RegisterValue(RegisterSource::kNone, DexFileReference(nullptr, 0), cls); + if (dex_register < current_registers_.size()) { + current_registers_[dex_register] = + RegisterValue(RegisterSource::kNone, DexFileReference(nullptr, 0), cls); + } } void VeriFlowAnalysis::UpdateRegister(uint32_t dex_register, int32_t value, const VeriClass* cls) { - current_registers_[dex_register] = - RegisterValue(RegisterSource::kConstant, value, DexFileReference(nullptr, 0), cls); + if (dex_register < current_registers_.size()) { + current_registers_[dex_register] = + RegisterValue(RegisterSource::kConstant, value, DexFileReference(nullptr, 0), cls); + } } const RegisterValue& VeriFlowAnalysis::GetRegister(uint32_t dex_register) const { @@ -199,7 +217,12 @@ void VeriFlowAnalysis::AnalyzeCode() { work_list.pop_back(); CHECK(IsBranchTarget(dex_pc)); current_registers_ = *dex_registers_[dex_pc].get(); + const uint32_t max_pc = code_item_accessor_.InsnsSizeInCodeUnits(); while (true) { + if (dex_pc >= max_pc) { + // We need to prevent abnormal access for outside of code + break; + } const uint16_t* insns = code_item_accessor_.Insns() + dex_pc; const Instruction& inst = *Instruction::At(insns); ProcessDexInstruction(inst); diff --git a/tools/veridex/hidden_api_finder.cc b/tools/veridex/hidden_api_finder.cc index e740cf4cbf..6a5c82e49d 100644 --- a/tools/veridex/hidden_api_finder.cc +++ b/tools/veridex/hidden_api_finder.cc @@ -61,7 +61,14 @@ void HiddenApiFinder::CollectAccesses(VeridexResolver* resolver, for (ClassAccessor accessor : dex_file.GetClasses()) { if (class_filter.Matches(accessor.GetDescriptor())) { for (const ClassAccessor::Method& method : accessor.GetMethods()) { - for (const DexInstructionPcPair& inst : method.GetInstructions()) { + CodeItemInstructionAccessor codes = method.GetInstructions(); + const uint32_t max_pc = codes.InsnsSizeInCodeUnits(); + for (const DexInstructionPcPair& inst : codes) { + if (inst.DexPc() >= max_pc) { + // We need to prevent abnormal access for outside of code + break; + } + switch (inst->Opcode()) { case Instruction::CONST_STRING: { dex::StringIndex string_index(inst->VRegB_21c()); |