Let’s quickly recap what we’ve done:
main
-containing compilation module to:
main
that initialize this file pointerload/store
instructionsLet’s see all this in action:
Let’s look at two files:
main.c
func.c
When we run these files unmodified:
> clang main.c func.c -o unmodified
> ./unmodified
Address of ptr: 0x117d2a0, value of ptr: 0x5
5
Address of ptr: 0x117d2a0, value of ptr: 0x100
And with our pass:
> clang -S -emit-llvm main.c func.c
> opt -load-pass-plugin ./lib/libMemoryTrace.so -passes=memory-trace func.ll -S -o modified_func.ll
Did not find main in func.ll
> opt -load-pass-plugin ./lib/libMemoryTrace.so -passes=memory-trace main.ll -S -o modified_main.ll
Found main in module main.ll
> clang modified_main.ll modified_func.ll -o modified
>./modified
Address of ptr: 0x1366490, value of ptr: 0x5
5
Address of ptr: 0x1366490, value of ptr: 0x100
And - finally:
> cat memory-traces.log
[Write] Wrote value 0x13652a0 to address 0x4040d8
[Write] Wrote value 0x0 to address 0x7fff7305510c
[Write] Wrote value 0x1366490 to address 0x7fff73055100
[Read] Read value 0x1366490 from address 0x7fff73055100
[Write] Wrote value 0x5 to address 0x1366490
[Read] Read value 0x1366490 from address 0x7fff73055100
[Read] Read value 0x1366490 from address 0x7fff73055100
[Read] Read value 0x5 from address 0x1366490
[Read] Read value 0x1366490 from address 0x7fff73055100
[Read] Read value 0x5 from address 0x1366490
[Read] Read value 0x1366490 from address 0x7fff73055100
[Write] Wrote value 0x1366490 to address 0x7fff73055098
[Read] Read value 0x1366490 from address 0x7fff73055098
[Write] Wrote value 0x100 to address 0x1366490
[Read] Read value 0x1366490 from address 0x7fff73055100
[Read] Read value 0x1366490 from address 0x7fff73055100
[Read] Read value 0x100 from address 0x1366490
We’ve traced all memory accesses in our program! We can see both memory reads & writes from/to the stack - and our own explicit reads & writes (notice the lines that contain 0x100
/ 0x5
).
Let’s finish up with some conclusions.