Pandora Ransomware

[TOC]

overview

First of all, I love oalabs. Below of code is copied from his research, and I get a lot from just repeat it. And maybe there are also bogus-control-flow in this sample however.

Sample: 5b56c5d86347e164c6e571c86dbf5b1535eae6b979fede6ed66b01e79ea33b7b

Unpacked sample: 2619862c382d3e375f13f3859c6ab44db1a4bce905b4a617df2390fbf36902e7 on the malshare(by the oalabs)

References

Dumpulator

according to the jmp [register]

Our approach is to seperate the dispatcher bb from the payload bb. For each dispatcher bb the code is emulated with all conditions to generate the conditional jump addresses. The bb is then replaced with a simple compare and conditional jmp. Emulation is done with Dumpulator.

Once the dispatcher has been deobfuscated we should be able to see the control flow for the payload bb, and futher simplify the dispatcher using more traditional tools, possibly removing it completely.

  • if the jump is relative it’s for a code bb
  • if the jump is register then it’s a cf bb
  • if there is a ret this is the end

build a table of bb the start is next head after jmp, end is jmp emulate patch the jmp for each table entry

IDA Produce Basic Block Table

There are two dispatcher bb formats, one that uses cmovl, cmovz, and one that uses setl and setz. We need to match both patterns and determine the type of condition for our jmp statement, and the eax cmp value. For each bb record the following information so it can be used in our emulator.

  • bb start
  • bb end
  • add cmov instruction
  • type of cmov instruction (l,z)
  • eax cmp value
  • jmp register

Results: (bb_start, bb_end, eax_value, jmp_condition,jmp_condition_address, jmp_register)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# Basic blocks for dispatcher
bb_table = []
# List of addresses of original code basic blocks
bb_orig_table = []
ptr = 0x00007FF6654A67F0
end = 0x00007FF6654A70D0
bb_start = ptr
while ptr <= end:
if print_insn_mnem(ptr) == 'jmp':
op_type = idc.get_operand_type(ptr, 0)
if op_type == o_reg:
# This is a cf bb save it
reg_name = print_operand(ptr, 0)
# Get eax value
first_instruction = print_insn_mnem(bb_start)
if first_instruction == 'cmp':
eax_cmp_value = get_operand_value(bb_start,1)
# Find cmov instruction
bb_ptr = bb_start
jmp_condition = None
jmp_condition_address = None
while bb_ptr < ptr:
if 'cmovl' == print_insn_mnem(bb_ptr):
jmp_condition = 'cmovl'
break
elif 'cmovz' == print_insn_mnem(bb_ptr):
jmp_condition = 'cmovz'
break
bb_ptr = next_head(bb_ptr)
jmp_condition_address = bb_ptr
# Check results of cmov find
if jmp_condition is None:
# This bb doesn't match our pattern skip it
print(f"BB at {hex(bb_start)} doesn't contain cmovl or cmovz, skip it")
ptr = next_head(ptr)
while not is_code(ida_bytes.get_full_flags(ptr)):
ptr = next_head(ptr)
bb_start = ptr
continue
elif first_instruction == 'xor':
# assume next instruction is the cmp, we should check
ptr_cmp = next_head(bb_start)
if "cmp" != print_insn_mnem(ptr_cmp):
# This bb doesn't match our pattern skip it
print(f"BB at {hex(bb_start)} doesn't contain have cmp after xor, skip it")
ptr = next_head(ptr)
while not is_code(ida_bytes.get_full_flags(ptr)):
ptr = next_head(ptr)
bb_start = ptr
continue
eax_cmp_value = get_operand_value(ptr_cmp,1)
# Find cmov instruction
bb_ptr = bb_start
jmp_condition = None
jmp_condition_address = None
while bb_ptr < ptr:
if 'setl' == print_insn_mnem(bb_ptr):
jmp_condition = 'setl'
break
elif 'setz' == print_insn_mnem(bb_ptr):
jmp_condition = 'setz'
break
elif 'setnz' == print_insn_mnem(bb_ptr):
jmp_condition = 'setnz'
break
bb_ptr = next_head(bb_ptr)
jmp_condition_address = bb_ptr
# Check results of cmov find
if jmp_condition is None:
# This bb doesn't match our pattern skip it
print(f"BB at {hex(bb_start)} doesn't contain setl or setz, skip it")
ptr = next_head(ptr)
while not is_code(ida_bytes.get_full_flags(ptr)):
ptr = next_head(ptr)
bb_start = ptr
continue
else:
# This bb doesn't match our pattern skip it
print(f"BB at {hex(bb_start)} doesn't match pattern, skip it")
ptr = next_head(ptr)
while not is_code(ida_bytes.get_full_flags(ptr)):
ptr = next_head(ptr)
bb_start = ptr
continue

print(f"Dispatcher bb {hex(bb_start)}")
bb_table.append((bb_start,ptr,eax_cmp_value,jmp_condition,jmp_condition_address,reg_name))
ptr = next_head(ptr)
while not is_code(ida_bytes.get_full_flags(ptr)):
ptr = next_head(ptr)
bb_start = ptr
else:
# This is code bb don't save it
print(f"Original code bb {hex(bb_start)}")
bb_orig_table.append(bb_start)
ptr = next_head(ptr)
while not is_code(ida_bytes.get_full_flags(ptr)):
ptr = next_head(ptr)
bb_start = ptr
else:
ptr = next_head(ptr)

bb_orig_table = [0x7ff6654a687f, 0x7ff6654a691a, 0x7ff6654a6a04, 0x7ff6654a6a84, 0x7ff6654a6ad1, 0x7ff6654a6b3b, 0x7ff6654a6b9b, 0x7ff6654a6bf3, 0x7ff6654a6c61, 0x7ff6654a6cfd, 0x7ff6654a6e9f, 0x7ff6654a6ef8, 0x7ff6654a6f58, 0x7ff6654a7024]

bb_table = [(0x7ff6654a67f0, 0x7ff6654a6817, 0x10bc6c78, 'cmovl', 0x7ff6654a67fa, 'rdx'), (0x7ff6654a6819, 0x7ff6654a682e, 0xffffffffc30bae2e, 'cmovl', 0x7ff6654a6823, 'rdx'), (0x7ff6654a6830, 0x7ff6654a6845, 0xffffffffa2992627, 'cmovl', 0x7ff6654a683a, 'rdx'), (0x7ff6654a6847, 0x7ff6654a6861, 0xffffffffa22a16af, 'cmovl', 0x7ff6654a6856, 'rdx'), (0x7ff6654a6863, 0x7ff6654a687d, 0xffffffff8cbc0434, 'cmovz', 0x7ff6654a6872, 'rcx'), (0x7ff6654a68b0, 0x7ff6654a68c5, 0x6c249751, 'cmovl', 0x7ff6654a68ba, 'rdx'), (0x7ff6654a68c7, 0x7ff6654a68e1, 0x3b2b8a1e, 'cmovl', 0x7ff6654a68d6, 'rdx'), (0x7ff6654a68e3, 0x7ff6654a68fd, 0x173ba5e1, 'cmovl', 0x7ff6654a68f2, 'rdx'), (0x7ff6654a68ff, 0x7ff6654a6918, 0x10bc6c78, 'setz', 0x7ff6654a6906, 'rcx'), (0x7ff6654a69b0, 0x7ff6654a69ca, 0xffffffffd43fb344, 'cmovl', 0x7ff6654a69bf, 'rdx'), (0x7ff6654a69cc, 0x7ff6654a69e6, 0xffffffffcef7092e, 'cmovl', 0x7ff6654a69db, 'rdx'), (0x7ff6654a69e8, 0x7ff6654a6a02, 0xffffffffc30bae2e, 'cmovz', 0x7ff6654a69f7, 'rcx'), (0x7ff6654a6a30, 0x7ff6654a6a4a, 0x7d71a1e3, 'cmovl', 0x7ff6654a6a3f, 'rdx'), (0x7ff6654a6a4c, 0x7ff6654a6a66, 0x7a980236, 'cmovl', 0x7ff6654a6a5b, 'rdx'), (0x7ff6654a6a68, 0x7ff6654a6a82, 0x6c249751, 'cmovz', 0x7ff6654a6a77, 'rcx'), (0x7ff6654a6a99, 0x7ff6654a6ab3, 0xffffffffc094d6c9, 'cmovl', 0x7ff6654a6aa8, 'rdx'), (0x7ff6654a6ab5, 0x7ff6654a6acf, 0xffffffffa2992627, 'cmovz', 0x7ff6654a6ac4, 'rcx'), (0x7ff6654a6b09, 0x7ff6654a6b1e, 0x3cd69d30, 'setl', 0x7ff6654a6b10, 'rdx'), (0x7ff6654a6b20, 0x7ff6654a6b39, 0x3b2b8a1e, 'setnz', 0x7ff6654a6b27, 'rcx'), (0x7ff6654a6b63, 0x7ff6654a6b7d, 0xffffffffecce8ff1, 'cmovl', 0x7ff6654a6b72, 'rdx'), (0x7ff6654a6b7f, 0x7ff6654a6b99, 0xffffffffd43fb344, 'cmovz', 0x7ff6654a6b8e, 'rcx'), (0x7ff6654a6bbb, 0x7ff6654a6bd5, 0x7d9d86f3, 'cmovl', 0x7ff6654a6bca, 'rdx'), (0x7ff6654a6bd7, 0x7ff6654a6bf1, 0x7d71a1e3, 'cmovz', 0x7ff6654a6be6, 'rcx'), (0x7ff6654a6c45, 0x7ff6654a6c5f, 0xffffffffa22a16af, 'cmovz', 0x7ff6654a6c54, 'rcx'), (0x7ff6654a6ce1, 0x7ff6654a6cfb, 0x173ba5e1, 'cmovz', 0x7ff6654a6cf0, 'rcx'), (0x7ff6654a6e83, 0x7ff6654a6e9d, 0xffffffffcef7092e, 'cmovz', 0x7ff6654a6e92, 'rcx'), (0x7ff6654a6edc, 0x7ff6654a6ef6, 0x7a980236, 'cmovz', 0x7ff6654a6eeb, 'rcx'), (0x7ff6654a6f3d, 0x7ff6654a6f56, 0xffffffffc094d6c9, 'setz', 0x7ff6654a6f44, 'rcx'), (0x7ff6654a7008, 0x7ff6654a7022, 0x3cd69d30, 'cmovz', 0x7ff6654a7017, 'rcx'), (0x7ff6654a7052, 0x7ff6654a706c, 0xffffffffecce8ff1, 'cmovz', 0x7ff6654a7061, 'rcx')]

bb_table means the Dispatcher bb, and this bb has two formats that uses (cmovl, cmovz) or uses (setl and setz)

bb_orig_table means the origin payload bb

Emulate Basic Blocks

For each dispatcher bb emulate the block both satisfying the condition and not satisfying it to produce both the jmp address for the conditional jmp and the jmp address for the unconditional jmp.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
DUMP_FILE = '13.25.dmp'

from dumpulator import Dumpulator

dp = Dumpulator(DUMP_FILE,quiet=True)
bb_table = [(0x7ff6654a67f0, 0x7ff6654a6817, 0x10bc6c78, 'cmovl', 0x7ff6654a67fa, 'rdx'), (0x7ff6654a6819, 0x7ff6654a682e, 0xffffffffc30bae2e, 'cmovl', 0x7ff6654a6823, 'rdx'), (0x7ff6654a6830, 0x7ff6654a6845, 0xffffffffa2992627, 'cmovl', 0x7ff6654a683a, 'rdx'), (0x7ff6654a6847, 0x7ff6654a6861, 0xffffffffa22a16af, 'cmovl', 0x7ff6654a6856, 'rdx'), (0x7ff6654a6863, 0x7ff6654a687d, 0xffffffff8cbc0434, 'cmovz', 0x7ff6654a6872, 'rcx'), (0x7ff6654a68b0, 0x7ff6654a68c5, 0x6c249751, 'cmovl', 0x7ff6654a68ba, 'rdx'), (0x7ff6654a68c7, 0x7ff6654a68e1, 0x3b2b8a1e, 'cmovl', 0x7ff6654a68d6, 'rdx'), (0x7ff6654a68e3, 0x7ff6654a68fd, 0x173ba5e1, 'cmovl', 0x7ff6654a68f2, 'rdx'), (0x7ff6654a68ff, 0x7ff6654a6918, 0x10bc6c78, 'setz', 0x7ff6654a6906, 'rcx'), (0x7ff6654a69b0, 0x7ff6654a69ca, 0xffffffffd43fb344, 'cmovl', 0x7ff6654a69bf, 'rdx'), (0x7ff6654a69cc, 0x7ff6654a69e6, 0xffffffffcef7092e, 'cmovl', 0x7ff6654a69db, 'rdx'), (0x7ff6654a69e8, 0x7ff6654a6a02, 0xffffffffc30bae2e, 'cmovz', 0x7ff6654a69f7, 'rcx'), (0x7ff6654a6a30, 0x7ff6654a6a4a, 0x7d71a1e3, 'cmovl', 0x7ff6654a6a3f, 'rdx'), (0x7ff6654a6a4c, 0x7ff6654a6a66, 0x7a980236, 'cmovl', 0x7ff6654a6a5b, 'rdx'), (0x7ff6654a6a68, 0x7ff6654a6a82, 0x6c249751, 'cmovz', 0x7ff6654a6a77, 'rcx'), (0x7ff6654a6a99, 0x7ff6654a6ab3, 0xffffffffc094d6c9, 'cmovl', 0x7ff6654a6aa8, 'rdx'), (0x7ff6654a6ab5, 0x7ff6654a6acf, 0xffffffffa2992627, 'cmovz', 0x7ff6654a6ac4, 'rcx'), (0x7ff6654a6b09, 0x7ff6654a6b1e, 0x3cd69d30, 'setl', 0x7ff6654a6b10, 'rdx'), (0x7ff6654a6b20, 0x7ff6654a6b39, 0x3b2b8a1e, 'setnz', 0x7ff6654a6b27, 'rcx'), (0x7ff6654a6b63, 0x7ff6654a6b7d, 0xffffffffecce8ff1, 'cmovl', 0x7ff6654a6b72, 'rdx'), (0x7ff6654a6b7f, 0x7ff6654a6b99, 0xffffffffd43fb344, 'cmovz', 0x7ff6654a6b8e, 'rcx'), (0x7ff6654a6bbb, 0x7ff6654a6bd5, 0x7d9d86f3, 'cmovl', 0x7ff6654a6bca, 'rdx'), (0x7ff6654a6bd7, 0x7ff6654a6bf1, 0x7d71a1e3, 'cmovz', 0x7ff6654a6be6, 'rcx'), (0x7ff6654a6c45, 0x7ff6654a6c5f, 0xffffffffa22a16af, 'cmovz', 0x7ff6654a6c54, 'rcx'), (0x7ff6654a6ce1, 0x7ff6654a6cfb, 0x173ba5e1, 'cmovz', 0x7ff6654a6cf0, 'rcx'), (0x7ff6654a6e83, 0x7ff6654a6e9d, 0xffffffffcef7092e, 'cmovz', 0x7ff6654a6e92, 'rcx'), (0x7ff6654a6edc, 0x7ff6654a6ef6, 0x7a980236, 'cmovz', 0x7ff6654a6eeb, 'rcx'), (0x7ff6654a6f3d, 0x7ff6654a6f56, 0xffffffffc094d6c9, 'setz', 0x7ff6654a6f44, 'rcx'), (0x7ff6654a7008, 0x7ff6654a7022, 0x3cd69d30, 'cmovz', 0x7ff6654a7017, 'rcx'), (0x7ff6654a7052, 0x7ff6654a706c, 0xffffffffecce8ff1, 'cmovz', 0x7ff6654a7061, 'rcx')]


