本文为看雪论坛精华文章
看雪论坛作者ID:0x指纹
前言
分析准备
Version0 加密
from unicorn import *
from unicorn.arm_const import *
table = []
def bytes2bin(bytes):
arr = []
for v in [m for m in bytes]:
arr.append(
[(v & 128) >> 7, (v & 64) >> 6, (v & 32) >> 5, (v & 16) >> 4, (v & 8) >> 3, (v & 4) >> 2, (v & 2) >> 1,
v & 1])
return [i for j in arr for i in j]
def bin2bytes(arr):
length = len(arr) // 8
arr1 = [0 for _ in range(length)]
for j in range(length):
arr1[j] = arr[j * 8] << 7 | arr[j * 8 + 1] << 6 | arr[j * 8 + 2] << 5 | arr[j * 8 + 3] << 4 | arr[
j * 8 + 4] << 3 | arr[j * 8 + 5] << 2 | arr[j * 8 + 6] << 1 | arr[j * 8 + 7]
return bytes(arr1)
def read(name):
with open(name, 'rb') as f:
return f.read()
def hook_code(mu, address, size, user_data):
if address == BASE + 0x119cc:
arr2 = []
for byte in mu.mem_read(PLAINTEXT_ADDR, 8):
arr2.append(byte)
table.append([user_data.index(1), bytes2bin(arr2).index(1)])
if __name__ == "__main__":
key0 = b'44e715a6e322ccb7d028f7a42fa55040'
mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB)
BASE = 0x400000
STACK_ADDR = 0x0
STACK_SIZE = 1024
PLAINTEXT_ADDR = 1024 * 2
PLAINTEXT_SIZE = 1024
KEY_ADDR = 1024 * 3
KEY_SIZE = 1024
mu.mem_map(BASE, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)
mu.mem_map(PLAINTEXT_ADDR, PLAINTEXT_SIZE)
mu.mem_map(KEY_ADDR, KEY_SIZE)
mu.reg_write(UC_ARM_REG_SP, STACK_ADDR + STACK_SIZE - 1)
# mu.mem_write(BASE, read("F:\\Code\\Pycharm\\JDSign\\libjdbitmapkit.so"))
mu.mem_write(BASE, read("./libjdbitmapkit.so"))
mu.mem_write(KEY_ADDR, key0)
for i in range(64):
arr1 = [0 for j in range(64)]
arr1[i] = 1
h = mu.hook_add(UC_HOOK_CODE, hook_code, arr1)
mu.mem_write(PLAINTEXT_ADDR, bin2bytes(arr1))
mu.reg_write(UC_ARM_REG_R1, KEY_ADDR)
mu.reg_write(UC_ARM_REG_R2, 32)
mu.reg_write(UC_ARM_REG_R3, PLAINTEXT_ADDR)
mu.emu_start(BASE + 0x00010EA4 + 1, BASE + 0x000119D0)
mu.hook_del(h)
print(table)
[[0, 0], [1, 4], [2, 61], [3, 15], [4, 56], [5, 40], [6, 6], [7, 59], [8, 62], [9, 58], [10, 17], [11, 2], [12, 12], [13, 8], [14, 32], [15, 60], [16, 13], [17, 45], [18, 34], [19, 14], [20, 36], [21, 21], [22, 22], [23, 39], [24, 23], [25, 25], [26, 26], [27, 20], [28, 1], [29, 33], [30, 46], [31, 55], [32, 35], [33, 24], [34, 57], [35, 19], [36, 53], [37, 37], [38, 38], [39, 5], [40, 30], [41, 41], [42, 42], [43, 18], [44, 47], [45, 27], [46, 9], [47, 44], [48, 51], [49, 7], [50, 49], [51, 63], [52, 28], [53, 43], [54, 54], [55, 52], [56, 31], [57, 10], [58, 29], [59, 11], [60, 3], [61, 16], [62, 50], [63, 48]]
def sub_10EA4(input):
table = [[0, 0], [1, 4], [2, 61], [3, 15], [4, 56], [5, 40], [6, 6], [7, 59], [8, 62], [9, 58], [10, 17], [11, 2],
[12, 12], [13, 8], [14, 32], [15, 60], [16, 13], [17, 45], [18, 34], [19, 14], [20, 36], [21, 21],
[22, 22], [23, 39], [24, 23], [25, 25], [26, 26], [27, 20], [28, 1], [29, 33], [30, 46], [31, 55],
[32, 35], [33, 24], [34, 57], [35, 19], [36, 53], [37, 37], [38, 38], [39, 5], [40, 30], [41, 41],
[42, 42], [43, 18], [44, 47], [45, 27], [46, 9], [47, 44], [48, 51], [49, 7], [50, 49], [51, 63], [52, 28],
[53, 43], [54, 54], [55, 52], [56, 31], [57, 10], [58, 29], [59, 11], [60, 3], [61, 16], [62, 50],
[63, 48]]
arr = bytes2bin(input)
arr1 = [0 for i in range(len(arr))]
for i in range(len(table)):
arr1[table[i][1]] = arr[table[i][0]]
return bin2bytes(arr1)
.text:00005BE2 loc_5BE2 ; CODE XREF: sub_4B7C+104↑j
.text:00005BE2 CMP R1, R2
.text:00005BE4 MOV R12, R1
.text:00005BE6 BEQ loc_5C00
.text:00005BE8 MOV R6, R1
.text:00005BEA MOV R8, R2
.text:00005BEC B loc_5BF0
.text:00005BEE ; ---------------------------------------------------------------------------
.text:00005BEE
.text:00005BEE loc_5BEE ; CODE XREF: sub_4B7C+1082↓j
.text:00005BEE MOV R12, R6
.text:00005BF0
.text:00005BF0 loc_5BF0 ; CODE XREF: sub_4B7C+1070↑j
.text:00005BF0 LDRB R6, [R6,#0x10]
.text:00005BF2 STRB.W R6, [R8,#0x10]
.text:00005BF6 MOV R8, R12
.text:00005BF8 LDR.W R6, [R12,#0xC]
.text:00005BFC CMP R6, R2
.text:00005BFE BNE loc_5BEE
.text:00005C00
text:00005C00 CMP R11, R2
.text:00005C02 STRB.W R4, [R12,#0x10]
.text:00005C06 MOV R4, R11
.text:00005C08 LDRB.W R8, [SP,#0xE0+var_98]
.text:00005C0C IT NE
.text:00005C0E MOVNE R12, R2
.text:00005C10 BNE loc_5C16
.text:00005C12 B loc_5C2C
.text:00005C14 ; ---------------------------------------------------------------------------
.text:00005C14
.text:00005C14 loc_5C14 ; CODE XREF: sub_4B7C+10AE↓j
.text:00005C14 MOV R4, R6
.text:00005C16
.text:00005C16 loc_5C16 ; CODE XREF: sub_4B7C+1094↑j
.text:00005C16 LDRB R6, [R4,#0x10]
.text:00005C18 RSBS.W R6, R6, #1
.text:00005C1C IT CC
.text:00005C1E MOVCC R6, #0
.text:00005C20 STRB.W R6, [R12,#0x10]
.text:00005C24 LDR R6, [R4,#4]
.text:00005C26 MOV R12, R4
.text:00005C28 CMP R6, R2
.text:00005C2A BNE loc_5C14
from unicorn import *
from unicorn.arm_const import *
table = []
table1 = []
def bytes2bin(bytes):
arr = []
for v in [m for m in bytes]:
arr.append(
[(v & 128) >> 7, (v & 64) >> 6, (v & 32) >> 5, (v & 16) >> 4, (v & 8) >> 3, (v & 4) >> 2, (v & 2) >> 1,
v & 1])
return [i for j in arr for i in j]
def bin2bytes(arr):
length = len(arr) // 8
arr1 = [0 for _ in range(length)]
for j in range(length):
arr1[j] = arr[j * 8] << 7 | arr[j * 8 + 1] << 6 | arr[j * 8 + 2] << 5 | arr[j * 8 + 3] << 4 | arr[
j * 8 + 4] << 3 | arr[j * 8 + 5] << 2 | arr[j * 8 + 6] << 1 | arr[j * 8 + 7]
return bytes(arr1)
def read(name):
with open(name, 'rb') as f:
return f.read()
def hook_code(mu, address, size, user_data):
if address == BASE + 0x5284:
table.append(bytes2bin(mu.mem_read(PLAINTEXT_ADDR, 1)))
if __name__ == "__main__":
key0 = b'44e715a6e322ccb7d028f7a42fa55040'
mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB)
BASE = 0x400000
STACK_ADDR = 0x0
STACK_SIZE = 1024
PLAINTEXT_ADDR = 1024 * 2
PLAINTEXT_SIZE = 1024
KEY_ADDR = 1024 * 3
KEY_SIZE = 1024
mu.mem_map(BASE, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)
mu.mem_map(PLAINTEXT_ADDR, PLAINTEXT_SIZE)
mu.mem_map(KEY_ADDR, KEY_SIZE)
mu.reg_write(UC_ARM_REG_SP, STACK_ADDR + STACK_SIZE - 1)
# mu.mem_write(BASE, read("F:\\Code\\Pycharm\\JDSign\\libjdbitmapkit.so"))
mu.mem_write(BASE, read("./libjdbitmapkit.so"))
mu.mem_write(KEY_ADDR, key0)
for i in range(9):
arr1 = [0 for j in range(8)]
if i != 0:
arr1[i-1] = 1
h = mu.hook_add(UC_HOOK_CODE, hook_code, arr1)
mu.mem_write(PLAINTEXT_ADDR, bin2bytes(arr1))
mu.reg_write(UC_ARM_REG_R0, KEY_ADDR)
mu.reg_write(UC_ARM_REG_R1, 32)
mu.reg_write(UC_ARM_REG_R2, 1)
mu.reg_write(UC_ARM_REG_R3, PLAINTEXT_ADDR)
mu.emu_start(BASE + 0x0004B7C + 1, BASE + 0x0005288)
mu.hook_del(h)
for i in range(8):
for j in range(8):
arr3 = []
if table[0][j] != table[i+1][j]:
table1.append([i, j, table[0][j], table[i+1][j]])
print(table1)
[[0, 6, 0, 1], [1, 4, 1, 0], [2, 5, 0, 1], [3, 0, 0, 1], [4, 2, 0, 1], [5, 3, 0, 1], [6, 1, 1, 0], [7, 7, 0, 1]]
def sub_4B7C(input):
table = [[0, 6, 0, 1], [1, 4, 1, 0], [2, 5, 0, 1], [3, 0, 0, 1], [4, 2, 0, 1], [5, 3, 0, 1], [6, 1, 1, 0],
[7, 7, 0, 1]]
arr = bytes2bin(input)
arr1 = [0 for i in range(8)]
for i in range(8):
if arr[i] == 0:
arr1[table[i][1]] = table[i][2]
else:
arr1[table[i][1]] = table[i][3]
return bin2bytes(arr1)
from unicorn import *
from unicorn.arm_const import *
table = []
table1 = []
def bytes2bin(bytes):
arr = []
for v in [m for m in bytes]:
arr.append(
[(v & 128) >> 7, (v & 64) >> 6, (v & 32) >> 5, (v & 16) >> 4, (v & 8) >> 3, (v & 4) >> 2, (v & 2) >> 1,
v & 1])
return [i for j in arr for i in j]
def bin2bytes(arr):
length = len(arr) // 8
arr1 = [0 for _ in range(length)]
for j in range(length):
arr1[j] = arr[j * 8] << 7 | arr[j * 8 + 1] << 6 | arr[j * 8 + 2] << 5 | arr[j * 8 + 3] << 4 | arr[
j * 8 + 4] << 3 | arr[j * 8 + 5] << 2 | arr[j * 8 + 6] << 1 | arr[j * 8 + 7]
return bytes(arr1)
def read(name):
with open(name, 'rb') as f:
return f.read()
def hook_code(mu, address, size, user_data):
if address == BASE + user_data[2] -4:
table.append(bytes2bin(mu.mem_read(PLAINTEXT_ADDR, m[0])))
if __name__ == "__main__":
key0 = b'44e715a6e322ccb7d028f7a42fa55040'
mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB)
BASE = 0x400000
STACK_ADDR = 0x0
STACK_SIZE = 1024 * 10
PLAINTEXT_ADDR = 1024 * 10
PLAINTEXT_SIZE = 1024
KEY_ADDR = 1024 * 11
KEY_SIZE = 1024
mu.mem_map(BASE, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)
mu.mem_map(PLAINTEXT_ADDR, PLAINTEXT_SIZE)
mu.mem_map(KEY_ADDR, KEY_SIZE)
mu.reg_write(UC_ARM_REG_SP, STACK_ADDR + STACK_SIZE - 1)
# mu.mem_write(BASE, read("F:\\Code\\Pycharm\\JDSign\\libjdbitmapkit.so"))
mu.mem_write(BASE, read("./libjdbitmapkit.so"))
mu.mem_write(KEY_ADDR, key0)
arr = [[1, 0x0004B7C, 0x0005288], [2, 0x00061A0, 0x0006AE8], [3, 0x0007994, 0x000084A6], [4, 0x000091AC, 0x00009DF4],
[5, 0x0000ABF8, 0x0000BA8C], [6, 0x0000C8C0, 0x0000D9A0], [7, 0x0000E7FC, 0x0000FC1C]]
for m in arr:
for i in range(m[0]*8+1):
arr1 = [0 for j in range(m[0]*8)]
if i != 0:
arr1[i - 1] = 1
h = mu.hook_add(UC_HOOK_CODE, hook_code, m)
mu.mem_write(PLAINTEXT_ADDR, bin2bytes(arr1))
mu.reg_write(UC_ARM_REG_R0, KEY_ADDR)
mu.reg_write(UC_ARM_REG_R1, 32)
mu.reg_write(UC_ARM_REG_R2, 1)
mu.reg_write(UC_ARM_REG_R3, PLAINTEXT_ADDR)
mu.emu_start(BASE + m[1] + 1, BASE + m[2])
mu.hook_del(h)
for i in range(m[0]*8):
for j in range(m[0]*8):
arr3 = []
if table[0][j] != table[i + 1][j]:
table1.append([i, j, table[0][j], table[i + 1][j]])
print("case %s 映射关系:"%(m[0]-1))
print(table1)
table.clear()
table1.clear()
case 0 映射关系:
[[0, 6, 0, 1], [1, 4, 1, 0], [2, 5, 0, 1], [3, 0, 0, 1], [4, 2, 0, 1], [5, 3, 0, 1], [6, 1, 1, 0], [7, 7, 0, 1]]
case 1 映射关系:
[[0, 5, 0, 1], [1, 9, 0, 1], [2, 0, 1, 0], [3, 7, 1, 0], [4, 10, 0, 1], [5, 6, 0, 1], [6, 13, 1, 0], [7, 1, 0, 1], [8, 4, 0, 1], [9, 11, 0, 1], [10, 14, 1, 0], [11, 3, 1, 0], [12, 12, 0, 1], [13, 15, 1, 0], [14, 8, 0, 1], [15, 2, 0, 1]]
case 2 映射关系:
[[0, 17, 0, 1], [1, 7, 0, 1], [2, 5, 0, 1], [3, 19, 1, 0], [4, 18, 0, 1], [5, 15, 1, 0], [6, 22, 0, 1], [7, 21, 0, 1], [8, 16, 0, 1], [9, 4, 0, 1], [10, 12, 0, 1], [11, 2, 1, 0], [12, 10, 1, 0], [13, 13, 1, 0], [14, 20, 1, 0], [15, 8, 1, 0], [16, 9, 0, 1], [17, 23, 0, 1], [18, 11, 1, 0], [19, 6, 0, 1], [20, 1, 0, 1], [21, 3, 1, 0], [22, 0, 1, 0], [23, 14, 0, 1]]
case 3 映射关系:
[[0, 25, 1, 0], [1, 4, 0, 1], [2, 29, 0, 1], [3, 1, 0, 1], [4, 27, 1, 0], [5, 18, 1, 0], [6, 23, 1, 0], [7, 14, 1, 0], [8, 28, 1, 0], [9, 11, 0, 1], [10, 9, 1, 0], [11, 13, 0, 1], [12, 24, 1, 0], [13, 0, 1, 0], [14, 5, 0, 1], [15, 2, 1, 0], [16, 26, 0, 1], [17, 12, 0, 1], [18, 31, 1, 0], [19, 16, 1, 0], [20, 30, 0, 1], [21, 15, 0, 1], [22, 10, 0, 1], [23, 22, 1, 0], [24, 7, 1, 0], [25, 21, 0, 1], [26, 6, 1, 0], [27, 3, 1, 0], [28, 8, 1, 0], [29, 20, 0, 1], [30, 19, 1, 0], [31, 17, 0, 1]]
case 4 映射关系:
[[0, 11, 0, 1], [1, 12, 0, 1], [2, 28, 1, 0], [3, 30, 0, 1], [4, 13, 1, 0], [5, 24, 0, 1], [6, 22, 1, 0], [7, 25, 1, 0], [8, 23, 1, 0], [9, 3, 0, 1], [10, 16, 0, 1], [11, 8, 1, 0], [12, 34, 0, 1], [13, 2, 0, 1], [14, 5, 0, 1], [15, 7, 1, 0], [16, 4, 0, 1], [17, 14, 0, 1], [18, 39, 1, 0], [19, 33, 0, 1], [20, 15, 0, 1], [21, 0, 0, 1], [22, 31, 0, 1], [23, 9, 1, 0], [24, 29, 0, 1], [25, 26, 1, 0], [26, 19, 0, 1], [27, 6, 1, 0], [28, 27, 1, 0], [29, 10, 1, 0], [30, 37, 0, 1], [31, 38, 1, 0], [32, 20, 0, 1], [33, 21, 1, 0], [34, 1, 0, 1], [35, 36, 0, 1], [36, 32, 0, 1], [37, 17, 0, 1], [38, 18, 0, 1], [39, 35, 1, 0]]
case 5 映射关系:
[[0, 11, 0, 1], [1, 45, 0, 1], [2, 15, 1, 0], [3, 22, 0, 1], [4, 10, 0, 1], [5, 7, 0, 1], [6, 3, 0, 1], [7, 42, 0, 1], [8, 17, 1, 0], [9, 21, 0, 1], [10, 4, 0, 1], [11, 8, 1, 0], [12, 19, 1, 0], [13, 32, 0, 1], [14, 28, 1, 0], [15, 31, 1, 0], [16, 29, 0, 1], [17, 14, 1, 0], [18, 39, 1, 0], [19, 27, 1, 0], [20, 2, 1, 0], [21, 24, 0, 1], [22, 26, 1, 0], [23, 9, 1, 0], [24, 41, 0, 1], [25, 1, 1, 0], [26, 47, 0, 1], [27, 44, 0, 1], [28, 23, 1, 0], [29, 0, 1, 0], [30, 12, 1, 0], [31, 18, 0, 1], [32, 33, 0, 1], [33, 36, 0, 1], [34, 40, 1, 0], [35, 34, 0, 1], [36, 25, 0, 1], [37, 16, 1, 0], [38, 5, 1, 0], [39, 35, 0, 1], [40, 38, 0, 1], [41, 37, 1, 0], [42, 13, 0, 1], [43, 20, 1, 0], [44, 6, 0, 1], [45, 43, 0, 1], [46, 30, 0, 1], [47, 46, 1, 0]]
case 6 映射关系:
[[0, 7, 1, 0], [1, 9, 0, 1], [2, 53, 1, 0], [3, 19, 1, 0], [4, 15, 1, 0], [5, 8, 0, 1], [6, 3, 0, 1], [7, 24, 1, 0], [8, 18, 0, 1], [9, 51, 0, 1], [10, 42, 1, 0], [11, 39, 0, 1], [12, 20, 0, 1], [13, 12, 0, 1], [14, 28, 1, 0], [15, 27, 1, 0], [16, 23, 0, 1], [17, 49, 0, 1], [18, 10, 1, 0], [19, 55, 1, 0], [20, 52, 1, 0], [21, 17, 0, 1], [22, 48, 0, 1], [23, 14, 1, 0], [24, 33, 0, 1], [25, 25, 1, 0], [26, 4, 1, 0], [27, 11, 0, 1], [28, 47, 1, 0], [29, 0, 0, 1], [30, 21, 1, 0], [31, 44, 0, 1], [32, 16, 0, 1], [33, 41, 0, 1], [34, 29, 0, 1], [35, 1, 0, 1], [36, 46, 0, 1], [37, 5, 0, 1], [38, 30, 0, 1], [39, 45, 0, 1], [40, 31, 1, 0], [41, 43, 1, 0], [42, 36, 1, 0], [43, 26, 0, 1], [44, 34, 0, 1], [45, 2, 0, 1], [46, 6, 0, 1], [47, 50, 1, 0], [48, 13, 1, 0], [49, 37, 1, 0], [50, 32, 0, 1], [51, 40, 0, 1], [52, 35, 0, 1], [53, 38, 0, 1], [54, 54, 0, 1], [55, 22, 0, 1]]
Version2 加密
.text:00012ECC LDR.W R12, =(__stack_chk_guard_ptr - 0x12ED8)
.text:00012ED0 PUSH.W {R4-R11,LR}
.text:00012ED4 ADD R12, PC ; __stack_chk_guard_ptr
.text:00012ED6 LDR.W R12, [R12] ; __stack_chk_guard
.text:00012EDA SUB SP, SP, #0x24
.text:00012EDC MOV R10, R3
.text:00012EDE LDR.W R3, [R12]
.text:00012EE2 MOV R7, R1
.text:00012EE4 LDR.W R8, [SP,#0x48+arg_0]
.text:00012EE8 MOV R9, R2
.text:00012EEA STR R3, [SP,#0x48+var_2C]
.text:00012EEC CMP.W R8, #0
.text:00012EF0 BNE loc_12F02
.text:00012EDC MOV R10, R3
.text:00012EE2 MOV R7, R1
.text:00012EE8 MOV R9, R2
.text:00012EE4 LDR.W R8, [SP,#0x48+arg_0]
.text:00012F66 MOVS R3, #0
.text:00012F68
.text:00012F68 loc_12F68
.text:00012F68 AND.W R2, R3, #0xF
.text:00012F6C ADD R0, SP, #0x48+var_28
.text:00012F6E ADD R2, R0
.text:00012F70 AND.W R1, R3, #7
.text:00012F74 LDRB.W R0, [R10]
.text:00012F78 ADDS R3, #1
.text:00012F7A LDRB.W R2, [R2,#-0x14]
.text:00012F7E CMP R3, R8
.text:00012F80 LDRB R4, [R7,R1]
.text:00012F82 EOR.W R0, R2, R0
.text:00012F86 EOR.W R0, R0, R4
.text:00012F8A ADD R0, R2
.text:00012F8C EOR.W R2, R2, R0
.text:00012F90 UXTB R2, R2
.text:00012F92 STRB.W R2, [R10],#1
.text:00012F96 LDRB R1, [R7,R1]
.text:00012F98 EOR.W R2, R2, R1
.text:00012F9C STRB.W R2, [R10,#-1]
.text:00012FA0 BNE loc_12F68
.text:00012F82 EOR.W R0, R2, R0
.text:00012F86 EOR.W R0, R0, R4
.text:00012F8A ADD R0, R2
.text:00012F8C EOR.W R2, R2, R0
.text:00012F90 UXTB R2, R2
.text:00012F96 LDRB R1, [R7,R1]
.text:00012F98 EOR.W R2, R2, R1
def sub_12ECC(input):
arr = [0x37, 0x92, 0x44, 0x68, 0xA5, 0x3D, 0xCC, 0x7F, 0xBB, 0xF, 0xD9, 0x88, 0xEE, 0x9A, 0xE9, 0x5A]
key2 = b"80306f4370b39fd5630ad0529f77adb6"
arr1 = [0 for _ in range(len(input))]
for i in range(len(input)):
r0 = int(input[i])
r2 = arr[i & 0xf]
r4 = int(key2[i & 7])
r0 = r2 ^ r0
r0 = r0 ^ r4
r0 = r0 + r2
r2 = r2 ^ r0
r1 = int(key2[i & 7])
r2 = r2 ^ r1
arr1[i] = r2 & 0xff
return bytes(arr1)
sign算法全流程还原
后记
看雪ID:0x指纹
https://bbs.pediy.com/user-home-802108.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!