Skip to content
New issue

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

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

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants