def
get_double_branch(uc, ins_stack):
ins_help
=
InsHelp()
cond
=
''
for
tup
in
ins_stack[::
-
1
]:
addr
=
tup[
0
]
context
=
tup[
1
]
ins
=
list
(ins_help.disasm(bin_data[addr: addr
+
5
], addr,
False
))[
0
]
if
ins.mnemonic.lower()
=
=
'br'
and
flag_br
=
=
False
:
flag_br
=
True
br_reg
=
ins.operands[
0
].reg
if
flag_br
=
=
True
and
(ins.mnemonic.lower()
=
=
'add'
or
ins.mnemonic.lower()
=
=
'sub'
) \
and
ins.operands[
0
].reg
=
=
br_reg
and
flag_sub_add
=
=
False
:
if
ins.operands[
1
].
type
=
=
1
and
ins.operands[
2
].
type
=
=
1
:
op_reg1
=
ins.operands[
1
].reg
op_reg2
=
ins.operands[
2
].reg
flag_sub_add
=
True
if
flag_sub_add
=
=
True
and
ins.mnemonic.lower()
=
=
'csel'
and
ins.operands[
0
].reg
=
=
op_reg2 \
and
flag_csel1
=
=
False
:
cond
=
ins.op_str.split(
', '
)[
-
1
]
regname1
=
ins.reg_name(ins.operands[
1
].reg)
regname2
=
ins.reg_name(ins.operands[
2
].reg)
reg2_value1
=
0
if
regname1.lower()
=
=
'xzr'
else
context[reg_ctou(regname1)
-
arm64_const.UC_ARM64_REG_X0]
reg2_value2
=
0
if
regname2.lower()
=
=
'xzr'
else
context[reg_ctou(regname2)
-
arm64_const.UC_ARM64_REG_X0]
flag_csel1
=
True
if
flag_sub_add
=
=
True
and
ins.mnemonic.lower()
=
=
'ldr'
and
ins.operands[
0
].reg
=
=
op_reg1 \
and
flag_ldr
=
=
False
:
pattern
=
r
'\[(.*?)\]'
matches
=
re.findall(pattern, ins.op_str)
assert
len
(matches)
=
=
1
,
'not find []: %x\t%s\t%s'
%
(addr, ins.mnemonic, ins.op_str)
op2_str
=
matches[
0
]
regs
=
op2_str.split(
', '
)
assert
len
(regs)
=
=
2
,
'ins invalid!: %x\t%s\t%s'
%
(addr, ins.mnemonic, ins.op_str)
table_base
=
context[reg_ctou(regs[
0
])
-
arm64_const.UC_ARM64_REG_X0]
op_reg3
=
reg_ctou(regs[
1
])
flag_ldr
=
True
if
flag_ldr
=
=
True
and
ins.mnemonic.lower()
=
=
'csel'
and
reg_ctou(ins.reg_name(ins.operands[
0
].reg))
=
=
op_reg3 \
and
flag_csel2
=
=
False
:
regname1
=
ins.reg_name(ins.operands[
1
].reg)
regname2
=
ins.reg_name(ins.operands[
2
].reg)
reg3_value1
=
0
if
regname1.lower()
=
=
'xzr'
else
context[reg_ctou(regname1)
-
arm64_const.UC_ARM64_REG_X0]
reg3_value2
=
0
if
regname2.lower()
=
=
'xzr'
else
context[reg_ctou(regname2)
-
arm64_const.UC_ARM64_REG_X0]
flag_csel2
=
True
if
flag_csel1
=
=
True
and
flag_csel2
=
=
True
:
barr1
=
uc.mem_read(table_base
+
reg3_value1,
8
)
base1
=
struct.unpack(
'q'
,barr1)
offset1
=
base1[
0
]
-
reg2_value1
barr2
=
uc.mem_read(table_base
+
reg3_value2,
8
)
base2
=
struct.unpack(
'q'
,barr2)
offset2
=
base2[
0
]
-
reg2_value2
return
(offset1, offset2, get_context(uc), cond)
else
:
return
None