bb_jmp_table = []


def emulate_bb(bb_start, bb_end, eax_value, jmp_reg):
dp.regs.eflags = 0
dp.regs.r15 = 0x190
dp.regs.r14 = 0x0FFFFFFFFAE6529F8
dp.regs.r13 = 0x10
dp.regs.r12 = 0x1B0
dp.regs.rcx = 0x00007FF6654A6CFD
dp.regs.rax = eax_value
dp.start(bb_start,end=bb_end)
jmp_reg_value = dp.regs.__getattr__(jmp_reg)
return jmp_reg_value


for bb in bb_table:
bb_start = bb[0]
bb_end = bb[1]
eax_value = bb[2]
jmp_condition = bb[3]
jmp_condition_address = bb[4]
jmp_register = bb[5]

# plus or minus the eax_value is used to satisfied the asm code, so that we can get the jmp address
if jmp_condition == 'cmovl' or jmp_condition == 'setl':
jmp_addr_satisfied = emulate_bb(bb_start, bb_end, eax_value - 1, jmp_register)
jmp_addr_unsatisfied = emulate_bb(bb_start, bb_end, eax_value + 1, jmp_register)
elif jmp_condition == 'cmovz' or jmp_condition == 'setz':
jmp_addr_satisfied = emulate_bb(bb_start, bb_end, eax_value, jmp_register)
jmp_addr_unsatisfied = emulate_bb(bb_start, bb_end, eax_value + 1, jmp_register)
elif jmp_condition == 'setnz':
jmp_addr_satisfied = emulate_bb(bb_start, bb_end, eax_value + 1, jmp_register)
jmp_addr_unsatisfied = emulate_bb(bb_start, bb_end, eax_value, jmp_register)

