1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| from capstone import * import copy from pwn import *
import graphviz from graphviz import nohtml from six import print_
elf = ELF("main.elf") md = Cs(CS_ARCH_X86, CS_MODE_64) md.detail = True initkey = elf.read(0x4000AD, 32)
def bin2str(m): t = '' for i in range(100): nn = m[i * 8: i * 8 + 8] t += chr(int("".join([str(i) for i in nn])[::-1], 2)) return t
g = graphviz.Digraph('g', filename='btree.gv', node_attr={'shape': 'record', 'height': '.1'})
class MyNode: def __init__(self, offset): self.offset = offset self.min_path = [] self.min_cost = 0
class Edge: def __init__(self, start, end, lr): self.start = start self.end = end self.lr = lr
g_nodes = {} g_edges = []
def decode_block(offset, key_data, vv = 0): bin_offset = offset + 0x400176 bin_data = bytearray(elf.read(bin_offset, 32)) for i in range(32): bin_data[i] ^= key_data[i] next_ = [] key_ = [] for i in md.disasm(bin_data, 0x4000AD): ins = "0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str) if 'lea' in ins and 'rbx' in ins: next_.append(int(i.op_str.split('[rdi + ')[1][:-1], 16)) if 'add' in ins and 'r9' in ins: key_.append(int(ins.split('r9, ')[1], 16))
g_nodes[offset] = MyNode(offset) min_cost = 0xffffff min_edge = None min_node = None for edge in g_edges: if edge.end == offset: node = g_nodes[edge.start] cur_cost = node.min_cost + vv if cur_cost < min_cost: min_cost = cur_cost min_edge = edge min_node = node if min_edge != None: g_nodes[offset].min_path = min_node.min_path.copy() g_nodes[offset].min_cost = min_cost g_nodes[offset].min_path.append(min_edge.lr)
if len(next_) == 2: g.node('node_' + hex(offset)[2:], nohtml('<f0> |<f1> %x|<f2>' % vv)) g.edge('node_%x:f0' % offset, 'node_%x:f1' % next_[0]) g.edge('node_%x:f2' % offset, 'node_%x:f1' % next_[1])
g_edges.append(Edge(offset, next_[0], 1)) g_edges.append(Edge(offset, next_[1], 0)) else: g.node('node_' + hex(offset)[2:], nohtml('<f0> |<f1> %x|<f2>' % min_cost)) print("min:%x" % min_cost) if min_cost <= 0x49da: print("yes !!!") print(g_nodes[offset].min_path) print(bin2str(g_nodes[offset].min_path)) return next_, key_, bin_data
def draw(): hist = [] worklist = [(0, initkey, 0)] while len(worklist) > 0: t = worklist[0] del(worklist[0]) if t[0] in hist: continue hist.append(t[0]) next_, key_, bin_data = decode_block(t[0], t[1], t[2]) if len(next_) == 2: worklist.append((next_[0], bin_data, key_[0])) worklist.append((next_[1], bin_data, key_[1])) draw() print("Finish.") input(">>>") g.view()
|