Matt Suiche 0c9e8df91c Add 'Security Research and Development with LLVM - Andrew Reiter/' from commit '0605b5174c2bc286d3e95d6c0df620800bef96c7'
git-subtree-dir: Security Research and Development with LLVM - Andrew Reiter
git-subtree-mainline: aa7a9fc1e16c3c5be7ba312c4b4e37775e005101
git-subtree-split: 0605b5174c2bc286d3e95d6c0df620800bef96c7
2017-04-29 17:11:06 +04:00

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.