print(f"BB {hex(bb_start)}:{hex(bb_end)} - jmp_addr_satisfied: {hex(jmp_addr_satisfied)} - jmp_addr_unsatisfied: {hex(jmp_addr_unsatisfied)}")
bb_jmp_table.append((bb_start,bb_end,eax_value,jmp_condition,jmp_condition_address,jmp_register,jmp_addr_satisfied,jmp_addr_unsatisfied))


for bb in bb_jmp_table:
print(bb)

ida patch

conditions

  • cmovl setl————jl
  • cmovz setz————jz
  • setnz————jnz

so why this???

1
2
3
4
5
cmovl   rdx, r12        ; Move if Less (SF!=OF)
cmovz rdx, rbp ; Move if Zero (ZF=1)
setz dl ; Set Byte if Zero (ZF=1)
setl dl ; Set Byte if Less (SF!=OF)
setnz dl ; Set Byte if Not Zero (ZF=0)

image-20220413170752647

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import struct 

bb_jmp_table = [(140696238057456, 140696238057495, 280783992, 'cmovl', 140696238057466, 'rdx', 140696238057497, 140696238057648), (140696238057497, 140696238057518, 18446744072686906926, 'cmovl', 140696238057507, 'rdx', 140696238057520, 140696238057904), (140696238057520, 140696238057541, 18446744072142530087, 'cmovl', 140696238057530, 'rdx', 140696238057543, 140696238058137), (140696238057543, 140696238057569, 18446744072135251631, 'cmovl', 140696238057558, 'rdx', 140696238057571, 140696238058565), (140696238057571, 140696238057597, 18446744071775716404, 'cmovz', 140696238057586, 'rcx', 140696238057599, 140696238057456), (140696238057648, 140696238057669, 1814337361, 'cmovl', 140696238057658, 'rdx', 140696238057671, 140696238058032), (140696238057671, 140696238057697, 992709150, 'cmovl', 140696238057686, 'rdx', 140696238057699, 140696238058249), (140696238057699, 140696238057725, 389785057, 'cmovl', 140696238057714, 'rdx', 140696238057727, 140696238058721), (140696238057727, 140696238057752, 280783992, 'setz', 140696238057734, 'rcx', 140696238057754, 140696238057456), (140696238057904, 140696238057930, 18446744072975528772, 'cmovl', 140696238057919, 'rdx', 140696238057932, 140696238058339), (140696238057932, 140696238057958, 18446744072886880558, 'cmovl', 140696238057947, 'rdx', 140696238057960, 140696238059139), (140696238057960, 140696238057986, 18446744072686906926, 'cmovz', 140696238057975, 'rcx', 140696238057988, 140696238057456), (140696238058032, 140696238058058, 2104599011, 'cmovl', 140696238058047, 'rdx', 140696238058060, 140696238058427), (140696238058060, 140696238058086, 2056782390, 'cmovl', 140696238058075, 'rdx', 140696238058088, 140696238059228), (140696238058088, 140696238058114, 1814337361, 'cmovz', 140696238058103, 'rcx', 140696238058116, 140696238057456), (140696238058137, 140696238058163, 18446744072645564105, 'cmovl', 140696238058152, 'rdx', 140696238058165, 140696238059325), (140696238058165, 140696238058191, 18446744072142530087, 'cmovz', 140696238058180, 'rcx', 140696238058193, 140696238057456), (140696238058249, 140696238058270, 1020697904, 'setl', 140696238058256, 'rdx', 140696238058272, 140696238059528), (140696238058272, 140696238058297, 992709150, 'setnz', 140696238058279, 'rcx', 140696238057456, 140696238058299), (140696238058339, 140696238058365, 18446744073387544561, 'cmovl', 140696238058354, 'rdx', 140696238058367, 140696238059602), (140696238058367, 140696238058393, 18446744072975528772, 'cmovz', 140696238058382, 'rcx', 140696238058395, 140696238057456), (140696238058427, 140696238058453, 2107475699, 'cmovl', 140696238058442, 'rdx', 140696238058455, 140696238057416), (140696238058455, 140696238058481, 2104599011, 'cmovz', 140696238058470, 'rcx', 140696238058483, 140696238057456), (140696238058565, 140696238058591, 18446744072135251631, 'cmovz', 140696238058580, 'rcx', 140696238058593, 140696238057456), (140696238058721, 140696238058747, 389785057, 'cmovz', 140696238058736, 'rcx', 140696238058749, 140696238057456), (140696238059139, 140696238059165, 18446744072886880558, 'cmovz', 140696238059154, 'rcx', 140696238059167, 140696238057456), (140696238059228, 140696238059254, 2056782390, 'cmovz', 140696238059243, 'rcx', 140696238059256, 140696238057456), (140696238059325, 140696238059350, 18446744072645564105, 'setz', 140696238059332, 'rcx', 140696238059352, 140696238057456), (140696238059528, 140696238059554, 1020697904, 'cmovz', 140696238059543, 'rcx', 140696238059556, 140696238057456), (140696238059602, 140696238059628, 18446744073387544561, 'cmovz', 140696238059617, 'rcx', 140696238059630, 140696238057456)]


for bb in bb_jmp_table:
bb_start = bb[0]
bb_end = bb[1]
eax_value = bb[2]
jmp_condition = bb[3]
jmp_condition_address = bb[4]
jmp_register = bb[5]
jmp_addr_satisfied = bb[6]
jmp_addr_unsatisfied = bb[7]

patch_jmp_cond_start = jmp_condition_address
jmp_rel_statisfied = jmp_addr_satisfied - (patch_jmp_cond_start + 6) #jz jnz jl address that satisfied the cmp eax,xxxxxx

patch_jmp_start = patch_jmp_cond_start + 6 # long jump need 6 byte ,jmp need 5 byte
jmp_rel = jmp_addr_unsatisfied - (patch_jmp_start + 5) # jmp relative address

if jmp_condition == 'cmovl' or jmp_condition == 'setl':
# jl
patch_jmp_condition = b'\x0f\x8c' + struct.pack('<i',jmp_rel_statisfied)
patch_jmp = b'\xe9' + struct.pack('<i',jmp_rel)
elif jmp_condition == 'cmovz' or jmp_condition == 'setz':
# jz
patch_jmp_condition = b'\x0f\x84' + struct.pack('<i',jmp_rel_statisfied)
patch_jmp = b'\xe9' + struct.pack('<i',jmp_rel)
elif jmp_condition == 'setnz':
# jnz
patch_jmp_condition = b'\x0f\x85' + struct.pack('<i',jmp_rel_statisfied)
patch_jmp = b'\xe9' + struct.pack('<i',jmp_rel)

