Using angr in 2024
Introduction
My first article on this personal blog was about angr
, and was supposed to be part of a series. As evident from the lack of additional articles, I in fact gave up, for the reasons below:
- No good enough hardware to handle the resources required by
angr
- Unfamiliarity with the framework and unwillingness to jump into its (rather large) codebase
angr
runs for a long time and consumes all my resources, and I don’t (didn’t) know why.- Few people around me shared my interest for it.
- Other priorities in my personal life
But now, things have changed and I feel I’m ready to take another stab at it! In fact, I’ve spent the last few weeks experimenting with it:
- I needed to track which byte in a file ended up being used at specific locations in a software. So naturally I didn’t properly scout the existing tools and made one built on top of pyvex,
angr
‘s python port ofValgrind
‘ Intermediate Representation. This was before I knew aboutpolytracker
and also before I realized I didn’t really needed that. Too bad, I wrote 2,000 lines of code for that haha. - Discussing with a colleague, we shared our need for an IDA extension where we could
right click
and askangr
to find bugs for us. So I made this extension (at least, theangr
integration part). - This time, I decided to stop reinventing the wheel and properly investigate the state-of-the-art (SOTA) approaches. While I initially relied on Google searches, the most fruitful method turned out to be exploring GitHub repositories. Specifically, I searched for projects with specific keywords (using the code search feature). The idea is that specific
angr
classes would necessarily be used in projects that solved the same problems I intended to solve (angr.analyses.VariableRecovery
) for instance.
I found these:
- ioctlance
- Arcus
- C3PO
- SEMA toolchain (malware analysis with
angr
)
I read their papers and source code. I found this file (disabled/int_overflow.py
) in Arcus that piqued my interest: could I copy-paste a ready to use integer overflow sanitizer?
So I made a basic vulnerable program in C, built it, created a basic angr
skeleton, and plugged in int_overflow.py
. It didn’t work.
My motivation didn’t waver for mysterious reasons; in fact, I felt even more driven to debug it. What do I do whenever I’m pushed towards solving something I seriously lack skills for? I minify it and add back some features, first copy-pasting from the examples, and repeatedly doing this until my understanding levels up.
This usually snowballs quite rapidly because, by doing this, I get ideas, I test them, this constrains the horizon of possibilities further, and then solutions become more obvious. I implement them until I become rather fluent with it.
Tout voyage tend vers une fin, mais à la fin, c’est le voyage qui compte. - Antoine de Saint-Exupéry
I’m glad to say this happened with angr
(although I will probably never fully master it; angr
is huge, and my love for Program Analysis stops at math-heavy papers).
This also means… I’m sharing my discoveries in this article in the hope of helping or inspiring others.
Installing angr
on macOS Apple Silicon in 2024
To be honest, I had a terrible experience installing it in 2020, and hoped it would be different. It was not.
Here are my notes to successfully install it:
- Download
cmake
from the official website and install, then
sudo "/Applications/CMake.app/Contents/bin/cmake-gui" --install=/usr/local/bin
brew install pkg-config
- Create a virtual environment if you want
pip install angr
This should work. If not, good luck, if yes, then you’re ready for the really painful part. By default, the capstone
dependency ships with the wrong architecture. So we’ll need to build it ourselves, and also fix bugs, because why would it be otherwise.
3130 git clone https://github.com/capstone-engine/capstone
3131 l
3132 cd capstone
3133 l
3134 make
3135 brew install llvm
3136 export LDFLAGS="-L/opt/homebrew/opt/llvm/lib"\n
3139 make
3140 cd bindings
3143 cd python
3144 sudo make install
3148 python3 setup.py install
3149 pip uninstall capstone
Above is the sequence of commands I had to execute. In short, we’re cloning capstone
, installing llvm
(used to build capstone
), configuring the linker because otherwise capstone
complains about it, then build the python
bindings, and then apparently uninstalling capstone
(installed as dependency while installing angr
) is enough for our freshly built version to be found.
Buuuut this is not over. By doing this, we installed a too recent version of capstone
. Of course, they made breaking changes: they replaced CS_ARCH_ARM64
with CS_ARCH_AARCH64
if you care.
error: module 'capstone' has no attribute "'CS_ARCH_ARM64'"
Just open .venv/lib/python3.9/site-packages/archinfo/arch_aarch64.py
and fix it at line 47:
if _capstone:
cs_arch = _capstone.CS_ARCH_ARM64
And now:
python3
>>> import angr
>>>
It works!
To be continued
In the next article, I’m sharing tips and tricks to make angr
faster and actually understand what it’s doing. I will be sharing code snippets that actually helped me find a bug in angr
‘s exploration (or undocument shortcoming if you want to call it like that).