def
patch_gen(instrs, loc_db, nop_addrs, link):
final_patch
=
b""
start_addr
=
instrs[
0
].offset
for
instr
in
instrs:
if
instr.offset
not
in
nop_addrs:
if
instr.is_subcall():
patch_addr
=
start_addr
+
len
(final_patch)
tgt
=
loc_db.get_location_offset(instr.args[
0
].loc_key)
_log.info(
"CALL %#x"
%
tgt)
call_patch_str
=
"CALL %s"
%
rel(tgt, patch_addr)
_log.debug(
"call patch : %s"
%
call_patch_str)
call_patch
=
asmb(call_patch_str, loc_db)
final_patch
+
=
call_patch
_log.debug(
"call patch asmb : %s"
%
encode_hex(call_patch))
else
:
final_patch
+
=
instr.b
patch_addr
=
start_addr
+
len
(final_patch)
_log.debug(
"jmps patch_addr : %#x"
, patch_addr)
jmp_patches
=
b""
if
'cond'
in
link:
t_addr
=
int
(link[
'true_next'
],
16
)
f_addr
=
int
(link[
'false_next'
],
16
)
jcc
=
link[
'cond'
].replace(
'CMOV'
,
'J'
)
_log.info(
"%s %#x"
%
(jcc, t_addr))
_log.info(
"JMP %#x"
%
f_addr)
patch1_str
=
"%s %s"
%
(jcc, rel(t_addr, patch_addr))
jmp_patches
+
=
asmb(patch1_str, loc_db)
patch_addr
+
=
len
(jmp_patches)
patch2_str
=
"JMP %s"
%
(rel(f_addr, patch_addr))
jmp_patches
+
=
asmb(patch2_str, loc_db)
_log.debug(
"jmp patches : %s; %s"
%
(patch1_str, patch2_str))
else
:
n_addr
=
int
(link[
'next'
],
16
)
_log.info(
"JMP %#x"
%
n_addr)
patch_str
=
"JMP %s"
%
rel(n_addr, patch_addr)
jmp_patches
=
asmb(patch_str, loc_db)
_log.debug(
"jmp patches : %s"
%
patch_str)
_log.debug(
"jmp patches asmb : %s"
%
encode_hex(jmp_patches))
final_patch
+
=
jmp_patches
return
final_patch