ROP gadget "stub" printing
While writing ROP chain we often need to do menial work to track registers and such. To speed up the process without invoking complex solvers we could generate "stubs" that are helpful from the first sight and can be understood immediately.
For example, for the following gadget:
0x00021ff8 0000a0e3 mov r0, 0
0x00021ffc 3080bde8 pop {r4, r5, pc}
Gadget size: 8
the "stub" could look like:
# Overwrites r0
chain += b'\xf8\x1f\x02\x00' # <- gadget address 0x21ff8
chain += b'\x00\x00\x00\x00' # r4
chain += b'\x00\x00\x00\x00' # r5
chain += b'\x00\x00\x00\x00' # pc <- next gadget address
The needed information is at RzRopGadgetInfo (can be extended if necessary)
We also could think about automatic stack adjustment in such a stub if gadget changes the stack, e.g.:
chain += b'\x00' * 0x14
Another option, would be using struct.pack() to make addresses more readable, for example:
# Overwrites r0
chain += struct.pack("<I", 0x21ff8) # <- gadget address
chain += b'\x00\x00\x00\x00' # r4
chain += b'\x00\x00\x00\x00' # r5
chain += struct.pack("<I", 0) # pc <- next gadget address
where struct.pack(<fmt>) determined by the target architecture bitness automatically.
Depending on how the result would look like, it makes sense to also include the gadget disassembly in the comments, e.g.:
# Overwrites r0
chain += struct.pack("<I", 0x21ff8) # <- gadget address "mov r0, 0; pop {r4, r5, pc}"
chain += b'\x00\x00\x00\x00' # r4
chain += b'\x00\x00\x00\x00' # r5
chain += struct.pack("<I", 0) # pc <- next gadget address
We already have such helpers for the raw bytestream (see pc subcommands), would make sense to do the same for the ROP.
It might even be possible to generate such stubs/chains using various languages that are already supported by pc commands:
╭pc [<len>] # Generate a C/C++ byte array.
│pca [<len>] # Generate a byte array in GAS assembly.
│pcA [<len>] # Generate a byte array in GAS assembly with instructions in comments.
│pcb [<len>] # Generate a bash script with the byte array.
│pcg [<len>] # Generate a Golang byte array.
│pcJ [<len>] # Generate a Java byte array.
│pcj [<len>] # Generate a JSON byte array.
│pck [<len>] # Generate a Kotlin byte array.
│pcn [<len>] # Generate a NodeJS buffer.
│pco [<len>] # Generate a Objective-C/C++ byte array.
│pcp [<len>] # Generate a Python byte array.
│pcr [<len>] # Generate a Rust byte array.
│pcs [<len>] # Generate a Swift byte array.
I would like to work on this issue, please assign it to me.
You can just work on it. Please see CONTRIBUTING.md for how to start.
Hello everyone, This is a high-value feature that will significantly speed up ROP chain development. I would like to take this on immediately. My Approach: Integration with Existing Tools: The most logical path is to integrate the new ROP stub generation logic with the existing multi-language payload output mechanism (the pc subcommands).[1] This will allow us to immediately support C, Python (struct.pack), and others. Data Source: I will use the information already available in RzRopGadgetInfo (and extend it if necessary) to accurately track register changes (mov r0, 0) and stack adjustments. Output Formatting: I will focus on generating highly readable output, ensuring comments include the gadget's disassembly and the necessary data fields for popped registers (r4, r5, etc.).