Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unicorn 2 regression: ARM mode changes in the Python don't work #1525

Closed
gerph opened this issue Jan 4, 2022 · 1 comment
Closed

Unicorn 2 regression: ARM mode changes in the Python don't work #1525

gerph opened this issue Jan 4, 2022 · 1 comment
Labels

Comments

@gerph
Copy link
Contributor

gerph commented Jan 4, 2022

#1520 might have addressed the privilege escalation, but now my OS won't even being to initialise because regular mode changes don't work.

Test environment

Unicorn 2 'dev' branch, sha 47097b55b79492c75f27ffb85f93aea2a3191dd7.

Sample code to show problem

#!/usr/bin/env python
# Sample code for ARM of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>

import sys
from unicorn import *
from unicorn.arm_const import *

reg_map = [
        UC_ARM_REG_R0,
        UC_ARM_REG_R1,
        UC_ARM_REG_R2,
        UC_ARM_REG_R3,
        UC_ARM_REG_R4,
        UC_ARM_REG_R5,
        UC_ARM_REG_R6,
        UC_ARM_REG_R7,
        UC_ARM_REG_R8,
        UC_ARM_REG_R9,
        UC_ARM_REG_R10,
        UC_ARM_REG_R11,
        UC_ARM_REG_R12,
        UC_ARM_REG_SP,
        UC_ARM_REG_LR,
        UC_ARM_REG_PC,
    ]
arm_names = [
        'r0', 'r1', 'r2', 'r3',
        'r4', 'r5', 'r6', 'r7',
        'r8', 'r9', 'r10', 'r11',
        'r12', 'sp', 'lr', 'pc'
    ]


def dump_registers(uc):
    print("Registers: ")
    for rn in range(0, 16):
        value = uc.reg_read(reg_map[rn])
        sys.stdout.write("  %3s : 0x%08x" % (arm_names[rn], value))
        if rn % 4 == 3:
            sys.stdout.write("\n")
    print("  CPSR = 0x{:08x}".format(uc.reg_read(UC_ARM_REG_CPSR)))
    print("  SPSR = 0x{:08x}".format(uc.reg_read(UC_ARM_REG_SPSR)))


# Test ARM
def test_arm():
    print("Testing under Unicorn : {!r}".format(uc_version()))
    print("Header version: {!r}".format((UC_VERSION_MAJOR, UC_VERSION_MINOR, UC_VERSION_EXTRA)))

    print("Changing ARM modes")
    try:
        # Initialize emulator in ARM mode
        mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)

        # initialize machine registers in different modes
        mu.reg_write(UC_ARM_REG_CPSR, 0x40000093)   # Current mode = SVC32 mode
        mu.reg_write(UC_ARM_REG_R13, 0x12345678)    # SVC stack value
        mu.reg_write(UC_ARM_REG_R14, 0x00102220)    # SVC link value
        print("--- Should be in SVC32, with R13 = 0x12345678")
        dump_registers(mu)

        mu.reg_write(UC_ARM_REG_CPSR, 0x4000009b)   # Current mode = UND32 mode
        mu.reg_write(UC_ARM_REG_SPSR, 0x40000093)   # Saved mode = SVC32 mode
        mu.reg_write(UC_ARM_REG_R13, 0xDEAD0000)    # UND stack value
        mu.reg_write(UC_ARM_REG_R14, 0x00509998)    # UND link value
        print("--- Should be in UND32, with R13 = 0xDEAD0000")
        dump_registers(mu)

        mu.reg_write(UC_ARM_REG_CPSR, 0x40000090)   # Current mode = USR32 mode
        mu.reg_write(UC_ARM_REG_R13, 0x0010000)     # USR stack value
        mu.reg_write(UC_ARM_REG_R14, 0x0001234)     # USR link value
        print("--- Should be in USR32, with R13 = 0x00010000")
        dump_registers(mu)

        mu.reg_write(UC_ARM_REG_CPSR, 0x40000093)   # Current mode = SVC32 mode
        print("--- Should be in SVC32, with R13 = 0x12345678")
        dump_registers(mu)

    except UcError as e:
        print("ERROR: %s" % e)


if __name__ == '__main__':
    test_arm()

Unicorn 1 output (working)

charles@Laputa ~/projects/RO/pyromaniac (master)> lpython test_mode_change_2.py 
Testing under Unicorn : (1, 0, 256L)
Header version: (1, 0, 2)
Changing ARM modes
--- Should be in SVC32, with R13 = 0x12345678
Registers: 
   r0 : 0x00000000   r1 : 0x00000000   r2 : 0x00000000   r3 : 0x00000000
   r4 : 0x00000000   r5 : 0x00000000   r6 : 0x00000000   r7 : 0x00000000
   r8 : 0x00000000   r9 : 0x00000000  r10 : 0x00000000  r11 : 0x00000000
  r12 : 0x00000000   sp : 0x12345678   lr : 0x00102220   pc : 0x00000000
  CPSR = 0x40000093
  SPSR = 0x00000000
