Created
April 5, 2023 21:42
-
-
Save lab313ru/36972ba4d4ded3ef1de3ef4a35de538a to your computer and use it in GitHub Desktop.
Applies sym file information to idb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
import idc | |
import ida_nalt | |
import ida_kernwin | |
import ida_name | |
MODULE = re.compile(r'^MODULE \w+ \w+ \w+ .+$') | |
INFO = re.compile(r'^INFO CODE_ID \w+ .+$') | |
FILE = re.compile(r'^FILE (\d+) (.+)$') | |
FUNC = re.compile(r'^FUNC (\w+) (\w+) (\w+) (.+)$') | |
LINE = re.compile(r'^([0-9a-f]+) (\w+) (\d+) (\d+)$') | |
PUBLIC = re.compile(r'^PUBLIC (\w+) (\w+) (.+)$') | |
STACK = re.compile(r'^STACK CFI .+$') | |
def is_module(line): | |
return MODULE.match(line) | |
def parse_module(res): | |
return None | |
def is_info(line): | |
return INFO.match(line) | |
def parse_info(res): | |
return None | |
def is_file(line): | |
return FILE.match(line) | |
def parse_file(res): | |
fnum = int(res.group(1)) | |
name = res.group(2) | |
return fnum, name | |
def is_func(line): | |
return FUNC.match(line) | |
def parse_func(res): | |
addr = int(res.group(1), 16) | |
size = int(res.group(2), 16) | |
psize = int(res.group(3), 16) | |
name = res.group(4) | |
return addr, size, name | |
def is_line(line): | |
return LINE.match(line) | |
def parse_line(res): | |
addr = int(res.group(1), 16) | |
size = int(res.group(2), 16) | |
line = int(res.group(3)) | |
fnum = int(res.group(4)) | |
return addr, size, line, fnum | |
def is_public(line): | |
return PUBLIC.match(line) | |
def parse_public(res): | |
addr = int(res.group(1), 16) | |
psize = int(res.group(2), 16) | |
name = res.group(3) | |
return addr, name | |
def is_stack(line): | |
return STACK.match(line) | |
def parse_stack(res): | |
return None | |
def parse_lines(line): | |
res = is_module(line) | |
if res: | |
return 'md', parse_module(res) | |
res = is_info(line) | |
if res: | |
return 'in', parse_info(res) | |
res = is_file(line) | |
if res: | |
return 'fl', parse_file(res) | |
res = is_func(line) | |
if res: | |
return 'fn', parse_func(res) | |
res = is_line(line) | |
if res: | |
return 'ln', parse_line(res) | |
res = is_public(line) | |
if res: | |
return 'pb', parse_public(res) | |
res = is_stack(line) | |
if res: | |
return 'st', parse_stack(res) | |
return 'nn', None | |
def use_files(files, funcs, lines, pubs): | |
base = ida_nalt.get_imagebase() | |
ida_kernwin.show_wait_box('Apply funcs') | |
sz = len(funcs) | |
for i, addr in enumerate(funcs.keys()): | |
size, name = funcs[addr] | |
name = ida_name.validate_name(name, ida_name.VNT_IDENT) | |
idc.set_name(base + addr, name, idc.SN_NOWARN) | |
ida_kernwin.replace_wait_box('%d/%d, 0x%X' % (i, sz, base + addr)) | |
ida_kernwin.hide_wait_box() | |
ida_kernwin.show_wait_box('Apply pubs') | |
sz = len(pubs) | |
for i, addr in enumerate(pubs.keys()): | |
name = pubs[addr] | |
name = ida_name.validate_name(name, ida_name.VNT_IDENT) | |
idc.set_name(base + addr, name, idc.SN_NOWARN) | |
ida_kernwin.replace_wait_box('%d/%d, 0x%X' % (i, sz, base + addr)) | |
ida_kernwin.hide_wait_box() | |
ida_kernwin.show_wait_box('Apply files') | |
sz1 = len(files) | |
for i, fnum in enumerate(files.keys()): | |
fname = files[fnum] | |
if fnum not in lines: | |
continue | |
addrs = lines[fnum] | |
sz2 = len(addrs) | |
for j, addr in enumerate(addrs.keys()): | |
size, line = addrs[addr] | |
idc.add_sourcefile(base + addr, base + addr + size, fname) | |
idc.set_source_linnum(base + addr, line) | |
ida_kernwin.replace_wait_box('%d/%d - %d/%d, 0x%X (0x%x)' % (i, sz1, j, sz2, base + addr, size)) | |
ida_kernwin.hide_wait_box() | |
def main(path): | |
files = dict() | |
funcs = dict() | |
lines = dict() | |
pubs = dict() | |
with open(path) as f: | |
for line in f.readlines(): | |
line = line.rstrip() | |
t, args = parse_lines(line) | |
if t in ['md', 'in', 'st']: | |
continue | |
elif t == 'fl': | |
fnum, name = args | |
files[fnum] = name | |
elif t == 'fn': | |
addr, size, name = args | |
funcs[addr] = size, name | |
elif t == 'ln': | |
addr, size, line, fnum = args | |
if fnum not in lines: | |
lines[fnum] = dict() | |
lines[fnum][addr] = size, line | |
elif t == 'pb': | |
addr, name = args | |
pubs[addr] = name | |
else: | |
print('wrong') | |
print('total:\nfiles = %d, funcs = %d, lines = %d, pubs = %d' % (len(files), len(funcs), len(lines), len(pubs))) | |
use_files(files, funcs, lines, pubs) | |
main('nw.dll.sym') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment