-
Notifications
You must be signed in to change notification settings - Fork 6
/
nadbg.py
190 lines (163 loc) · 5.4 KB
/
nadbg.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
from core.welprompt import CLUI
from core.nadbg import *
# these codes for debug
from IPython import embed
import traceback as tb
import sys
def excepthook(type, value, traceback):
tb.print_last()
embed()
sys.excepthook = excepthook
# load plugins
try:
from plugins.hi_loader import hi # heapinspect
except ImportError:
print('Use `git submodule init` to download plugins')
exit()
if __name__ == '__main__':
interval = DEFAULT_INTERVAL
def set_value(key, val):
'''set global values.
args:
key: key
val: val
'''
key_to_obj = {
'interval': (interval, int),
}
if key in key_to_obj:
obj, typ = key_to_obj[key]
obj = typ(val)
else:
print('invalid key')
def attach(s):
'''attach to a process. name and pid are supported
args:
s: a binary name or its pid, also support path
'''
pid = nadbg.attach(s)
if pid == 0:
print('attach {} failed'.format(s))
else:
print('attach {} success. pid: {}'.format(s, pid))
def watch(typ, addr, size='1'):
'''set memory watch point for the attached process.
args:
typ: supported type -- byte str int dword qword ptr size_t
addr: the address you want to set watch point. (e.g. 0x602010 0x7fff8b4000)
size: total_size = sizeof(typ) * size
'''
if addr.startswith('0x'):
addr = int(addr[2:], 16)
else:
addr = int(addr)
if size.startswith('0x'):
size = int(size[2:], 16)
else:
size = int(size)
nadbg.watches.add(addr, typ, size)
def watcher_print():
'''print out all watch point information. no args needed.
'''
nadbg.do_check()
print(nadbg.watches_info)
def print_forever():
'''print out all watch point information when there is a change.
use `set interval 0.5` to let it check each 0.5 sec. default is 1.
'''
pre_msg = ''
while True:
nadbg.do_check()
msg = nadbg.watches_info
if msg != pre_msg:
pre_msg = msg
print(msg)
print('')
sleep(interval)
def dump(typ, addr, size='1'):
'''dump memory for the attached process.
args:
typ: supported type -- byte str int dword qword ptr size_t
addr: the address you want to set watch point. (e.g. 0x602010 0x7fff8b4000)
size: total_size = sizeof(typ) * size
'''
if addr.startswith('0x'):
addr = int(addr[2:], 16)
else:
addr = int(addr)
if size.startswith('0x'):
size = int(size[2:], 16)
else:
size = int(size)
nadbg.do_check()
print(nadbg.memdump(addr, typ, size))
def psinfo(key=None):
'''get process info.
args:
key: the name of the info.
'''
nadbg.do_check()
if key == 'vmmap':
print('\n'.join([str(map) for map in nadbg.proc.vmmap]))
elif key == 'bases':
print('\n'.join(['{}: {:#x}'.format(base[0], base[1]) for base in nadbg.proc.bases.items()]))
elif key == 'canary':
print(hex(nadbg.proc.canary))
else:
info = []
info.append('process path: {}'.format(nadbg.proc.path))
info.append('arch: {}'.format(nadbg.proc.arch))
info.append('libc: {}'.format(nadbg.proc.libc))
info.append('prog address: {:#x}'.format(nadbg.proc.bases['prog']))
info.append('libc address: {:#x}'.format(nadbg.proc.bases['libc']))
print('\n'.join(info))
def find(s):
'''Search in all memory of the attached process.
args:
s: The content to search. use `0x` to search int.
'''
nadbg.do_check()
results = nadbg.proc.search_in_all(s)
if not results:
print('not found')
else:
contents = []
for idx, ele in enumerate(results):
addr, memhex = ele
content = '[{}] {:#x}'.format(idx, addr)
contents.append(content)
print('\n'.join([_ for _ in contents]))
def prompt_status():
return nadbg.s
ui = CLUI('nadbg')
ui.commands['set'] = set_value
ui.commands['attach'] = attach
ui.commands['watch'] = watch
ui.commands['print'] = watcher_print
ui.commands['print_forever'] = print_forever
ui.commands['dump'] = dump
ui.commands['info'] = psinfo
ui.commands['find'] = find
ui.prompt_status = prompt_status
ui.alias['wb'] = 'watch byte'
ui.alias['ws'] = 'watch str'
ui.alias['ww'] = 'watch word'
ui.alias['wd'] = 'watch dword'
ui.alias['wq'] = 'watch qword'
ui.alias['db'] = 'dump byte'
ui.alias['ds'] = 'dump str'
ui.alias['ww'] = 'dump word'
ui.alias['dd'] = 'dump dword'
ui.alias['dq'] = 'dump qword'
ui.alias['vmmap'] = 'info vmmap'
ui.alias['canary'] = 'info canary'
ui.alias['at'] = 'attach'
ui.alias['p'] = 'print'
ui.alias['q'] = 'exit'
# plugins
def hi_plugin(command='help', *args):
''' Heapinspect plugin '''
func = getattr(hi, command)
return func(*args)
ui.commands['hi'] = hi_plugin
ui.run()