--- Should be in UND32, with R13 = 0xDEAD0000
Registers: 
   r0 : 0x00000000   r1 : 0x00000000   r2 : 0x00000000   r3 : 0x00000000
   r4 : 0x00000000   r5 : 0x00000000   r6 : 0x00000000   r7 : 0x00000000
   r8 : 0x00000000   r9 : 0x00000000  r10 : 0x00000000  r11 : 0x00000000
  r12 : 0x00000000   sp : 0xdead0000   lr : 0x00509998   pc : 0x00000000
  CPSR = 0x4000009b
  SPSR = 0x40000093
--- Should be in USR32, with R13 = 0x00010000
Registers: 
   r0 : 0x00000000   r1 : 0x00000000   r2 : 0x00000000   r3 : 0x00000000
   r4 : 0x00000000   r5 : 0x00000000   r6 : 0x00000000   r7 : 0x00000000
   r8 : 0x00000000   r9 : 0x00000000  r10 : 0x00000000  r11 : 0x00000000
  r12 : 0x00000000   sp : 0x00010000   lr : 0x00001234   pc : 0x00000000
  CPSR = 0x40000090
  SPSR = 0x00000000
--- Should be in SVC32, with R13 = 0x12345678
Registers: 
   r0 : 0x00000000   r1 : 0x00000000   r2 : 0x00000000   r3 : 0x00000000
   r4 : 0x00000000   r5 : 0x00000000   r6 : 0x00000000   r7 : 0x00000000
   r8 : 0x00000000   r9 : 0x00000000  r10 : 0x00000000  r11 : 0x00000000
  r12 : 0x00000000   sp : 0x12345678   lr : 0x00102220   pc : 0x00000000
  CPSR = 0x40000093
  SPSR = 0x00000000

Observe the CPSR at the end is SVC32 (0x93) - as requested by the python code.

Unicorn 2 output (failing)

Testing under Unicorn : (2, 0, 33554437L)
Header version: (2, 0, 5)
Changing ARM modes
--- Should be in SVC32, with R13 = 0x12345678
Registers: 
   r0 : 0x00000000   r1 : 0x00000000   r2 : 0x00000000   r3 : 0x00000000
   r4 : 0x00000000   r5 : 0x00000000   r6 : 0x00000000   r7 : 0x00000000
   r8 : 0x00000000   r9 : 0x00000000  r10 : 0x00000000  r11 : 0x00000000
  r12 : 0x00000000   sp : 0x12345678   lr : 0x00102220   pc : 0x00000000
  CPSR = 0x40000093
  SPSR = 0x00000000
--- Should be in UND32, with R13 = 0xDEAD0000
Registers: 
   r0 : 0x00000000   r1 : 0x00000000   r2 : 0x00000000   r3 : 0x00000000
   r4 : 0x00000000   r5 : 0x00000000   r6 : 0x00000000   r7 : 0x00000000
   r8 : 0x00000000   r9 : 0x00000000  r10 : 0x00000000  r11 : 0x00000000
  r12 : 0x00000000   sp : 0xdead0000   lr : 0x00509998   pc : 0x00000000
  CPSR = 0x4000009b
  SPSR = 0x40000093
--- Should be in USR32, with R13 = 0x00010000
Registers: 
   r0 : 0x00000000   r1 : 0x00000000   r2 : 0x00000000   r3 : 0x00000000
   r4 : 0x00000000   r5 : 0x00000000   r6 : 0x00000000   r7 : 0x00000000
   r8 : 0x00000000   r9 : 0x00000000  r10 : 0x00000000  r11 : 0x00000000
  r12 : 0x00000000   sp : 0x00010000   lr : 0x00001234   pc : 0x00000000
  CPSR = 0x40000090
  SPSR = 0x00000000
--- Should be in SVC32, with R13 = 0x12345678
Registers: 
   r0 : 0x00000000   r1 : 0x00000000   r2 : 0x00000000   r3 : 0x00000000
   r4 : 0x00000000   r5 : 0x00000000   r6 : 0x00000000   r7 : 0x00000000
   r8 : 0x00000000   r9 : 0x00000000  r10 : 0x00000000  r11 : 0x00000000
  r12 : 0x00000000   sp : 0x12345678   lr : 0x00102220   pc : 0x00000000
  CPSR = 0x40000090
  SPSR = 0x00000000

Observe that we're still in USR32 mode (0x90) which is wrong, but the registers have switched to those banked for SVC32 mode (which is right).

@gerph gerph changed the title Unicorn 2 regression: mode changes in the Python don't work Unicorn 2 regression: ARM mode changes in the Python don't work Jan 4, 2022
@wtdcode wtdcode added the bug label Jan 5, 2022
wtdcode added a commit that referenced this issue Jan 5, 2022
@wtdcode
Copy link
Member

wtdcode commented Jan 5, 2022

Fixed in 7a886f5

@wtdcode wtdcode closed this as completed Jan 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants