- Notifications
You must be signed in to change notification settings - Fork10
Python command-line tool and GDB extension to view and save x86, ARM and objdump assembly files as control-flow graph (CFG) pdf files
License
Kazhuu/asm2cfg
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Python command-line tool and GDB extension to view and save x86, ARM and objdumpassembly files as control-flow graph (CFG) pdf files. From GDB debugging sessionuseviewcfg
command to view CFG and usesavecfg
command to save it to thepdf file.
Program has been developed to support X86, ARM and objdump assembly outputs.Program is mostly tested with x86 assembly. ARM and objdump formats might not befully supported. If you have any suggestions or find bugs, please open an issueor create a pull request. If you want to contribute, checkDevelopment how to get started.
Project can be installed with pip
pip install asm2cfg
To be able to view the dot files from GDB. External dot viewer is required. Forthis purposexdot can be used for example. Anyother dot viewer will also do. To install this on Debian based distro run
sudo apt install xdot
Or Arch based
sudo pacman -S xdot
To add extension to GDB you need to source the pip installed plugin to it. Tofind where pip placed GDB extension runwhich gdb_asm2cfg
or in case if youuse pyenv usepyenv which gdb_asm2cfg
. Copy the path to the clipboard.
Then in you home directory if not already add.gdbinit
fileand place following line in it and replace path from the earlier step.
source <path-from-earlier>
For example in my Linux machine line end up to be
source ~/.local/bin/gdb_asm2cfg.py
Now when you start GDB no errors should be displayed and you are ready to go.
In GDB session this extension provides commandviewcfg
to view CFG withexternal dot viewer. Commandsavecfg
saves the CFG to pdf file to currentworking directory with same name as the function being dumped. Both commandsdisassemble the current execution frame/function when the command is issued. Tosee help for these commands usehelp
command likehelp viewcfg
.
For example let's view main function from you favorite non-stripped executable.First run GDB until main function
gdb -ex 'b main' -ex 'run' <executable>
Now runviewcfg
to view CFG as a dot graph with external editor. Or runsavecfg
to save CFG to pdf file namedmain.pdf
to current working directory. Iffunction is stripped then memory address of the function will used as a nameinstead. For example0x555555555faf-0x555555557008.pdf
.
If assembly function is very large with a lot of jumps and calls to otherfunctions. Then rendering the CFG can take a long time. So be patient or cancelrendering with Ctrl-C. To make the rendering faster you can skip function callsinstructions from splitting the code to more blocks. To set this runset skipcalls on
and then run earlier command again. Note that if function is longand has a lot of jumps inside itself, then rendering is still gonna take a longtime. To have normal behavior again runset skipcalls off
.
This method can be used with assembly files saved from ouput of objdump and GDBdisassembly. Pip installation will come withasm2cfg
command-line tool forthis purpose.
To use as standalone script you first need to dump assembly from GDB or objdumpto the file which is explained below.
If you don't know the name of function you're looking for then you can also listall function names using GDB:
gdb -batch -ex 'b main' -ex r -ex 'info functions' ./test_executable
This will set breakpoint at functionmain
, thenrun the program and print symbols from all loaded libraries.
For functions which come from main executable you can avoid running the programand simply do
gdb -batch -ex 'info functions' ./test_executable
If you want to narrow the search down you can also use regexp
gdb ... -ex 'info functions <regexp>' ...
Once you have the function name, you can produce its disassembly via
gdb -batch -ex 'b main' -ex r -ex 'pipe disassemble test_function | tee test_function.asm' ./test_executable
or
gdb -batch -ex 'set breakpoints pending on' -ex 'b test_function' -ex r -ex 'pipe disassemble | tee test_function.asm' ./test_executable
(theset breakpoint pending on
command enables pending breakpoints andcould be added to your.gdbinit
instead)
For functions from main executable it's enough to do
gdb -batch -ex 'pipe disassemble test_function | tee test_function.asm' ./test_executable
You can also extract function's disassembly fromobjdump
output:
objdump -d ./test_executable | sed -ne '/<test_function/,/^$/p' > test_executable.asm
(this may be useful for specific non-native targets which lack GDB support).
Now you have the assembly file. Time to turn that to CFG pdf file. Do that by giving ittoasm2cfg
command-line tool like so
asm2cfg test_function.asm
Asm2cfg by default expects x86 assembly files. If you want to use ARM assembly files,then provide--target arm
command-line flag.
Above command should outputtest_function.pdf
file in the same directory wherethe executable was ran. If the assembly file is stripped then the functionmemory range is used as a name instead. For example0x555555555faf-0x555555557008.pdf
.
To view CFG instead of saving provide-v
flag. And to skip function calls fromsplitting the code to further blocks provide-c
flag. To show the help use-h
.
Repository includes examples which can be used to test the standalonefunctionality for x86, ARM and objdump.
Filetest_function.asm
is non-stripped assembly file and itscorresponding outputtest_function.pdf
.
Filestripped_function.asm
containsstripped function and its corresponding outputstripped_function.pdf
.
Fileatt_syntax.asm
is an example of non-stripped AT&T assembly.
Filehuge.asm
is a large strippedassembly function and its corresponding outputhuge.pdf
. This can be used totest processing time of big functions.
Filesobjdump.asm
andstripped_objdump.asm
are the regular and strippedobjdump-based disassemblies of short functions.
Filearm.asm
is ARM based assembly file and its corresponding pdf file isarm.pdf
.
You want to contribute? You're very welcome to do so! This section will give youguidance how to setup development environment and test things locally.
For development this project manages packages with pipenv. Pipenv is a tool tomanage Python virtual environments and packages with much less pain compared tonormal pip and virtualenv usage.
Install pipenv for your system following the guidehere.
After installing pipenv. Create virtual environment and install all requiredpackages to it. Run following at project root
pipenv install -d
Now you can activate the virtual environment with
pipenv shell
Now yourpython
andpip
commands will correspond to created virtual environmentinstead of your system's Python installation.
To deactivate the environment, use
exit
This project usespytest for testing. Sometest are written using Python's own unittest testing framework, but they workwith pytest out of the box. Pytest style is preferred way to write tests.
To run tests from project root, usepytest
or
pipenv run pytest
During testing dot viewer might be opened if you have it installed. This isbecause GDB integration commandviewcfg
is tested, which will open externaldot viewer. Just close it after it's opened. It should not affect the test runitself.
Project usesflake8 andpylint for code linting.
To run flake8, use
flake8
And to run pylint use
pylint src test
Both commands should not print any errors.
To test command-line interface of asm2cfg wihtout installing the package. Youcan execute module directly. For example to print help
python -m src.asm2cfg -h
Standalone method can be used to try out the examples underexamples
folder aswell. For example following command should generatemain.pdf
file to currentworking directory.
python -m src.asm2cfg -c examples/huge.asm
Before testing GDB functionality, make sure asm2cfg is not installed with pip!This can lead to GDB using code from pip installed asm2cfg package instead ofcode from this repository!
Also pipenv cannot be used with GDB. You need to install required packages toyour system's Python pip. This is because your installed GDB is linked againstsystem's Python interpreter and will use it, instead of active virtualenvironment. If packages are not installed to your system's pip. You are likelyto receive following error messages when trying to use asm2cfg with GDB
ModuleNotFoundError: No module named 'graphviz'
To fix this, install required packages to your system's pip without activevirtual environment. Currently GDB integration only requires graphviz.
pip install graphviz
To use asm2cfg GDB related functionality. Use following line fromproject root.
PYTHONPATH=${PWD}/src gdb -ex 'source src/gdb_asm2cfg.py'
This will set Python import path so that GDB can import code from thisrepository without installing the package. After this you should be able to usecommandsviewcfg
andsavecfg
.
There are might be cases asm2cfg will not fully support all x86 or ARM assemblylines. If you encounter such problems please open an issue.
Current developed goals are best described in issues section. Please open a newone if existing one does not exist.
If you want to talk to me, you can contact me at Discord with nameKazhuu#3121
.
About
Python command-line tool and GDB extension to view and save x86, ARM and objdump assembly files as control-flow graph (CFG) pdf files