-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpinja.py
115 lines (87 loc) · 3.44 KB
/
pinja.py
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
108
109
110
111
112
113
114
115
from unittest.mock import Mock
from os import system
from binaryninja.debugger import DebuggerController
import binaryninja
import pwn
from pwnlib.util import packing
from time import sleep
class ninja_process(pwn.process):
def __init__(self, filename):
"""
exe is pwn ELF object
filename is patched binary location
bv is BN live view of process
dbg is BN DebuggerController
"""
self.exe = pwn.ELF(filename)
self.exe.asm(self.exe.entrypoint, "h: jmp h;nop;nop")
self.exe.save("/tmp/" + filename)
self.filename = "/tmp/" + filename
system(f"chmod +x {self.filename}")
bv = binaryninja.BinaryViewType.get_view_of_file(filename)
self.dbg = DebuggerController(bv)
super().__init__(self.filename)
if self.dbg.attach(self.pid):
pwn.info(f"Sucessfully Attached to process {self.pid}")
else:
pwn.error(f"Error Attaching to process {self.pid}")
self.bv = self.dbg.live_view
# atat bad
self.dbg.execute_backend_command("settings set target.x86-disassembly-flavor intel")
self.dbg.set_reg_value("rip", self.bv.entry_point +4)
self.bv.write(self.bv.entry_point, pwn.asm("endbr64"))
# Clones the BN debugger object, hopefully no name collisions
# for attr in [method_name for method_name in dir(self.dbg) if not method_name.startswith('__') and method_name != 'ID']:
# for attr in [method_name for method_name in dir(self.dbg) if not method_name.startswith("_") ]:
# setattr(self,attr, (getattr(self.dbg, attr)))
# self.breakpoints = DebuggerController.breakpoints
def __getattr__(self, attr):
try:
return getattr(self.dbg, attr)
except:
return super().__getattr__(attr)
def sendline(self, line=b''):
# Screw \n, If you want a newline put it in urself
line = packing._need_bytes(line)
self.send(line)
def close(self):
super().close()
self.bv.file.close()
self.dbg.destroy()
def _pint(self):
if self.target_status.value == 1:
self.execute_backend_command("process interrupt")
return True
else:
# Already pause/breakpoint
return False
def _cont(self):
self.execute_backend_command("continue")
def _dunno(self):
self._pint()
sleep(.3)
self._cont()
# Custom Binja Stuff, mirrors gdb
def add_breakpoint_sym(self, symbol : str):
if "+" in symbol:
symbol = symbol.split("+")
self.add_breakpoint( self.bv.symbols[symbol[0]][0].address + int(symbol[1]))
else:
self.add_breakpoint( self.bv.symbols[symbol][0].address )
def dump_regs(self, regs : list, hint=True, hexxed=True):
output = ""
for r in regs:
for a in self.regs:
if a.name == r:
output += f"{r}: {hex(a.value) if hexxed else a.value} {'→ ' + a.hint if a.hint != '' and hint else ''}\n"
return output
# Mock everything
def fake_debug(*args,**kwargs):
d = pwn.gdb.debug(args,**kwargs)
# No need to comment between flips
for attr in [method_name for method_name in dir(DebuggerController) if not method_name.startswith("_") ]:
setattr(d, attr, Mock())
d.dbg = Mock()
d.bv = Mock()
d.add_breakpoint_sym = Mock()
return d