10
10
11
11
log = getLogger (__name__ )
12
12
13
- DEBUG = args .PLT_DEBUG or 0
14
-
15
- if not DEBUG :
16
- log .setLevel (logging .DEBUG + 1 )
17
13
18
14
def emulate_plt_instructions (elf , got , address , data , targets ):
19
15
"""Emulates instructions in ``data``
@@ -31,6 +27,9 @@ def emulate_plt_instructions(elf, got, address, data, targets):
31
27
"""
32
28
rv = {}
33
29
30
+ if not args .PLT_DEBUG :
31
+ log .setLevel (logging .DEBUG + 1 )
32
+
34
33
# Unicorn doesn't support big-endian for everything yet.
35
34
if elf .endian == 'big' and elf .arch == 'mips' :
36
35
data = packing .unpack_many (data , bits = 32 , endian = 'little' )
@@ -46,7 +45,7 @@ def emulate_plt_instructions(elf, got, address, data, targets):
46
45
log .debug (elf .disasm (pc , 4 ))
47
46
48
47
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 :])
50
49
51
50
if target in targets :
52
51
log .debug ("%#x -> %#x" , pc , target )
@@ -106,14 +105,14 @@ def prepare_unicorn_and_context(elf, got, address, data):
106
105
# Because of this, we have to support loading memory from this location.
107
106
#
108
107
# https://www.cr0.org/paper/mips.elf.external.resolution.txt
109
- magic_addr = 0xdbdbdbdb
108
+ magic_addr = 0x7c7c7c7c
110
109
111
110
if elf .arch == 'mips' :
112
111
# Map the GOT so that MIPS can access it
113
112
p_magic = packing .p32 (magic_addr )
114
113
start = got & (~ 0xfff )
115
114
try :
116
- uc .mem_map (start , start + 0x1000 )
115
+ uc .mem_map (start , 0x1000 )
117
116
except Exception :
118
117
# Ignore double-mapping
119
118
pass
@@ -125,7 +124,7 @@ def prepare_unicorn_and_context(elf, got, address, data):
125
124
# the magic address.
126
125
start = magic_addr & (~ 0xfff )
127
126
try :
128
- uc .mem_map (start , start + 0x1000 )
127
+ uc .mem_map (start , 0x1000 )
129
128
except Exception :
130
129
# Ignore double-mapping
131
130
pass
@@ -134,14 +133,15 @@ def prepare_unicorn_and_context(elf, got, address, data):
134
133
135
134
return uc , uc .context_save ()
136
135
137
- def emulate_plt_instructions_inner (uc , elf , got , pc , data , targets ):
136
+
137
+ def emulate_plt_instructions_inner (uc , elf , got , pc , data ):
138
138
import unicorn as U
139
139
140
140
# Hook invalid addresses and any accesses out of the specified address range
141
141
stopped_addr = []
142
142
143
143
# For MIPS. Explanation at prepare_unicorn_and_context.
144
- magic_addr = 0xdbdbdbdb
144
+ magic_addr = 0x7c7c7c7c
145
145
146
146
def hook_mem (uc , access , address , size , value , user_data ):
147
147
# Special case to allow MIPS to dereference the _DYNAMIC pointer
@@ -154,14 +154,15 @@ def hook_mem(uc, access, address, size, value, user_data):
154
154
return False
155
155
156
156
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 ),
159
159
]
160
160
161
161
# callback for tracing instructions
162
162
# 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))
165
166
166
167
# For Intel, set the value of EBX
167
168
if elf .arch == 'i386' :
@@ -183,7 +184,7 @@ def hook_mem(uc, access, address, size, value, user_data):
183
184
184
185
if elf .arch == 'mips' :
185
186
pc = uc .reg_read (U .mips_const .UC_MIPS_REG_PC )
186
- if pc + 1 == magic_addr :
187
+ if pc == magic_addr :
187
188
t8 = uc .reg_read (U .mips_const .UC_MIPS_REG_T8 )
188
189
stopped_addr .append (elf ._mips_got .get (t8 , 0 ))
189
190
0 commit comments