Skip to content

Commit

Permalink
run pre-commit hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
Kazhuu committed Mar 28, 2024
1 parent cdd8d38 commit c555976
Show file tree
Hide file tree
Showing 17 changed files with 339 additions and 280 deletions.
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ flake8 = "*"
pytest = "*"
pytest-cov = "*"
pylint = "*"
pre-commit = "*"
12 changes: 8 additions & 4 deletions ocgraph/configuration/architecture/ppc.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@


# Common regexes
HEX_PATTERN = r'[0-9a-fA-F]+'
HEX_LONG_PATTERN = r'(?:0x0*)?' + HEX_PATTERN
HEX_PATTERN = r"[0-9a-fA-F]+"
HEX_LONG_PATTERN = r"(?:0x0*)?" + HEX_PATTERN

# fmt: off
ppc_call_opcodes = [
Expand Down Expand Up @@ -697,7 +697,9 @@ def is_call(self, instruction: Instruction):
return instruction.opcode in ppc_call_opcodes

def is_branch(self, instruction: Instruction):
return instruction.opcode in (ppc_conditional_branch_opcodes + ppc_unconditional_branch_opcodes) and not self.is_call(instruction)
return instruction.opcode in (
ppc_conditional_branch_opcodes + ppc_unconditional_branch_opcodes
) and not self.is_call(instruction)

def is_unconditional_branch(self, instruction: Instruction):
return instruction.opcode in ppc_unconditional_branch_opcodes
Expand All @@ -706,4 +708,6 @@ def is_sink(self, instruction: Instruction):
return instruction.opcode in ppc_sink_opcodes

def is_direct_branch(self, instruction: Instruction):
return self.is_branch(instruction) and (re.search(rf"{HEX_LONG_PATTERN}", '|'.join(instruction.ops)))
return self.is_branch(instruction) and (
re.search(rf"{HEX_LONG_PATTERN}", "|".join(instruction.ops))
)
4 changes: 3 additions & 1 deletion ocgraph/configuration/architecture/sparc.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ def is_call(self, instruction: Instruction):
return instruction.opcode in sparc_v8_call_opcodes

def is_branch(self, instruction: Instruction):
return instruction.opcode in (sparc_v8_conditional_branch_opcodes + sparc_v8_unconditional_branch_opcodes)
return instruction.opcode in (
sparc_v8_conditional_branch_opcodes + sparc_v8_unconditional_branch_opcodes
)

def get_branch_delay(self, instruction: Instruction) -> int | None:
delay = None
Expand Down
2 changes: 1 addition & 1 deletion ocgraph/configuration/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def __init__(
self.__dict__ = _preset

# configure logging
self.logger = OCGraphLogger("OcGraph", logging_preset, "asm2cfg.log")
self.logger = OCGraphLogger("OcGraph", logging_preset, "asm2cfg.log")

@staticmethod
def architectures():
Expand Down
1 change: 0 additions & 1 deletion ocgraph/configuration/disassembler/objdump_arm.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/env python3
"""Class for parsing the objdump ARM input"""

import re
Expand Down
2 changes: 0 additions & 2 deletions ocgraph/configuration/disassembler/objdump_ppc.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,5 +225,3 @@ def parse_line(self, line: str, lineno, function_name: str) -> Instruction | Non
def parse_jump_target(self, ops: List[str]) -> int | None:
# it assumes the last operand of the branch to be the target address
return int(ops[-1], 16)


5 changes: 2 additions & 3 deletions ocgraph/configuration/disassembler/objdump_x86.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/env python3
"""Class for parsing the input"""

import re
Expand Down Expand Up @@ -55,7 +54,7 @@ def extract_information(self, str_input: str) -> dict[str, str]:
}
else:
raise DisassemblerError("Line not processable: \n" + str(str_input))

return result

def parse_function_header(self, line: str) -> str | None:
Expand Down Expand Up @@ -187,7 +186,7 @@ def parse_line(self, line: str, lineno, function_name: str) -> Instruction | Non
address, line = self.parse_address(line)
if address is None:
return None

encoding, line = self.parse_encoding(line)
if not line:
return encoding
Expand Down
4 changes: 1 addition & 3 deletions test/fixtures/simple_program/hello.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#include <stdio.h>

int main() {
printf("Hello World\n");
}
int main() { printf("Hello World\n"); }
4 changes: 1 addition & 3 deletions test/templates/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@ __attribute__((visibility("hidden")))
void foo() {
}

void bar() {
foo();
}
void bar() { foo(); }
29 changes: 15 additions & 14 deletions test/templates/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def error(msg):
"""
Print nicely-formatted error message and exit.
"""
sys.stderr.write(f'{_ME}: error: {msg}\n')
sys.stderr.write(f"{_ME}: error: {msg}\n")
sys.exit(1)


Expand All @@ -29,13 +29,14 @@ def _run(cmd, stdin=None, verbose=0):
"""
if verbose:
print(f"{_ME}: running command: {' '.join(cmd)}")
with subprocess.Popen(cmd, stdin=stdin, stdout=subprocess.PIPE,
stderr=subprocess.PIPE) as process:
with subprocess.Popen(
cmd, stdin=stdin, stdout=subprocess.PIPE, stderr=subprocess.PIPE
) as process:
out, err = process.communicate()
out = out.decode()
err = err.decode()
if process.returncode != 0:
cmds = ' '.join(cmd)
cmds = " ".join(cmd)
error(f"'{cmds}' failed:\n{out}{err}")
sys.stderr.write(err)
return out
Expand All @@ -45,43 +46,43 @@ def gcc(args):
"""
Run compiler with given arguments.
"""
return _run(['gcc'] + args)
return _run(["gcc"] + args)


def disasm(file, objdump_or_gdb, symbol, start, finish):
"""
Disassemble binary file.
"""
if objdump_or_gdb:
out = _run(['objdump', '-d', file])
out = _run(["objdump", "-d", file])
elif symbol is not None:
out = _run(['gdb', '-batch', '-ex', f'disassemble {symbol}', file])
out = _run(["gdb", "-batch", "-ex", f"disassemble {symbol}", file])
else:
out = _run(['gdb', '-batch', '-ex', f'disassemble {start},{finish}', file])
out = _run(["gdb", "-batch", "-ex", f"disassemble {start},{finish}", file])
return out


def strip_binary(file):
"""
Strip symbol info from binary file.
"""
_run(['strip', '-s', file])
_run(["strip", "-s", file])


def grep(text, regex):
lines = text.split('\n')
lines = text.split("\n")
return list(filter(lambda s: re.search(regex, s), lines))


def find_address(file, name):
out = _run(['readelf', '-sW', file])
lines = grep(out, fr'{name}$')
assert len(lines) >= 1, f'failed to locate symbol {name} in\n{out}'
out = _run(["readelf", "-sW", file])
lines = grep(out, rf"{name}$")
assert len(lines) >= 1, f"failed to locate symbol {name} in\n{out}"
line = lines[0]
# Num: Value Size Type Bind Vis Ndx Name
# 27: 0000000000001030 11 FUNC GLOBAL DEFAULT 9 foo
line = line.strip()
words = re.split(r'\s+', line)
words = re.split(r"\s+", line)
start = int(words[1], 16)
size = int(words[2])
return start, start + size
53 changes: 29 additions & 24 deletions test/templates/gen_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,53 +14,58 @@

set_basename(os.path.basename(__file__))

for gdb, pic, plt, direct, strip in itertools.product([False, True],
[False, True], # Do we need to test PIE too?
[False, True],
[False, True],
[False, True]):
for gdb, pic, plt, direct, strip in itertools.product(
[False, True],
[False, True], # Do we need to test PIE too?
[False, True],
[False, True],
[False, True],
):
# Print config

disasm_type = 'GDB' if gdb else 'objdump'
pic_type = 'position-INdependent' if pic else 'position-dependent'
call_type = 'Non-PIC-call' if direct else 'PIC-call'
strip_type = 'stripped' if strip else 'UNstripped'
plt_type = 'PLT' if plt else 'PLT-less'
print(f'Checking {disasm_type} {pic_type} {plt_type} {call_type} {strip_type}')
disasm_type = "GDB" if gdb else "objdump"
pic_type = "position-INdependent" if pic else "position-dependent"
call_type = "Non-PIC-call" if direct else "PIC-call"
strip_type = "stripped" if strip else "UNstripped"
plt_type = "PLT" if plt else "PLT-less"
print(f"Checking {disasm_type} {pic_type} {plt_type} {call_type} {strip_type}")

# Generate object code

flags = ['call.c', '-o', 'a.out',
'-Wl,--defsym,_start=0', '-nostdlib', '-nostartfiles']
flags = ["call.c", "-o", "a.out", "-Wl,--defsym,_start=0", "-nostdlib", "-nostartfiles"]
# DLL or executable?
if pic:
flags += ['-fPIC', '-shared']
flags += ["-fPIC", "-shared"]
# Use PLT?
if not plt:
flags += ['-fno-plt']
flags += ["-fno-plt"]
# Force non-PLT call for PIC code?
if direct and pic:
flags.append('-DHIDDEN')
flags.append("-DHIDDEN")

gcc(flags)

caller = 'bar'
start, finish = find_address('a.out', caller)
caller = "bar"
start, finish = find_address("a.out", caller)
if strip:
strip_binary('a.out')
strip_binary("a.out")
caller = None

# Generate disasm

out = disasm('a.out', not gdb, caller, start, finish)
out = disasm("a.out", not gdb, caller, start, finish)

# Print snippets

headers = grep(out, r'<bar>:|Dump of')
calls = grep(out, r'call')
print('''\
headers = grep(out, r"<bar>:|Dump of")
calls = grep(out, r"call")
print(
"""\
headers:
{0}
calls:
{1}
'''.format('\n '.join(headers), '\n '.join(calls)))
""".format(
"\n ".join(headers), "\n ".join(calls)
)
)
47 changes: 29 additions & 18 deletions test/templates/gen_funtable.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,45 +11,56 @@

set_basename(os.path.basename(__file__))

for gdb, pic, strip in itertools.product([False, True],
[False, True], # Do we need to test PIE too?
[False, True]):
for gdb, pic, strip in itertools.product(
[False, True], [False, True], [False, True] # Do we need to test PIE too?
):
# Print config

disasm_type = 'GDB' if gdb else 'objdump'
pic_type = 'position-INdependent' if pic else 'position-dependent'
stripped = 'stripped' if strip else 'UNstripped'
print(f'Checking {disasm_type} {pic_type} {stripped}')
disasm_type = "GDB" if gdb else "objdump"
pic_type = "position-INdependent" if pic else "position-dependent"
stripped = "stripped" if strip else "UNstripped"
print(f"Checking {disasm_type} {pic_type} {stripped}")

# Generate object code

flags = ['funtable.c', '-o', 'a.out',
'-Wl,--defsym,_start=0', '-nostdlib', '-nostartfiles', '-O2']
flags = [
"funtable.c",
"-o",
"a.out",
"-Wl,--defsym,_start=0",
"-nostdlib",
"-nostartfiles",
"-O2",
]
# DLL or executable?
if pic:
flags += ['-fPIC', '-shared']
flags += ["-fPIC", "-shared"]
# Include debuginfo?
if not strip:
flags.append('-g')
flags.append("-g")

gcc(flags)

# Strip

caller = 'bar'
start, finish = find_address('a.out', caller)
caller = "bar"
start, finish = find_address("a.out", caller)
if strip:
strip_binary('a.out')
strip_binary("a.out")
caller = None

# Generate disasm

out = disasm('a.out', not gdb, caller, start, finish)
out = disasm("a.out", not gdb, caller, start, finish)

# Print snippets

jumps = grep(out, r'\bcall')
print('''\
jumps = grep(out, r"\bcall")
print(
"""\
table calls:
{}
'''.format('\n '.join(jumps)))
""".format(
"\n ".join(jumps)
)
)
Loading

0 comments on commit c555976

Please sign in to comment.