from miasm.analysis.binary import Container from miasm.analysis.machine import Machine from miasm.core.locationdb import LocationDB
loc_db = LocationDB()
cont = Container.from_stream(open("dump.bin","rb"), loc_db=loc_db) # Bin stream is a view on the mapped binary bin_stream = cont.bin_stream
# 'cont.arch' is "x86_32", extracted from the ELF header machine = Machine(cont.arch) # Disassembly engine associated with the current binary mdis = machine.dis_engine(bin_stream, loc_db=loc_db) # Disassemble the main function blocks = mdis.dis_multiblock(cont.entry_point) # Get back the CFG as a dot file open("cfg.dot", "w").write(blocks.dot())
from miasm.core.locationdb import LocationDB from miasm.analysis.binary import Container from miasm.analysis.machine import Machine from miasm.core.graph import MatchGraphJoker, DiGraphSimplifier from miasm.expression.expression import LocKey from miasm.core.asmblock import AsmCFG
"""MatchGraphJoker are joker nodes of MatchGraph, that is to say nodes which stand for any node. Restrictions can be added to jokers. If j1, j2 and j3 are MatchGraphJoker, one can quickly build a matcher for the pattern: | +----v----+ | (j1) | +----+----+ | +----v----+ | (j2) |<---+ +----+--+-+ | | +------+ +----v----+ | (j3) | +----+----+ | v Using: >>> matcher = j1 >> j2 >> j3 >>> matcher += j2 >> j2 Or: >>> matcher = j1 >> j2 >> j2 >> j3 """
def__init__(self, restrict_in=True, restrict_out=True, filt=None, name=None): """Instantiate a MatchGraphJoker, with restrictions @restrict_in: (optional) if set, the number of predecessors of the matched node must be the same than the joker node in the associated MatchGraph @restrict_out: (optional) counterpart of @restrict_in for successors @filt: (optional) function(graph, node) -> boolean for filtering candidate node @name: (optional) helper for displaying the current joker """
import os from miasm.analysis.sandbox import Sandbox_Linux_x86_32 from miasm.core.locationdb import LocationDB from miasm.core.types import Str, set_allocator from miasm.os_dep.common import heap from miasm.jitter.csts import PAGE_READ, PAGE_WRITE, PAGE_EXEC from miasm.analysis.binary import Container from miasm.analysis.machine import Machine from miasm.core.graph import MatchGraphJoker, DiGraphSimplifier from miasm.expression.expression import LocKey from miasm.core.asmblock import AsmCFG from miasm.analysis.simplifier import IRCFGSimplifierSSA
defdelete_items_by_value(d, value): return {k: v for k, v in d.items() if v != value}
defblock_merge(dgs, graph: AsmCFG): global block_list for sol in matcher.match(graph): print(sol) successors = graph.successors(sol[end]) for pred in graph.predecessors(sol[dad]): for succ in successors: graph.add_edge(pred, succ, graph.edges2constraint[(pred, sol[dad])]) for node in sol.values(): graph.del_node(node)
deffilt_func(graph: AsmCFG, node: LocKey): global if_print, block_list # print(f"node ==> {node}") blocks = graph.blocks for block in blocks: iflen(block.lines) == 2and block.lines[0].name == "PUSH"and block.lines[1].name == "MOV": if block notin block_list: block_list.append(block) return block_list
dad = MatchGraphJoker(name="dad", restrict_in=False, filt=filt_func)
middle = MatchGraphJoker(name="middle") end = MatchGraphJoker(name="end", restrict_out=False)
这里遇到了一个麻烦的地方。就是enable_passes会跑三次这个apply_simp.当只跑第一次时可以成功将node删除掉,但是它跑完一轮后new_graph = graph.copy()会把node还原,第二次第三次又不会进入for sol in matcher.match(graph):的循环内。所以相当于我这个删除操作没啥用。不知道是这个copy的逻辑问题还是我的问题,我直接改源码让它第一次break就正常了。如果有知道的大佬跪求联系我指导一下(
defenable_passes(self, passes): """Add @passes to passes to applied @passes: sequence of function (DiGraphSimplifier, DiGraph) -> None """ self.passes += passes
defapply_simp(self, graph): """Apply enabled simplifications on graph @graph @graph: DiGraph instance """ whileTrue: new_graph = graph.copy() for simp_func in self.passes: simp_func(self, new_graph)
if new_graph == graph: break graph = new_graph return new_graph
def__call__(self, graph): """Wrapper on 'apply_simp'""" return self.apply_simp(graph)