Disassemble and debug RISC-V and CHERI-RISC-V programs
This exercise steps you through disassembling and debugging RISC-V and CHERI-RISC-V programs. It draws attention to differences in program structure and code generation, particularly relating to control flow, between the two compilation targets.
First, use llvm-objdump
on the host (which you can find at
~/cheri/output/sdk/bin/llvm-objdump
, unless you have altered cheribuild
's
default paths) to disassemble and explore the two binaries from the previous
exercise:
- Using
llvm-objdump -dS
, disassemble theprint-pointer-riscv
andprint-pointer-cheri
binaries. - What jump instruction is used to call
printf()
inprint-pointer-riscv
? Where does the target address for that jump originate? - What jump instruction is used to call
printf()
inprint-pointer-cheri
? Where does the target capability for that jump originate? (Hint, you may find it helpful to add the-s
flag to yourllvm-objdump
command to see all sections.)
Next use GDB to explore binary execution for RISC-V:
- Run
print-pointer-riscv
under GDB, setting a breakpoint at the start ofprintf()
. Note: GDB can't find the run-time linker of binaries of the non-default ABI on its own so you need to invokeset program-interpreter /libexec/ld-elf64.so.1
before running the program. - Run the program and at the breakpoint, print out the value of the string pointer argument.
- Use
info proc mappings
in GDB to print out the layout of the process address space. - Print out the program counter (
info reg pc
). What memory mapping is it derived from?
And for CHERI-RISC-V:
- Run
print-pointer-cheri
under GDB, setting a breakpoint at the start ofprintf()
. - Print out the value of the string pointer argument.
- Use
info proc mappings
(in GDB) to print out the layout of the process address space. - Print out the program counter (
info reg pcc
). What memory mapping is it derived from? Where do its bounds appear to originate from? - Print out the register file using
info registers
. What mappings do the capabilities in the register file point to? Notice that some capabilities are labeled with(sentry)
(or(sealed)
in the case of older versions of GDB which do not distinguish sentries from other sealed capabilities). Sentry capabilities are sealed (cannot be modified or used to load or store), but can be used as a jump target (where they are unsealed and installed inpcc
). What implications does this have for attackers?