# calculat nops for end of patch
total_bytes = bb_end - jmp_condition_address + 2
nop_count = total_bytes - 11

# 11 bytes for the patch + nops to fill space
patch_bytes = patch_jmp_condition + patch_jmp + b'\x90'* nop_count

# patch the bytes
patch_ptr = jmp_condition_address

# print("ggod")
for c in patch_bytes:
patch_byte(patch_ptr, c)
patch_ptr += 1

analysis

1
print(hex(patch_jmp_cond_start),hex(jmp_rel_statisfied),hex(patch_jmp_start),hex(jmp_rel))

output beblow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
patch_jmp_cond_start jmp_rel_statisfied patch_jmp_start   jmp_rel
0x7ff6654a67fa 0x19 0x7ff6654a6800 0xab
0x7ff6654a6823 0x7 0x7ff6654a6829 0x182
0x7ff6654a683a 0x7 0x7ff6654a6840 0x254
0x7ff6654a6856 0x7 0x7ff6654a685c 0x3e4
0x7ff6654a6872 0x7 0x7ff6654a6878 -0x8d
0x7ff6654a68ba 0x7 0x7ff6654a68c0 0x16b
0x7ff6654a68d6 0x7 0x7ff6654a68dc 0x228
0x7ff6654a68f2 0x7 0x7ff6654a68f8 0x3e4
0x7ff6654a6906 0xe 0x7ff6654a690c -0x121
0x7ff6654a69bf 0x7 0x7ff6654a69c5 0x199
0x7ff6654a69db 0x7 0x7ff6654a69e1 0x49d
0x7ff6654a69f7 0x7 0x7ff6654a69fd -0x212
0x7ff6654a6a3f 0x7 0x7ff6654a6a45 0x171
0x7ff6654a6a5b 0x7 0x7ff6654a6a61 0x476
0x7ff6654a6a77 0x7 0x7ff6654a6a7d -0x292
0x7ff6654a6aa8 0x7 0x7ff6654a6aae 0x48a
0x7ff6654a6ac4 0x7 0x7ff6654a6aca -0x2df
0x7ff6654a6b10 0xa 0x7ff6654a6b16 0x4ed
0x7ff6654a6b27 -0x33d 0x7ff6654a6b2d 0x9
0x7ff6654a6b72 0x7 0x7ff6654a6b78 0x4d5
0x7ff6654a6b8e 0x7 0x7ff6654a6b94 -0x3a9
0x7ff6654a6bca 0x7 0x7ff6654a6bd0 -0x40d
0x7ff6654a6be6 0x7 0x7ff6654a6bec -0x401
0x7ff6654a6c54 0x7 0x7ff6654a6c5a -0x46f
0x7ff6654a6cf0 0x7 0x7ff6654a6cf6 -0x50b
0x7ff6654a6e92 0x7 0x7ff6654a6e98 -0x6ad
0x7ff6654a6eeb 0x7 0x7ff6654a6ef1 -0x706
0x7ff6654a6f44 0xe 0x7ff6654a6f4a -0x75f
0x7ff6654a7017 0x7 0x7ff6654a701d -0x832
0x7ff6654a7061 0x7 0x7ff6654a7067 -0x87c

patch_jmp_cond_start = jmp_condition_address
jmp_rel_statisfied = jmp_addr_satisfied - (patch_jmp_cond_start + 6)
patch_jmp_start = patch_jmp_cond_start + 6
jmp_rel = jmp_addr_unsatisfied - (patch_jmp_start + 5)

this means

截屏2022-04-13 下午2.14.49

本文采用CC-BY-SA-3.0协议,转载请注明出处
Author: scr1pt