Post

Single branching in ROP

Single branching in ver A

Notes: All addresses mentioned below is for verA

Traditional Branching Method (1:3B8EH Method)

  1. Initial Setup: Single branching method requires a boolean-like address and stores the result into register R0 to 0x00 or 0x01 accordingly.

    Below are some basic boolean addresses:

    • 0:9AE6: If ER0 = ER2, then R0 = 1, else R0 = 0. Additionally, if R0 is between 0x4E and 0x5F, R0 is also set to 1, and the function returns via RT.
      (Since the keycode value KI is not expected to fall within 0x4E to 0x5F, this address is suitable for keycode checks.)

    • 1:9618: If ER2 = ER4, then R0 = 1; otherwise, R0 = 0.
      Note: This function resets all registers, including LR.

    • 0:C790: If ER0 > ER2, then R0 = 0; otherwise, R0 = 1.
      The function returns via RT.

    • 0:C7A8: If ER2 > ER0, then R0 = 0; otherwise, R0 = 1.
      The function returns via RT.

  2. Branching: After assigning a flag to R0, call the 1:3B8E function.
    • This function multiplies R0 with R2, and storing the result in ER0
    • It then sets ER2 to the value of ER0 and add an offset of ER4 to ER0.
    • The function ends with RT so make sure to setlr before calling it.

  3. Address Setup: Place the smaller jump address in ER4 and the difference between the jump addresses in R2. When calling 1:3B8E: If R0 = 0: Multiplying R0 by R2 yields 0, and adding it to ER4 still returns ER4, giving the smaller address in ER0 If R0 = 1: Multiplying R0 by R2 gives R2, which is the address difference, and adding it to ER4 returns the larger address in ER0

  4. Jumping: After obtaining the jump address in ER0, call 1:7B22 to load the address into ER14 and jump with MOV SP, ER14. The brach is completed. However it ends with POP XR0 so all addresses have to pad with -4 bytes

Improved Method (1:3B7E Method):

  1. Address Setup: After assigning the flag to R0 (aka completing the boolean step):
    • Call 1:4BD6 to set R2 to R0 (MOV ER2, ER0)
    • Call 1:893A and assign the smaller address in ER0 and the address difference in R4

  2. Jumping:
    • Call 1:3B7E, the logic behind this is relatively similar to the former method. It stores the jump address in ER4 (The instruction MOV R8, R8 serves no actual purpose here.)

    • Finally, call 1:939E to set SP to ER4 and jump, completing the branch.

  3. Adjustments:
    • Note that after setting SP to ER4, the actual jump occurs to ER4 + 0x3E (ADD SP, +32H and pop 16 bytes)

Comparison Between Methods:

  1. Advantages of the new method:
    1. 1:3B7E can use 1:893A to assign values to two registers in one call.
    2. Does not require passing ER0 to ER14
    3. Takes up less memory than the old method
  2. Advantages of the old method:
    1. 1:3B8E stores the jump address in ER14, allowing more options to choose jump functions to control the subsequent POP instructions.
    2. The new method 1:3B7E can only use 1:939E for jumping, which resets XR4 and QR8 during the POP instructions.