BinaryAnalysisPlatform/bap

How to produce phi terms

mateosss opened this issue · 3 comments

Hello, I've been trying to understand what phi terms are by looking for them in binaries. Unfortunately, I was unable to do so, I've tried running bap on both custom-made executables and bigger system utilities like grep but the count of phi terms seems to always be zero.

I'm using the following python lines to count phi terms.

import bap
proj = bap.run('/bin/grep')
subs = proj.program.subs.elements
sum(len(blk.phis) for sub in subs for blk in sub.blks.elements) # this returns 0

I've tried with the following C file compiled with gcc -O0

int main() {
  register int i asm("r8");
  i = 0xDEADB1FE;
  register int j asm("r9");
  j = 0xCAFECAFE;
  register int k asm("r13");
  if (i == j) {
    __asm__("mov %r8d, %r13d\n\t"); // k = i;
  } else {
    __asm__("mov %r9d, %r13d\n\t"); // k = j;
  }
  k += 1;
}

The compiled binary produces a BIR with the following blocks:

000000fa: 
000000fb: R13 := pad:64[low:32[R9]]
000000fc: goto %00000100

000000fd: 
000000fe: R13 := pad:64[low:32[R8]]
000000ff: goto %00000100

00000100: 
00000101: RAX := pad:64[low:32[R13]]
...

From my understanding of the documentation the third block in the example should contain a phi node.

Am I misinterpreting something? An example that produces phi nodes would be appreciated.

bap 1.4.0
ubuntu 18.04
gcc 8.4.0
python 3.9.1
ivg commented

That's easy, you just need to enable the ssa pass, e.g., bap.run('/bin/grep', '--pass=ssa').

With that said, is there any reasons why you're using such an old (if not to say ancient) version of bap? Provided that you're using Ubuntu and don't need OCaml toolchain, you can just use our deb packages and install the latest version, e.g.,

wget https://github.com/BinaryAnalysisPlatform/bap/releases/download/v2.2.0/{bap,libbap,libbap-dev}_2.2.0.deb
sudo dpkg -i {bap,libbap,libbap-dev}_2.2.0.deb

Indeed that was easy 😅, though I stumbled across other problems, I detail my solutions below for future reference.

is there any reasons why you're using such an old (if not to say ancient) version of bap?

My original installation trials were done in a hurry (and without knowing much of the OCaml ecosystem). I do want to develop in both OCaml and Python and would like to have merlin running as well for my code editor.

I've just properly updated opam (1.2.2 -> 2.0.8) and bap (1.4.0 -> 2.2.0). Something that might be of interest is that the README command opam init --comp=4.09.0 didn't seem to work (does the --comp argument still exist?) therefore an old OCaml compiler and an old bap installation candidate were selected by default, I needed to do opam switch create 4.09.0 instead.


There seems to be another problem when running bap 2.2.0 from Python (pip bap 1.3.1) with the --pass=ssa argument:

import bap
proj = bap.run('./a.out', ['--pass=ssa']) # Error here
subs = proj.program.subs.elements
sum(len(blk.phis) for sub in subs for blk in sub.blks.elements)

That example run over the same C code as above gives an error in this line of bap/adt.py

self.elements = dict((x.arg[0],x.arg[1]) for x in args[0])

For now I've just patched it with:

if all(hasattr(x, "arg") for x in args[0]):
    self.elements = dict((x.arg[0],x.arg[1]) for x in args[0])

And lastly, the bap-tutorial doesn't seem to be working anymore in 2.2.0 throwing:

45 |         Option.some_if (Sub.name s = name) (Term.tid s)
                             ^^^^^^^^^^
Error: This expression has type string but an expression was expected of type
         Core_kernel.Int.t = int

It seems to be coming from a redefinition of the equal sign in the JaneStreet Base library, I was able to solve it by using String.equal instead.


Everything seems to be working now thank you!

ivg commented

I think we can close it. The tutorial is updated and I will handle the ssa bug in the bap-python repository.