git-subtree-dir: Security Research and Development with LLVM - Andrew Reiter git-subtree-mainline: aa7a9fc1e16c3c5be7ba312c4b4e37775e005101 git-subtree-split: 0605b5174c2bc286d3e95d6c0df620800bef96c7
119 строки
4.5 KiB
Markdown
119 строки
4.5 KiB
Markdown
|
|
The code will look for any/all pointer function arguments and will
|
|
insert an assert(ptr != NULL); statement. It shows looking at
|
|
functions, their arguments, a function pass, declaring a function,
|
|
and inserting code. Why? Eh. A few reasons that are BS, but mostly
|
|
to help learn API.
|
|
|
|
|
|
## Build and Run
|
|
|
|
This requires LLVM and Clang 3.8, 3.9, or 4.0 releases. You should
|
|
review the Makefile to setup the LLVM path and version.
|
|
|
|
```
|
|
$ make
|
|
$ make tests
|
|
$ cd tests
|
|
```
|
|
|
|
If you do not specify a configuration file, the code will look for all
|
|
functions and their arguments. If you specify a configuration file,
|
|
it will specify the function and the argument to check. The tests/ex0*b....
|
|
files are those in which a configuration file was specified and the
|
|
ex0*a are those in which none was specified.. so you should see a difference
|
|
|
|
### Example running by hand
|
|
```
|
|
$ clang -g -emit-llvm -c -o FOO.bc FOO.c
|
|
$ opt -load built/libnpassert.so -null-ptr-assert -o FOO_assertall.bc < FOO.bc
|
|
$ opt -load built/libnpassert.so -null-ptr-assert -npa-target-config FOO.cfg -o FOO_assertbyconfigfile.bc < FOO.bc
|
|
$ clang -g -o FOO_assertall FOO_assertall.bc
|
|
$ clang -g -o FOO_assertbyconfigfile FOO_assertbyconfigfile.bc
|
|
```
|
|
|
|
The last clang steps generate an runnable executable.
|
|
Use llvm-dis on bitcode (.bc) files to get the human readable IR
|
|
to view the differences. One may also use the -npa-use-function option
|
|
which will tell the pass to create a separate function to perform
|
|
the assertion in.
|
|
|
|
So with the above instead of getting a crash like:
|
|
```
|
|
(gdb) r
|
|
Starting program: /home/hoser/code/npassert/test/ex02
|
|
|
|
Program received signal SIGSEGV, Segmentation fault.
|
|
0x0000000000400549 in foo (s=0x0) at test/ex02.c:16
|
|
16 return s->one;
|
|
(gdb) disass foo
|
|
Dump of assembler code for function foo:
|
|
0x0000000000400530 <+0>: push %rbp
|
|
0x0000000000400531 <+1>: mov %rsp,%rbp
|
|
0x0000000000400534 <+4>: sub $0x10,%rsp
|
|
0x0000000000400538 <+8>: mov %rdi,-0x8(%rbp)
|
|
0x000000000040053c <+12>: callq 0x400420 <random@plt>
|
|
0x0000000000400541 <+17>: mov %rax,-0x10(%rbp)
|
|
0x0000000000400545 <+21>: mov -0x8(%rbp),%rax
|
|
=> 0x0000000000400549 <+25>: mov (%rax),%eax
|
|
0x000000000040054b <+27>: add $0x10,%rsp
|
|
0x000000000040054f <+31>: pop %rbp
|
|
0x0000000000400550 <+32>: retq
|
|
End of assembler dump.
|
|
(gdb)
|
|
```
|
|
|
|
You would get a crash early in the function..
|
|
```
|
|
(gdb) r
|
|
Starting program: /home/hoser/code/npassert/test/ex02a
|
|
Program received signal SIGSEGV, Segmentation fault.
|
|
0x0000000000400554 in foo (s=0x0) at test/ex02.c:12
|
|
12 {
|
|
(gdb) disass foo
|
|
Dump of assembler code for function foo:
|
|
0x0000000000400530 <+0>: push %rbp
|
|
0x0000000000400531 <+1>: mov %rsp,%rbp
|
|
0x0000000000400534 <+4>: sub $0x20,%rsp
|
|
0x0000000000400538 <+8>: cmp $0x0,%rdi
|
|
0x000000000040053c <+12>: mov %rdi,-0x8(%rbp)
|
|
0x0000000000400540 <+16>: jne 0x400558 <foo+40>
|
|
0x0000000000400546 <+22>: xor %eax,%eax
|
|
0x0000000000400548 <+24>: mov %eax,%ecx
|
|
0x000000000040054a <+26>: mov %rsp,%rdx
|
|
0x000000000040054d <+29>: add $0xfffffffffffffff0,%rdx
|
|
0x0000000000400551 <+33>: mov %rdx,%rsp
|
|
=> 0x0000000000400554 <+36>: mov (%rcx),%eax
|
|
0x0000000000400556 <+38>: mov %eax,(%rdx)
|
|
0x0000000000400558 <+40>: mov %rsp,%rax
|
|
0x000000000040055b <+43>: add $0xfffffffffffffff0,%rax
|
|
0x000000000040055f <+47>: mov %rax,%rsp
|
|
0x0000000000400562 <+50>: mov %rsp,%rcx
|
|
0x0000000000400565 <+53>: add $0xfffffffffffffff0,%rcx
|
|
0x0000000000400569 <+57>: mov %rcx,%rsp
|
|
0x000000000040056c <+60>: mov -0x8(%rbp),%rdx
|
|
0x0000000000400570 <+64>: mov %rdx,(%rax)
|
|
0x0000000000400573 <+67>: mov %rax,-0x10(%rbp)
|
|
0x0000000000400577 <+71>: mov %rcx,-0x18(%rbp)
|
|
0x000000000040057b <+75>: callq 0x400420 <random@plt>
|
|
0x0000000000400580 <+80>: mov -0x18(%rbp),%rcx
|
|
0x0000000000400584 <+84>: mov %rax,(%rcx)
|
|
0x0000000000400587 <+87>: mov -0x10(%rbp),%rax
|
|
0x000000000040058b <+91>: mov (%rax),%rdx
|
|
0x000000000040058e <+94>: mov (%rdx),%eax
|
|
0x0000000000400590 <+96>: mov %rbp,%rsp
|
|
0x0000000000400593 <+99>: pop %rbp
|
|
0x0000000000400594 <+100>: retq
|
|
```
|
|
|
|
Or if you add the -npa-use-function option
|
|
```
|
|
(gdb) r
|
|
Starting program: /home/hoser/code/npassert/test/ex02c
|
|
|
|
Program received signal SIGSEGV, Segmentation fault.
|
|
0x00000000004005b3 in __NPA_assert_8__ ()
|
|
(gdb)
|
|
```
|
|
it will fault in the assertion function.
|