From e9ac835fa0ab48eda53056e1bec00dd6535a5e06 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Sat, 26 Oct 2019 16:51:11 +0200 Subject: [PATCH] Updating repositories and working on constants analysis --- WORKSPACE | 13 ++++++++- analysis/constants_analysis.cpp | 13 +++++++-- disassembler/aarch64/find_functions.cpp | 4 +-- disassembler/main.cpp | 6 ++-- disassembler/resolve_branches.cpp | 38 +++++++++++++------------ flow_graph/flow_graph.cpp | 2 +- flow_graph/instruction_provider.cpp | 3 ++ flow_graph/native_flow_graph.cpp | 13 +++++---- flow_graph/native_flow_graph.h | 4 +-- memory_image/memory_image.cpp | 2 +- repositories.bzl | 30 ++++++++++++++++--- 11 files changed, 89 insertions(+), 39 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 37d0904..ca7b6e4 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -16,5 +16,16 @@ workspace(name = "reil") local_repository(name = 'reil_rules', path = '.') load("@reil_rules//:repositories.bzl", "reil_repositories") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -reil_repositories() \ No newline at end of file +http_archive( + name = "com_google_protobuf", + sha256 = "758249b537abba2f21ebc2d02555bf080917f0f2f88f4cbe2903e0e28c4187ed", + strip_prefix = "protobuf-3.10.0", + urls = ["https://github.com/google/protobuf/archive/v3.10.0.tar.gz"] +) + +load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") +protobuf_deps() + +reil_repositories() diff --git a/analysis/constants_analysis.cpp b/analysis/constants_analysis.cpp index 47a1d32..702e31c 100644 --- a/analysis/constants_analysis.cpp +++ b/analysis/constants_analysis.cpp @@ -188,6 +188,7 @@ std::shared_ptr ConstantsStateImpl::GetOperandImpl( value = GetTemporaryImpl(absl::get(operand).index); } else if (operand.index() == kRegister) { value = GetRegisterImpl(absl::get(operand).index); + } else if (operand.index() == kOffset) { } else { CHECK(false); } @@ -360,8 +361,8 @@ void ConstantsStateImpl::TransformLdm(const Instruction& ri, auto value = GetOperand(ri.input0); if (value) { uint64_t address = static_cast(*value); - if (memory_image.readable(address, Size(ri.output)) && - !memory_image.writable(address, Size(ri.output))) { + if (memory_image.readable(address, Size(ri.output) / 8) && + memory_image.writable(address, Size(ri.output) / 8)) { SetOperand(ri.output, Immediate(memory_image.Read(address).data(), Size(ri.output) / 8)); } @@ -483,7 +484,6 @@ void ConstantsStateImpl::TransformAshr(const Instruction& ri) { } else { result >>= *rhs; } - std::cerr << result << std::endl; SetOperandImpl(ri.output, std::move(result)); } else { SetOperandImpl(ri.output, nullptr); @@ -868,11 +868,18 @@ void LocalConstantsAnalysisImpl::Update() { queue.erase(queue.begin()); if (node == 0) { + VLOG(4) << "bailed1"; continue; } // compute the input state to the node node = flow_graph->BasicBlockEnd(node); + + if (node == 0) { + VLOG(4) << "bailed2"; + continue; + } + auto in_state = AtImpl(node); // for each out edge, transform the in state to the new out state. diff --git a/disassembler/aarch64/find_functions.cpp b/disassembler/aarch64/find_functions.cpp index df9b6ec..78e38cb 100644 --- a/disassembler/aarch64/find_functions.cpp +++ b/disassembler/aarch64/find_functions.cpp @@ -35,8 +35,8 @@ std::set FindFunctions(const MemoryImage& memory_image) { memcpy(&opcode, &mapping.data[offset], sizeof(opcode)); - VLOG(3) << std::hex << address << ": " << opcode << " " - << reil::aarch64::decoder::DecodeInstruction(address, opcode); + //VLOG(3) << std::hex << address << ": " << opcode << " " + // << reil::aarch64::decoder::DecodeInstruction(address, opcode); if (!pacsp && (opcode & 0b11111111111111111111111110111111) == 0b11010101000000110010001100111111) { diff --git a/disassembler/main.cpp b/disassembler/main.cpp index 284b104..6640041 100644 --- a/disassembler/main.cpp +++ b/disassembler/main.cpp @@ -93,8 +93,6 @@ int main(int argc, char** argv) { queue_lock.unlock(); int resolved = 0; - - std::cout << std::thread::hardware_concurrency() << std::endl; int thread_count = std::thread::hardware_concurrency() / 2; std::vector disassembler_threads; @@ -115,6 +113,10 @@ int main(int argc, char** argv) { << ".cfg"; function_iter.second->Save(path_stream.str()); } + } else { + for (auto& function_iter : functions) { + resolved += function_iter.second->resolved(); + } } functions_lock.unlock(); diff --git a/disassembler/resolve_branches.cpp b/disassembler/resolve_branches.cpp index a38da4c..ed364b5 100644 --- a/disassembler/resolve_branches.cpp +++ b/disassembler/resolve_branches.cpp @@ -52,33 +52,35 @@ bool ResolveBranches(const MemoryImage& memory_image, InstructionProvider& ip, auto value = state->GetOperand(ri.output); if (value) { uint64_t address = static_cast(*value); - VLOG(1) << "resolved " << *ip.NativeInstruction(edge.source.address) - << " [" << std::hex << address << "]"; - if (edge.kind == EdgeKind::kNativeJump) { - nfg.RemoveEdge(edge.source.address, 0, NativeEdgeKind::kJump); - nfg.AddEdge(edge.source.address, address, NativeEdgeKind::kJump); - Disassemble(memory_image, nfg, address); - jump_added = true; - } else if (edge.kind == EdgeKind::kNativeCall) { - nfg.RemoveEdge(edge.source.address, 0, NativeEdgeKind::kCall); - nfg.AddEdge(edge.source.address, address, NativeEdgeKind::kCall); - } else { - LOG(WARNING) << "Unexpected edge resolved: " << edge << " " - << address; + if (address) { + VLOG(0) << "resolved " << *ip.NativeInstruction(edge.source.address) + << " [" << std::hex << address << "]"; + if (edge.kind == EdgeKind::kNativeJump) { + jump_added = nfg.RemoveEdge(edge.source.address, 0, NativeEdgeKind::kJump); + nfg.AddEdge(edge.source.address, address, NativeEdgeKind::kJump); + Disassemble(memory_image, nfg, address); + } else if (edge.kind == EdgeKind::kNativeCall) { + nfg.RemoveEdge(edge.source.address, 0, NativeEdgeKind::kCall); + nfg.AddEdge(edge.source.address, address, NativeEdgeKind::kCall); + } else { + LOG(WARNING) << "Unexpected edge resolved: " << edge << " " + << *ip.NativeInstruction(edge.source.address); + } + } else if (edge.kind != EdgeKind::kNativeReturn) { + resolved = false; } - } else { + } else if (edge.kind != EdgeKind::kNativeReturn) { resolved = false; } } } else { break; } - } while (jump_added && !nfg.resolved()); - if (jump_added) { - return true; - } + VLOG(0) << jump_added << " " << nfg.resolved(); + } while (jump_added && !nfg.resolved()); + VLOG(0) << resolved; return resolved; } diff --git a/flow_graph/flow_graph.cpp b/flow_graph/flow_graph.cpp index ba8eaa6..c252e73 100644 --- a/flow_graph/flow_graph.cpp +++ b/flow_graph/flow_graph.cpp @@ -237,7 +237,7 @@ std::unique_ptr FlowGraph::Create(const MemoryImage& memory_image, Offset offset = absl::get(ri.output); rfg->AddEdge( Edge(node, Node(node.address, offset.offset), EdgeKind::kJump)); - DCHECK(edges.size() == 1); + //DCHECK(edges.size() == 1); } else { // all non-local jcc instructions should have a hint. DCHECK(ri.input1.index() == kImmediate); diff --git a/flow_graph/instruction_provider.cpp b/flow_graph/instruction_provider.cpp index f2737fe..8595f83 100644 --- a/flow_graph/instruction_provider.cpp +++ b/flow_graph/instruction_provider.cpp @@ -64,6 +64,9 @@ Node InstructionProvider::NextInstruction(const Node& node) { reil::Instruction InstructionProvider::Instruction(const Node& node) { auto ni = NativeInstruction(node.address); + if (ni == nullptr) { + LOG(ERROR) << node; + } DCHECK(node.offset < ni->reil.size()); return ni->reil[node.offset]; } diff --git a/flow_graph/native_flow_graph.cpp b/flow_graph/native_flow_graph.cpp index b9f49cd..e846c83 100644 --- a/flow_graph/native_flow_graph.cpp +++ b/flow_graph/native_flow_graph.cpp @@ -37,11 +37,12 @@ void NativeFlowGraph::AddEdge(uint64_t source, uint64_t target, AddEdge(NativeEdge(source, target, kind)); } -void NativeFlowGraph::RemoveEdge(const NativeEdge& edge) { +bool NativeFlowGraph::RemoveEdge(const NativeEdge& edge) { VLOG(1) << "remove " << edge; + bool found = false; auto out_edge_iter = outgoing_edges_.find(edge.source); if (out_edge_iter != outgoing_edges_.end()) { - out_edge_iter->second.erase(edge); + found |= out_edge_iter->second.erase(edge); if (out_edge_iter->second.empty()) { outgoing_edges_.erase(out_edge_iter); } @@ -49,16 +50,18 @@ void NativeFlowGraph::RemoveEdge(const NativeEdge& edge) { auto in_edge_iter = incoming_edges_.find(edge.target); if (in_edge_iter != incoming_edges_.end()) { - in_edge_iter->second.erase(edge); + found |= in_edge_iter->second.erase(edge); if (in_edge_iter->second.empty()) { incoming_edges_.erase(in_edge_iter); } } + + return found; } -void NativeFlowGraph::RemoveEdge(uint64_t source, uint64_t target, +bool NativeFlowGraph::RemoveEdge(uint64_t source, uint64_t target, NativeEdgeKind kind) { - RemoveEdge(NativeEdge(source, target, kind)); + return RemoveEdge(NativeEdge(source, target, kind)); } bool NativeFlowGraph::resolved() const { diff --git a/flow_graph/native_flow_graph.h b/flow_graph/native_flow_graph.h index 6cb02fd..5886a32 100644 --- a/flow_graph/native_flow_graph.h +++ b/flow_graph/native_flow_graph.h @@ -31,8 +31,8 @@ class NativeFlowGraph { void AddEdge(const NativeEdge& edge); void AddEdge(uint64_t source, uint64_t target, NativeEdgeKind kind); - void RemoveEdge(const NativeEdge& edge); - void RemoveEdge(uint64_t source, uint64_t target, NativeEdgeKind kind); + bool RemoveEdge(const NativeEdge& edge); + bool RemoveEdge(uint64_t source, uint64_t target, NativeEdgeKind kind); bool resolved() const; diff --git a/memory_image/memory_image.cpp b/memory_image/memory_image.cpp index 4b41048..9bef45b 100644 --- a/memory_image/memory_image.cpp +++ b/memory_image/memory_image.cpp @@ -54,7 +54,7 @@ bool MemoryImage::AccessOk(uint64_t address, uint64_t size, bool read, } if (found) { - return read == readable && write == writable && execute == executable; + return (read == readable) && (write == writable) && (execute == executable); } return false; diff --git a/repositories.bzl b/repositories.bzl index f8b9934..2ad04bd 100644 --- a/repositories.bzl +++ b/repositories.bzl @@ -17,6 +17,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") def reil_repositories( + omit_bazel_skylib=False, + omit_rules_python=False, omit_com_google_abseil=False, omit_com_github_gflags_gflags=False, omit_com_google_binexport=False, @@ -24,6 +26,10 @@ def reil_repositories( omit_com_google_googletest=False, omit_com_google_protobuf=False): + if not omit_bazel_skylib: + bazel_skylib() + if not omit_rules_python: + rules_python() if not omit_com_google_abseil: com_google_abseil() if not omit_com_github_gflags_gflags: @@ -37,6 +43,22 @@ def reil_repositories( if not omit_com_google_protobuf: com_google_protobuf() +def bazel_skylib(): + http_archive( + name = "bazel_skylib", + sha256 = "839ee2a0ee5b728b7af73eac87b5e207ed2c8651b7bcf7c6142cdf4dd1ea738b", + strip_prefix = "bazel-skylib-e59b620b392a8ebbcf25879fc3fde52b4dc77535", + urls = ["https://github.com/bazelbuild/bazel-skylib/archive/e59b620b392a8ebbcf25879fc3fde52b4dc77535.tar.gz"] + ) + +def rules_python(): + http_archive( + name = "rules_python", + sha256 = "e220053c4454664c09628ffbb33f245e65f5fe92eb285fbd0bc3a26f173f99d0", + strip_prefix = "rules_python-5aa465d5d91f1d9d90cac10624e3d2faf2057bd5", + urls = ["https://github.com/bazelbuild/rules_python/archive/5aa465d5d91f1d9d90cac10624e3d2faf2057bd5.tar.gz"] + ) + def com_google_abseil(): http_archive( name = "com_google_abseil", @@ -81,7 +103,7 @@ def com_google_googletest(): def com_google_protobuf(): http_archive( name = "com_google_protobuf", - sha256 = "cef7f1b5a7c5fba672bec2a319246e8feba471f04dcebfe362d55930ee7c1c30", - strip_prefix = "protobuf-3.5.0", - urls = ["https://github.com/google/protobuf/archive/v3.5.0.zip"] - ) + sha256 = "758249b537abba2f21ebc2d02555bf080917f0f2f88f4cbe2903e0e28c4187ed", + strip_prefix = "protobuf-3.10.0", + urls = ["https://github.com/google/protobuf/archive/v3.10.0.tar.gz"] + ) \ No newline at end of file