Skip to content

Commit 03df22a

Browse files
authored
Fix MIPS PLT on newer Unicorn versions (#1932)
Apparently it is us who used unicorn The Wrong Way, e.g. trying to fetch instructions @ 0xdbdbdbdb, which is both unaligned and high-address-space. Unicorn just changed the exception to throw exception with the address of an offending jump instruction, instead of the incorrect address. Making the debugs actually work and changing address to 0x7c7c7c7c solves the issue. Closes #1538 Ping pentoo/pentoo-overlay#734 @blshkv
1 parent bbdb5db commit 03df22a

File tree

2 files changed

+18
-16
lines changed

2 files changed

+18
-16
lines changed

pwnlib/elf/plt.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010

1111
log = getLogger(__name__)
1212

13-
DEBUG = args.PLT_DEBUG or 0
14-
15-
if not DEBUG:
16-
log.setLevel(logging.DEBUG + 1)
1713

1814
def emulate_plt_instructions(elf, got, address, data, targets):
1915
"""Emulates instructions in ``data``
@@ -31,6 +27,9 @@ def emulate_plt_instructions(elf, got, address, data, targets):
3127
"""
3228
rv = {}
3329

30+
if not args.PLT_DEBUG:
31+
log.setLevel(logging.DEBUG + 1)
32+
3433
# Unicorn doesn't support big-endian for everything yet.
3534
if elf.endian == 'big' and elf.arch == 'mips':
3635
data = packing.unpack_many(data, bits=32, endian='little')
@@ -46,7 +45,7 @@ def emulate_plt_instructions(elf, got, address, data, targets):
4645
log.debug(elf.disasm(pc, 4))
4746

4847
uc.context_restore(ctx)
49-
target = emulate_plt_instructions_inner(uc, elf, got, pc, data[i*4:], targets)
48+
target = emulate_plt_instructions_inner(uc, elf, got, pc, data[i*4:])
5049

5150
if target in targets:
5251
log.debug("%#x -> %#x", pc, target)
@@ -106,14 +105,14 @@ def prepare_unicorn_and_context(elf, got, address, data):
106105
# Because of this, we have to support loading memory from this location.
107106
#
108107
# https://www.cr0.org/paper/mips.elf.external.resolution.txt
109-
magic_addr = 0xdbdbdbdb
108+
magic_addr = 0x7c7c7c7c
110109

111110
if elf.arch == 'mips':
112111
# Map the GOT so that MIPS can access it
113112
p_magic = packing.p32(magic_addr)
114113
start = got & (~0xfff)
115114
try:
116-
uc.mem_map(start, start+0x1000)
115+
uc.mem_map(start, 0x1000)
117116
except Exception:
118117
# Ignore double-mapping
119118
pass
@@ -125,7 +124,7 @@ def prepare_unicorn_and_context(elf, got, address, data):
125124
# the magic address.
126125
start = magic_addr & (~0xfff)
127126
try:
128-
uc.mem_map(start, start+0x1000)
127+
uc.mem_map(start, 0x1000)
129128
except Exception:
130129
# Ignore double-mapping
131130
pass
@@ -134,14 +133,15 @@ def prepare_unicorn_and_context(elf, got, address, data):
134133

135134
return uc, uc.context_save()
136135

137-
def emulate_plt_instructions_inner(uc, elf, got, pc, data, targets):
136+
137+
def emulate_plt_instructions_inner(uc, elf, got, pc, data):
138138
import unicorn as U
139139

140140
# Hook invalid addresses and any accesses out of the specified address range
141141
stopped_addr = []
142142

143143
# For MIPS. Explanation at prepare_unicorn_and_context.
144-
magic_addr = 0xdbdbdbdb
144+
magic_addr = 0x7c7c7c7c
145145

146146
def hook_mem(uc, access, address, size, value, user_data):
147147
# Special case to allow MIPS to dereference the _DYNAMIC pointer
@@ -154,14 +154,15 @@ def hook_mem(uc, access, address, size, value, user_data):
154154
return False
155155

156156
hooks = [
157-
uc.hook_add(U.UC_HOOK_MEM_READ, hook_mem, stopped_addr),
158-
uc.hook_add(U.UC_HOOK_MEM_UNMAPPED, hook_mem, stopped_addr)
157+
uc.hook_add(U.UC_HOOK_MEM_READ | U.UC_HOOK_MEM_READ_UNMAPPED,
158+
hook_mem, stopped_addr),
159159
]
160160

161161
# callback for tracing instructions
162162
# def hook_code(uc, address, size, user_data):
163-
# print(">>> Tracing instruction at 0x%x, instruction size = 0x%x, data=%r" %(address, size, uc.mem_read(address, size)))
164-
# uc.hook_add(U.UC_HOOK_CODE, hook_code)
163+
# print(">>> Tracing instruction at %#x, instr size = %#x, data=%r"
164+
# % (address, size, uc.mem_read(address, size)))
165+
# hooks.append(uc.hook_add(U.UC_HOOK_CODE, hook_code))
165166

166167
# For Intel, set the value of EBX
167168
if elf.arch == 'i386':
@@ -183,7 +184,7 @@ def hook_mem(uc, access, address, size, value, user_data):
183184

184185
if elf.arch == 'mips':
185186
pc = uc.reg_read(U.mips_const.UC_MIPS_REG_PC)
186-
if pc+1 == magic_addr:
187+
if pc == magic_addr:
187188
t8 = uc.reg_read(U.mips_const.UC_MIPS_REG_T8)
188189
stopped_addr.append(elf._mips_got.get(t8, 0))
189190

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@
6060
'psutil>=3.3.0',
6161
'intervaltree>=3.0',
6262
'sortedcontainers',
63-
'unicorn>=1.0.2rc1,<1.0.2rc4', # see unicorn-engine/unicorn#1100, unicorn-engine/unicorn#1170, Gallopsled/pwntools#1538
63+
# see unicorn-engine/unicorn#1100 and #1170
64+
'unicorn>=1.0.2rc1',
6465
'six>=1.12.0',
6566
'rpyc',
6667
'colored_traceback',

0 commit comments

Comments
 (0)