summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/veridex/flow_analysis.cc37
-rw-r--r--tools/veridex/hidden_api_finder.cc9
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());