记一次安卓的so花指令逆向
题目来源为
ISCC 2022
的擂台题,最终就1解,严重怀疑是出题人开的小号,毕竟两个人的id
十分接近,所以注册时间都差不多,而且这题上题的时间距离比赛结束就1天了,这题的各种套路明摆着来耗时间的,能用1天解出来的绝对是大手子。
题目附件:Mobile-zzgf_revenge-2022.05.24.apk
观察逻辑
先看一下activity
入口搁哪,原来是叫com.ctf.zzgfrev.ui.login.LoginActivity
。
翻了一下视图层的逻辑,代码是一片糨糊...大概能猜测除了loginViewModel.login
函数,其他的对解题都没啥用。
套娃到loginRepository.login
去。
然后是dataSource.l1ll1l1ll1l1lll1ll1l11lll
。
可以看出来有俩判断,一个是java
层的l1ll1l1ll1l1ll1ll1l1ll1ll
函数,一个是native
层的l1ll1l1ll1l11ll1ll1l11l1l
函数。
前半部分
l1ll1l1ll1l1ll1ll1l1ll1ll
主要就是个4字节key21, 84, 50, 14
用来循环异或然后再用O0O0O0O00O0O0OO0O0O00O.O0O0O0O0OO000OO000O00O
加密最后和:jC^.oj[n)46W>
比较。
那么去看看O0O0O0O00O0O0OO0O0O00O.O0O0O0O0OO000OO000O00O
,是用一个自定义字节流和一个乱序码表进行加密。
其中映射规律比较绕,懒得看了,直接尝试frida hook
爆破得了,先写个脚本看看前后字节是否相互影响。
Java.perform(function () {
console.log()
const input1_result = Array.from(":jC^.oj[n)46W>", (x) => x.charCodeAt(0))
const O0O0O0O00O0O0OO0O0O00O = Java.use('com.ctf.zzgfrev.util.O0O0O0O00O0O0OO0O0O00O')
O0O0O0O00O0O0OO0O0O00O.O0O0O0O0OO000OO000O00O.implementation = function (s: any) {
let input1 = Array(11).fill(0)
console.log('-', '\t', input1, '\t', Array.from(this.O0O0O0O0OO000OO000O00O(Java.array('byte', input1))).join('\t'))
for (let i in [...input1.keys()]) {
input1[i] = 1
const result = this.O0O0O0O0OO000OO000O00O(Java.array('byte', input1))
console.log(i, '\t', input1, '\t', Array.from(result).join('\t'))
}
return Java.array('byte', [])
}
const LoginActivity = Java.use('com.ctf.zzgfrev.ui.login.LoginActivity')
LoginActivity.onStart.overload().implementation = function () {
O0O0O0O00O0O0OO0O0O00O.O0O0O0O0OO000OO000O00O(Java.array('byte', []))
this.onStart.overload().call(this);
}
})
可以发现是个类似于base64
的拆位影响:
0 -> 0
1 -> 0 1
2 -> 2
3 -> 2 3
4 -> 4
5 -> 6
6 -> 6 7
7 -> 8
8 -> 8 9 *13
9 -> 10
10 -> 12
猜测是5个为一组,然后最后那个补位条件不太清楚,不过不影响。
所以就可以据此写frida hook
爆破脚本了:
Java.perform(function () {
console.log()
const input1_target = Array.from(":jC^.oj[n)46W>", (x) => x.charCodeAt(0))
const O0O0O0O00O0O0OO0O0O00O = Java.use('com.ctf.zzgfrev.util.O0O0O0O00O0O0OO0O0O00O')
O0O0O0O00O0O0OO0O0O00O.O0O0O0O0OO000OO000O00O.implementation = function (s: any) {
let input1 = Array(11).fill(0)
for (let i0 of [...Array(128).keys()]) {
input1[0] = i0
for (let i1 of [...Array(128).keys()]) {
input1[1] = i1
const result = this.O0O0O0O0OO000OO000O00O(Java.array('byte', input1))
if (!(result[0] === input1_target[0] && result[1] === input1_target[1])) continue
console.log(input1.join("\t"))
for (let i2 of [...Array(128).keys()]) {
input1[2] = i2
for (let i3 of [...Array(128).keys()]) {
input1[3] = i3
const result = this.O0O0O0O0OO000OO000O00O(Java.array('byte', input1))
if (!(result[2] === input1_target[2] && result[3] === input1_target[3])) continue
console.log(input1.join("\t"))
for (let i4 of [...Array(128).keys()]) {
input1[4] = i4
const result = this.O0O0O0O0OO000OO000O00O(Java.array('byte', input1))
if (!(result[4] === input1_target[4] && result[5] === input1_target[5])) continue
console.log(input1.join("\t"))
for (let i5 of [...Array(128).keys()]) {
input1[5] = i5
for (let i6 of [...Array(128).keys()]) {
input1[6] = i6
const result = this.O0O0O0O0OO000OO000O00O(Java.array('byte', input1))
if (!(result[6] === input1_target[6] && result[7] === input1_target[7])) continue
console.log(input1.join("\t"))
for (let i7 of [...Array(128).keys()]) {
input1[7] = i7
for (let i8 of [...Array(128).keys()]) {
input1[8] = i8
const result = this.O0O0O0O0OO000OO000O00O(Java.array('byte', input1))
if (!(result[8] === input1_target[8] && result[9] === input1_target[9])) continue
console.log(input1.join("\t"))
for (let i9 of [...Array(128).keys()]) {
input1[9] = i9
const result = this.O0O0O0O0OO000OO000O00O(Java.array('byte', input1))
if (!(result[10] === input1_target[10] && result[11] === input1_target[11])) continue
console.log(input1.join("\t"))
for (let i10 of [...Array(128).keys()]) {
input1[10] = i10
const result = this.O0O0O0O0OO000OO000O00O(Java.array('byte', input1))
if (!(result[12] === input1_target[12] && result[13] === input1_target[13])) continue
console.log(input1.join("\t"))
return Java.array('byte', input1)
}
}
}
}
}
}
}
}
}
}
}
return Java.array('byte', [])
}
const LoginActivity = Java.use('com.ctf.zzgfrev.ui.login.LoginActivity')
LoginActivity.onStart.overload().implementation = function () {
const input1_result: number[] = Array.from(O0O0O0O00O0O0OO0O0O00O.O0O0O0O0OO000OO000O00O(Java.array('byte', [])))
const input1_key = [21, 84, 50, 14]
const input1_byte = input1_result.map((x, i) => x ^ input1_key[i % 4])
console.log(`input1_byte=${input1_byte}`)
const input1 = String.fromCharCode(...input1_byte)
console.log(`input1=${input1}`)
this.onStart.overload().call(this);
}
})
成功得到第一个字符串iscc xhzg!!
后半部分
那现在去看l1ll1l1ll1l11ll1ll1l11l1l
函数,在so
里面没找到,所以是动态加载的。
通杀脚本frida_hook_libart
走一波看看,发现在0xc011-1
。
但是IDA
打开F5一下发现JUMPOUT
了,去看下汇编,妥妥的花指令。
那就patch+删除重建大法去修呗,具体可参考:[原创]分享一个对抗JUMPOUT的小技巧-Android安全-看雪论坛
patch前:
patch后:
然后回到函数开头,删除了然后P一下重建(因为在哪P就会以哪为函数开头去自动识别,所以刚才删除之前先回到函数开头,删除后就不方便找了,只能G地址过去)。
删除:
重建:
重新F5:
发现出来了新的花指令点,那就继续G过去,猜测应该是0xC340
那个BX R0
跳转到0xC344
所以把R0
给patch成0xC344
然后再删除重建。
后续这个函数里还有几十个花指令点,大致分为两类,一类是反复横跳式花指令,也就是上面的那种B
和BX
跳跳跳的,另一类是插入垃圾代码导致代码量暴增的,其特征是以getpid()
调用为开头,如下图,实际上有用的就354~355
两行,剩下的全是垃圾代码。
写个idapython
脚本把当前位置所在代码段(正常情况是给start
段去花,除非你光标在data
段哈哈哈)去花吧,脚本主要思路就是根据那俩花指令的特征去匹配,然后匹配出来了在开头就直接B
到真实地址去。
比如说反复横跳的又分为两种,一种是B
到PC+1
的,一种是B
到PC+9
的,不过这两种都有各自的真实地址与当前地址的固定差值(分别是+6
和+4
),所以直接+6
和+4
就行(具体值是根据ida
给的汇编跳转情况算的,多看几个花指令位置就会发现都是这俩差值)
然后插垃圾代码那个的话,直接把BLX getpid
给替换成B
真实地址就完事,至于真实地址怎么找的话,我这里的思路是根据fopen
下面的单分支if
去看跳转地址,因为if
里头也都是垃圾代码,而if
跳出来直接就结束了整个这段垃圾代码了,所以这个跳出地址就是真实地址。
from idc_bc695 import *
def put_unconditional_branch(source, destination, dw=False):
offset = (destination - source - 4) >> 1
if offset > 2097151 or offset < -2097152:
raise RuntimeError("Invalid offset")
if offset > 1023 or offset < -1024:
instruction1 = 0xf000 | ((offset >> 11) & 0x7ff)
instruction2 = 0xb800 | (offset & 0x7ff)
PatchWord(source, instruction1) # thumb: B desti
PatchWord(source + 2, instruction2) # thumb: B nation
else:
instruction = 0xe000 | (offset & 0x7ff)
PatchWord(source, instruction) # thumb: B destination
if dw:
PatchWord(source + 2, 0xbf00) #thumb: NOP
def dejunkcode(addr,endaddr):
funcs = set()
while addr<endaddr:
MakeCode(addr)
if GetMnem(addr)=="BLX" and GetFunctionName(GetOperandValue(addr,0))=="getpid": # BLX getpid
to=addr+ItemSize(addr)
to+=ItemSize(to)
to+=ItemSize(to)
if GetMnem(to)=="B":
to=GetOperandValue(to,0)
while GetMnem(to)!="BL" and GetFunctionName(GetOperandValue(to,0))!="sub_FEAC": # BL sub_FEAC
to+=ItemSize(to)
to+=ItemSize(to)
if GetMnem(to)=="B":
to=GetOperandValue(to,0)
while GetMnem(to)!="BLX" and GetFunctionName(GetOperandValue(to,0))!="fopen": # BLX fopen
to+=ItemSize(to)
to+=ItemSize(to)
to+=ItemSize(to)
to+=ItemSize(to)
if GetMnem(to)=="B":
to=GetOperandValue(to,0)
to += ItemSize(to)
to += ItemSize(to)
to += ItemSize(to)
to += ItemSize(to)
if GetMnem(to)=="BEQ" or GetMnem(to)=="BEQ.W":
to=GetOperandValue(to,0)
print(f"success find junk1 from {hex(addr)} to {hex(to)}")
put_unconditional_branch(addr, to, True)
funcs.add(GetFunctionAttr(addr, FUNCATTR_START))
else:
print(f"error at {hex(addr)} when find BEQ at {hex(to)}")
else:
print(f"error at {hex(addr)} when find B to BEQ at {hex(to)}")
else:
print(f"error at {hex(addr)} when find B to BLX fopen at {hex(to)}")
else:
print(f"error at {hex(addr)} when find B to BL sub_FEAC at {hex(to)}")
elif GetMnem(addr)=="MOV" and GetOperandValue(addr,0)==0 and GetOperandValue(addr,1)==15: # MOV R0, PC
to=addr+ItemSize(addr)
if GetMnem(to)=="B":
to=GetOperandValue(to,0)
if GetMnem(to)=="ADDS" and GetOperandValue(to,0)==0 and GetOperandValue(to,1)==1: # ADDS R0, #1
to+=ItemSize(to)
if GetMnem(to)=="BX" and GetOperandValue(to,0)==0: # BX R0
print(f"success find junk2.1 at {hex(to)}")
put_unconditional_branch(to, to+6)
funcs.add(GetFunctionAttr(addr, FUNCATTR_START))
else:
print(f"error at {hex(addr)} when find BX, R0 at {hex(to)}")
else:
print(f"error at {hex(addr)} when find ADDS R0, #1 at {hex(to)}")
elif GetMnem(to)=="ADDS" and GetOperandValue(to,0)==0 and GetOperandValue(to,1)==9: # ADDS R0, #9
to+=ItemSize(to)
to+=ItemSize(to)
to+=ItemSize(to)
if GetMnem(to)=="BX" and GetOperandValue(to,0)==0: # BX R0
print(f"success find junk2.2 at {hex(to)}")
put_unconditional_branch(to, to+4)
funcs.add(GetFunctionAttr(addr, FUNCATTR_START))
else:
print(f"error at {hex(addr)} when find BX, R0 at {hex(to)}")
else:
print(f"error at {hex(addr)} when find B to ADDS R0, #1 or ADDS R0, #9 at {hex(to)}")
addr+=ItemSize(addr)
return funcs
def remakeFunction(addr):
DelFunction(addr)
idaapi.add_func(addr)
for func in dejunkcode(idc.get_segm_start(here()), idc.get_segm_end(here())):
remakeFunction(func)
这个是去垃圾代码之前的:
void __fastcall __noreturn sub_C010(int a1, int a2, int a3, int a4)
{
int jj; // [sp+27Ch] [bp-FD5Ch]
FILE *v5; // [sp+284h] [bp-FD54h]
__pid_t v6; // [sp+288h] [bp-FD50h]
int ii; // [sp+28Ch] [bp-FD4Ch]
FILE *v8; // [sp+294h] [bp-FD44h]
__pid_t v9; // [sp+298h] [bp-FD40h]
int n; // [sp+29Ch] [bp-FD3Ch]
FILE *v11; // [sp+2A4h] [bp-FD34h]
__pid_t v12; // [sp+2A8h] [bp-FD30h]
FILE *v13; // [sp+2B0h] [bp-FD28h]
__pid_t v14; // [sp+2B4h] [bp-FD24h]
int v15; // [sp+2B8h] [bp-FD20h]
FILE *v16; // [sp+2C0h] [bp-FD18h]
__pid_t v17; // [sp+2C4h] [bp-FD14h]
int m; // [sp+2C8h] [bp-FD10h]
FILE *v19; // [sp+2D0h] [bp-FD08h]
__pid_t v20; // [sp+2D4h] [bp-FD04h]
FILE *v21; // [sp+2DCh] [bp-FCFCh]
__pid_t v22; // [sp+2E0h] [bp-FCF8h]
FILE *v23; // [sp+2E8h] [bp-FCF0h]
__pid_t v24; // [sp+2ECh] [bp-FCECh]
FILE *v25; // [sp+2F4h] [bp-FCE4h]
__pid_t v26; // [sp+2F8h] [bp-FCE0h]
int v27; // [sp+2FCh] [bp-FCDCh]
FILE *v28; // [sp+304h] [bp-FCD4h]
__pid_t v29; // [sp+308h] [bp-FCD0h]
FILE *v30; // [sp+310h] [bp-FCC8h]
__pid_t v31; // [sp+314h] [bp-FCC4h]
int k; // [sp+318h] [bp-FCC0h]
FILE *v33; // [sp+320h] [bp-FCB8h]
__pid_t v34; // [sp+324h] [bp-FCB4h]
int v35; // [sp+328h] [bp-FCB0h]
FILE *v36; // [sp+330h] [bp-FCA8h]
__pid_t v37; // [sp+334h] [bp-FCA4h]
FILE *v38; // [sp+33Ch] [bp-FC9Ch]
__pid_t v39; // [sp+340h] [bp-FC98h]
int j; // [sp+344h] [bp-FC94h]
FILE *v41; // [sp+34Ch] [bp-FC8Ch]
__pid_t v42; // [sp+350h] [bp-FC88h]
_BYTE *v43; // [sp+354h] [bp-FC84h]
FILE *v44; // [sp+35Ch] [bp-FC7Ch]
__pid_t v45; // [sp+360h] [bp-FC78h]
FILE *v46; // [sp+368h] [bp-FC70h]
__pid_t v47; // [sp+36Ch] [bp-FC6Ch]
FILE *v48; // [sp+374h] [bp-FC64h]
__pid_t v49; // [sp+378h] [bp-FC60h]
FILE *v50; // [sp+380h] [bp-FC58h]
__pid_t v51; // [sp+384h] [bp-FC54h]
FILE *v52; // [sp+38Ch] [bp-FC4Ch]
__pid_t v53; // [sp+390h] [bp-FC48h]
FILE *v54; // [sp+398h] [bp-FC40h]
__pid_t v55; // [sp+39Ch] [bp-FC3Ch]
FILE *v56; // [sp+3A4h] [bp-FC34h]
__pid_t v57; // [sp+3A8h] [bp-FC30h]
int v58; // [sp+3ACh] [bp-FC2Ch]
int v59; // [sp+3ACh] [bp-FC2Ch]
int v60; // [sp+3ACh] [bp-FC2Ch]
int v61; // [sp+3ACh] [bp-FC2Ch]
FILE *v62; // [sp+3B4h] [bp-FC24h]
__pid_t v63; // [sp+3B8h] [bp-FC20h]
FILE *v64; // [sp+3C0h] [bp-FC18h]
__pid_t v65; // [sp+3C4h] [bp-FC14h]
FILE *v66; // [sp+3CCh] [bp-FC0Ch]
__pid_t v67; // [sp+3D0h] [bp-FC08h]
FILE *v68; // [sp+3D8h] [bp-FC00h]
__pid_t v69; // [sp+3DCh] [bp-FBFCh]
FILE *v70; // [sp+3E4h] [bp-FBF4h]
__pid_t v71; // [sp+3E8h] [bp-FBF0h]
int i; // [sp+3ECh] [bp-FBECh]
FILE *v73; // [sp+3F4h] [bp-FBE4h]
__pid_t v74; // [sp+3F8h] [bp-FBE0h]
int v75; // [sp+3FCh] [bp-FBDCh]
FILE *v76; // [sp+404h] [bp-FBD4h]
__pid_t v77; // [sp+408h] [bp-FBD0h]
unsigned __int8 *v78; // [sp+40Ch] [bp-FBCCh]
FILE *v79; // [sp+414h] [bp-FBC4h]
__pid_t v80; // [sp+418h] [bp-FBC0h]
int v81; // [sp+41Ch] [bp-FBBCh]
FILE *v82; // [sp+424h] [bp-FBB4h]
__pid_t pid; // [sp+430h] [bp-FBA8h]
char v87[10]; // [sp+730h] [bp-F8A8h] BYREF
char v88[1014]; // [sp+73Ah] [bp-F89Eh] BYREF
char filename[1024]; // [sp+B30h] [bp-F4A8h] BYREF
char s1[10]; // [sp+F30h] [bp-F0A8h] BYREF
char v91[1014]; // [sp+F3Ah] [bp-F09Eh] BYREF
char v92[1024]; // [sp+1330h] [bp-ECA8h] BYREF
char v93[10]; // [sp+1730h] [bp-E8A8h] BYREF
char v94[1014]; // [sp+173Ah] [bp-E89Eh] BYREF
char v95[1024]; // [sp+1B30h] [bp-E4A8h] BYREF
_BYTE v96[128]; // [sp+1F30h] [bp-E0A8h] BYREF
char v97[10]; // [sp+1FB0h] [bp-E028h] BYREF
char v98[1014]; // [sp+1FBAh] [bp-E01Eh] BYREF
char v99[1024]; // [sp+23B0h] [bp-DC28h] BYREF
char v100[10]; // [sp+27B0h] [bp-D828h] BYREF
char v101[1014]; // [sp+27BAh] [bp-D81Eh] BYREF
char v102[1024]; // [sp+2BB0h] [bp-D428h] BYREF
char v103[10]; // [sp+2FB0h] [bp-D028h] BYREF
char v104[1014]; // [sp+2FBAh] [bp-D01Eh] BYREF
char v105[1024]; // [sp+33B0h] [bp-CC28h] BYREF
char v106[10]; // [sp+37B0h] [bp-C828h] BYREF
char v107[1014]; // [sp+37BAh] [bp-C81Eh] BYREF
char v108[80]; // [sp+3BB0h] [bp-C428h] BYREF
__int64 v109; // [sp+3FB0h] [bp-C028h]
char v110[10]; // [sp+3FB8h] [bp-C020h] BYREF
char v111[1014]; // [sp+3FC2h] [bp-C016h] BYREF
char v112[1024]; // [sp+43B8h] [bp-BC20h] BYREF
_QWORD v113[2]; // [sp+47B8h] [bp-B820h]
char v114[10]; // [sp+47CCh] [bp-B80Ch] BYREF
char v115[1014]; // [sp+47D6h] [bp-B802h] BYREF
char v116[1024]; // [sp+4BCCh] [bp-B40Ch] BYREF
char v117[10]; // [sp+4FCCh] [bp-B00Ch] BYREF
char v118[1014]; // [sp+4FD6h] [bp-B002h] BYREF
char v119[1024]; // [sp+53CCh] [bp-AC0Ch] BYREF
char v120[10]; // [sp+57CCh] [bp-A80Ch] BYREF
char v121[1014]; // [sp+57D6h] [bp-A802h] BYREF
char v122[1024]; // [sp+5BCCh] [bp-A40Ch] BYREF
char v123[10]; // [sp+5FCCh] [bp-A00Ch] BYREF
char v124[1014]; // [sp+5FD6h] [bp-A002h] BYREF
char v125[1024]; // [sp+63CCh] [bp-9C0Ch] BYREF
char v126[10]; // [sp+67CCh] [bp-980Ch] BYREF
char v127[1014]; // [sp+67D6h] [bp-9802h] BYREF
char v128[1024]; // [sp+6BCCh] [bp-940Ch] BYREF
char v129[10]; // [sp+6FCCh] [bp-900Ch] BYREF
char v130[1014]; // [sp+6FD6h] [bp-9002h] BYREF
char v131[1024]; // [sp+73CCh] [bp-8C0Ch] BYREF
char v132[10]; // [sp+77CCh] [bp-880Ch] BYREF
char v133[1014]; // [sp+77D6h] [bp-8802h] BYREF
char v134[1024]; // [sp+7BCCh] [bp-840Ch] BYREF
char v135[10]; // [sp+7FCCh] [bp-800Ch] BYREF
char v136[1014]; // [sp+7FD6h] [bp-8002h] BYREF
char v137[1024]; // [sp+83CCh] [bp-7C0Ch] BYREF
char v138[10]; // [sp+87CCh] [bp-780Ch] BYREF
char v139[1014]; // [sp+87D6h] [bp-7802h] BYREF
char v140[1024]; // [sp+8BCCh] [bp-740Ch] BYREF
char v141[10]; // [sp+8FCCh] [bp-700Ch] BYREF
char v142[1014]; // [sp+8FD6h] [bp-7002h] BYREF
char v143[1024]; // [sp+93CCh] [bp-6C0Ch] BYREF
char v144[10]; // [sp+97CCh] [bp-680Ch] BYREF
char v145[1014]; // [sp+97D6h] [bp-6802h] BYREF
char v146[1024]; // [sp+9BCCh] [bp-640Ch] BYREF
char v147[10]; // [sp+9FCCh] [bp-600Ch] BYREF
char v148[1014]; // [sp+9FD6h] [bp-6002h] BYREF
char v149[1024]; // [sp+A3CCh] [bp-5C0Ch] BYREF
char v150[10]; // [sp+A7CCh] [bp-580Ch] BYREF
char v151[1014]; // [sp+A7D6h] [bp-5802h] BYREF
char v152[1024]; // [sp+ABCCh] [bp-540Ch] BYREF
char v153[10]; // [sp+AFCCh] [bp-500Ch] BYREF
char v154[1014]; // [sp+AFD6h] [bp-5002h] BYREF
char v155[1024]; // [sp+B3CCh] [bp-4C0Ch] BYREF
char v156[10]; // [sp+B7CCh] [bp-480Ch] BYREF
char v157[1014]; // [sp+B7D6h] [bp-4802h] BYREF
char v158[1024]; // [sp+BBCCh] [bp-440Ch] BYREF
char v159[10]; // [sp+BFCCh] [bp-400Ch] BYREF
char v160[1014]; // [sp+BFD6h] [bp-4002h] BYREF
char v161[1024]; // [sp+C3CCh] [bp-3C0Ch] BYREF
char v162[10]; // [sp+C7CCh] [bp-380Ch] BYREF
char v163[1014]; // [sp+C7D6h] [bp-3802h] BYREF
char v164[1024]; // [sp+CBCCh] [bp-340Ch] BYREF
char v165[10]; // [sp+CFCCh] [bp-300Ch] BYREF
char v166[1014]; // [sp+CFD6h] [bp-3002h] BYREF
char v167[1024]; // [sp+D3CCh] [bp-2C0Ch] BYREF
char v168[10]; // [sp+D7CCh] [bp-280Ch] BYREF
char v169[1014]; // [sp+D7D6h] [bp-2802h] BYREF
char v170[1024]; // [sp+DBCCh] [bp-240Ch] BYREF
char v171[10]; // [sp+DFCCh] [bp-200Ch] BYREF
char v172[1014]; // [sp+DFD6h] [bp-2002h] BYREF
char v173[1024]; // [sp+E3CCh] [bp-1C0Ch] BYREF
char v174[10]; // [sp+E7CCh] [bp-180Ch] BYREF
char v175[1014]; // [sp+E7D6h] [bp-1802h] BYREF
char v176[1024]; // [sp+EBCCh] [bp-140Ch] BYREF
char v177[10]; // [sp+EFCCh] [bp-100Ch] BYREF
char v178[1014]; // [sp+EFD6h] [bp-1002h] BYREF
char v179[1024]; // [sp+F3CCh] [bp-C0Ch] BYREF
char v180[10]; // [sp+F7CCh] [bp-80Ch] BYREF
char v181[1014]; // [sp+F7D6h] [bp-802h] BYREF
char v182[1024]; // [sp+FBCCh] [bp-40Ch] BYREF
pid = getpid();
sub_EE94(v182, 1024, &unk_28756, pid);
v82 = fopen(v182, byte_28748);
if ( v82 )
{
while ( _fgets_chk(v180, 1024, v82, 1024) )
{
if ( !strncmp(v180, byte_2874B, 9u) )
{
if ( atoi(v181) )
{
fclose(v82);
kill(pid, 9);
}
break;
}
}
fclose(v82);
}
v81 = sub_EF00(a1, a3, 0);
v80 = getpid();
sub_EE94(v179, 1024, &unk_28756, v80);
v79 = fopen(v179, byte_28748);
if ( v79 )
{
while ( _fgets_chk(v177, 1024, v79, 1024) )
{
if ( !strncmp(v177, byte_2874B, 9u) )
{
if ( atoi(v178) )
{
fclose(v79);
kill(v80, 9);
}
break;
}
}
fclose(v79);
}
v78 = (unsigned __int8 *)sub_EF00(a1, a4, 0);
v77 = getpid();
sub_EE94(v176, 1024, &unk_28756, v77);
v76 = fopen(v176, byte_28748);
if ( v76 )
{
while ( _fgets_chk(v174, 1024, v76, 1024) )
{
if ( !strncmp(v174, byte_2874B, 9u) )
{
if ( atoi(v175) )
{
fclose(v76);
kill(v77, 9);
}
break;
}
}
fclose(v76);
}
v75 = operator new[](0x10u);
v74 = getpid();
sub_EE94(v173, 1024, &unk_28756, v74);
v73 = fopen(v173, byte_28748);
if ( v73 )
{
while ( _fgets_chk(v171, 1024, v73, 1024) )
{
if ( !strncmp(v171, byte_2874B, 9u) )
{
if ( atoi(v172) )
{
fclose(v73);
kill(v74, 9);
}
break;
}
}
fclose(v73);
}
for ( i = 0; i <= 15; ++i )
{
if ( i > 10 )
{
*(_BYTE *)(v75 + i) = 96;
}
else
{
v71 = getpid();
sub_EE94(v170, 1024, &unk_28756, v71);
v70 = fopen(v170, byte_28748);
if ( v70 )
{
while ( _fgets_chk(v168, 1024, v70, 1024) )
{
if ( !strncmp(v168, byte_2874B, 9u) )
{
if ( atoi(v169) )
{
fclose(v70);
kill(v71, 9);
}
break;
}
}
fclose(v70);
}
if ( *(_BYTE *)(v81 + i) == 32 )
{
v69 = getpid();
sub_EE94(v167, 1024, &unk_28756, v69);
v68 = fopen(v167, byte_28748);
if ( v68 )
{
while ( _fgets_chk(v165, 1024, v68, 1024) )
{
if ( !strncmp(v165, byte_2874B, 9u) )
{
if ( atoi(v166) )
{
fclose(v68);
kill(v69, 9);
}
break;
}
}
fclose(v68);
}
*(_BYTE *)(v75 + i) = 95;
}
else
{
*(_BYTE *)(v75 + i) = *(_BYTE *)(v81 + i);
v67 = getpid();
sub_EE94(v164, 1024, &unk_28756, v67);
v66 = fopen(v164, byte_28748);
if ( v66 )
{
while ( _fgets_chk(v162, 1024, v66, 1024) )
{
if ( !strncmp(v162, byte_2874B, 9u) )
{
if ( atoi(v163) )
{
fclose(v66);
kill(v67, 9);
}
break;
}
}
fclose(v66);
}
}
}
v65 = getpid();
sub_EE94(v161, 1024, &unk_28756, v65);
v64 = fopen(v161, byte_28748);
if ( v64 )
{
while ( _fgets_chk(v159, 1024, v64, 1024) )
{
if ( !strncmp(v159, byte_2874B, 9u) )
{
if ( atoi(v160) )
{
fclose(v64);
kill(v65, 9);
}
break;
}
}
fclose(v64);
}
}
v63 = getpid();
sub_EE94(v158, 1024, &unk_28756, v63);
v62 = fopen(v158, byte_28748);
if ( v62 )
{
while ( _fgets_chk(v156, 1024, v62, 1024) )
{
if ( !strncmp(v156, byte_2874B, 9u) )
{
if ( atoi(v157) )
{
fclose(v62);
kill(v63, 9);
}
break;
}
}
fclose(v62);
}
v58 = *v78;
v57 = getpid();
sub_EE94(v155, 1024, &unk_28756, v57);
v56 = fopen(v155, byte_28748);
if ( v56 )
{
while ( _fgets_chk(v153, 1024, v56, 1024) )
{
if ( !strncmp(v153, byte_2874B, 9u) )
{
if ( atoi(v154) )
{
fclose(v56);
kill(v57, 9);
}
break;
}
}
fclose(v56);
}
v59 = v58 + 73;
v55 = getpid();
sub_EE94(v152, 1024, &unk_28756, v55);
v54 = fopen(v152, byte_28748);
if ( v54 )
{
while ( _fgets_chk(v150, 1024, v54, 1024) )
{
if ( !strncmp(v150, byte_2874B, 9u) )
{
if ( atoi(v151) )
{
fclose(v54);
kill(v55, 9);
}
break;
}
}
fclose(v54);
}
v60 = v59 + 115;
v53 = getpid();
sub_EE94(v149, 1024, &unk_28756, v53);
v52 = fopen(v149, byte_28748);
if ( v52 )
{
while ( _fgets_chk(v147, 1024, v52, 1024) )
{
if ( !strncmp(v147, byte_2874B, 9u) )
{
if ( atoi(v148) )
{
fclose(v52);
kill(v53, 9);
}
break;
}
}
fclose(v52);
}
v61 = v60 - 67;
v51 = getpid();
sub_EE94(v146, 1024, &unk_28756, v51);
v50 = fopen(v146, byte_28748);
if ( v50 )
{
while ( _fgets_chk(v144, 1024, v50, 1024) )
{
if ( !strncmp(v144, byte_2874B, 9u) )
{
if ( atoi(v145) )
{
fclose(v50);
kill(v51, 9);
}
break;
}
}
fclose(v50);
}
if ( 99 * v61 == 22176 )
{
if ( sub_BFBC(v78[31] ^ 0x3E) == 1346269 )
{
v45 = getpid();
sub_EE94(v137, 1024, &unk_28756, v45);
v44 = fopen(v137, byte_28748);
if ( v44 )
{
while ( _fgets_chk(v135, 1024, v44, 1024) )
{
if ( !strncmp(v135, byte_2874B, 9u) )
{
if ( atoi(v136) )
{
fclose(v44);
kill(v45, 9);
}
break;
}
}
fclose(v44);
}
v43 = (_BYTE *)operator new[](0x10u);
v42 = getpid();
sub_EE94(v134, 1024, &unk_28756, v42);
v41 = fopen(v134, byte_28748);
if ( v41 )
{
while ( _fgets_chk(v132, 1024, v41, 1024) )
{
if ( !strncmp(v132, byte_2874B, 9u) )
{
if ( atoi(v133) )
{
fclose(v41);
kill(v42, 9);
}
break;
}
}
fclose(v41);
}
for ( j = 0; j <= 14; ++j )
v43[j + 1] = v78[j + 1];
v39 = getpid();
sub_EE94(v131, 1024, &unk_28756, v39);
v38 = fopen(v131, byte_28748);
if ( v38 )
{
while ( _fgets_chk(v129, 1024, v38, 1024) )
{
if ( !strncmp(v129, byte_2874B, 9u) )
{
if ( atoi(v130) )
{
fclose(v38);
kill(v39, 9);
}
break;
}
}
fclose(v38);
}
*v43 = 94;
v37 = getpid();
sub_EE94(v128, 1024, &unk_28756, v37);
v36 = fopen(v128, byte_28748);
if ( v36 )
{
while ( _fgets_chk(v126, 1024, v36, 1024) )
{
if ( !strncmp(v126, byte_2874B, 9u) )
{
if ( atoi(v127) )
{
fclose(v36);
kill(v37, 9);
}
break;
}
}
fclose(v36);
}
v35 = operator new[](0x10u);
v34 = getpid();
sub_EE94(v125, 1024, &unk_28756, v34);
v33 = fopen(v125, byte_28748);
if ( v33 )
{
while ( _fgets_chk(v123, 1024, v33, 1024) )
{
if ( !strncmp(v123, byte_2874B, 9u) )
{
if ( atoi(v124) )
{
fclose(v33);
kill(v34, 9);
}
break;
}
}
fclose(v33);
}
for ( k = 0; k <= 14; ++k )
*(_BYTE *)(v35 + k) = v78[k + 16];
v31 = getpid();
sub_EE94(v122, 1024, &unk_28756, v31);
v30 = fopen(v122, byte_28748);
if ( v30 )
{
while ( _fgets_chk(v120, 1024, v30, 1024) )
{
if ( !strncmp(v120, byte_2874B, 9u) )
{
if ( atoi(v121) )
{
fclose(v30);
kill(v31, 9);
}
break;
}
}
fclose(v30);
}
*(_BYTE *)(v35 + 15) = 36;
v29 = getpid();
sub_EE94(v119, 1024, &unk_28756, v29);
v28 = fopen(v119, byte_28748);
if ( v28 )
{
while ( _fgets_chk(v117, 1024, v28, 1024) )
{
if ( !strncmp(v117, byte_2874B, 9u) )
{
if ( atoi(v118) )
{
fclose(v28);
kill(v29, 9);
}
break;
}
}
fclose(v28);
}
v27 = operator new[](0x10u);
v26 = getpid();
sub_EE94(v116, 1024, &unk_28756, v26);
v25 = fopen(v116, byte_28748);
if ( v25 )
{
while ( _fgets_chk(v114, 1024, v25, 1024) )
{
if ( !strncmp(v114, byte_2874B, 9u) )
{
if ( atoi(v115) )
{
fclose(v25);
kill(v26, 9);
}
break;
}
}
fclose(v25);
}
v113[0] = unk_94D8;
v113[1] = unk_94E0;
v24 = getpid();
sub_EE94(v112, 1024, &unk_28756, v24);
v23 = fopen(v112, byte_28748);
if ( v23 )
{
while ( _fgets_chk(v110, 1024, v23, 1024) )
{
if ( !strncmp(v110, byte_2874B, 9u) )
{
if ( atoi(v111) )
{
fclose(v23);
kill(v24, 9);
}
break;
}
}
fclose(v23);
}
v109 = unk_94E8;
v22 = getpid();
sub_EE94(v108, 1024, &unk_28756, v22);
v21 = fopen(v108, byte_28748);
if ( v21 )
{
while ( _fgets_chk(v106, 1024, v21, 1024) )
{
if ( !strncmp(v106, byte_2874B, 9u) )
{
if ( atoi(v107) )
{
fclose(v21);
kill(v22, 9);
}
break;
}
}
fclose(v21);
}
sub_13DCC(v27, v43);
v20 = getpid();
sub_EE94(v105, 1024, &unk_28756, v20);
v19 = fopen(v105, byte_28748);
if ( v19 )
{
while ( _fgets_chk(v103, 1024, v19, 1024) )
{
if ( !strncmp(v103, byte_2874B, 9u) )
{
if ( atoi(v104) )
{
fclose(v19);
kill(v20, 9);
}
break;
}
}
fclose(v19);
}
for ( m = 0; m <= 15; ++m )
{
if ( *(unsigned __int8 *)(v27 + m) != *((unsigned __int8 *)v113 + m) )
return;
}
v17 = getpid();
sub_EE94(v102, 1024, &unk_28756, v17);
v16 = fopen(v102, byte_28748);
if ( v16 )
{
while ( _fgets_chk(v100, 1024, v16, 1024) )
{
if ( !strncmp(v100, byte_2874B, 9u) )
{
if ( atoi(v101) )
{
fclose(v16);
kill(v17, 9);
}
break;
}
}
fclose(v16);
}
v15 = operator new[](0x20u);
v14 = getpid();
sub_EE94(v99, 1024, &unk_28756, v14);
v13 = fopen(v99, byte_28748);
if ( v13 )
{
while ( _fgets_chk(v97, 1024, v13, 1024) )
{
if ( !strncmp(v97, byte_2874B, 9u) )
{
if ( atoi(v98) )
{
fclose(v13);
kill(v14, 9);
}
break;
}
}
fclose(v13);
}
qmemcpy(v96, &unk_94F0, sizeof(v96));
v12 = getpid();
sub_EE94(v95, 1024, &unk_28756, v12);
v11 = fopen(v95, byte_28748);
if ( v11 )
{
while ( _fgets_chk(v93, 1024, v11, 1024) )
{
if ( !strncmp(v93, byte_2874B, 9u) )
{
if ( atoi(v94) )
{
fclose(v11);
kill(v12, 9);
}
break;
}
}
fclose(v11);
}
for ( n = 0; n <= 15; n += 4 )
{
v9 = getpid();
sub_EE94(v92, 1024, &unk_28756, v9);
v8 = fopen(v92, byte_28748);
if ( v8 )
{
while ( _fgets_chk(s1, 1024, v8, 1024) )
{
if ( !strncmp(s1, byte_2874B, 9u) )
{
if ( atoi(v91) )
{
fclose(v8);
kill(v9, 9);
}
break;
}
}
fclose(v8);
}
sub_14CC4(v35 + n, 4, v15);
for ( ii = 0; ii <= 7; ++ii )
{
v6 = getpid();
sub_EE94(filename, 1024, &unk_28756, v6);
v5 = fopen(filename, byte_28748);
if ( v5 )
{
while ( _fgets_chk(v87, 1024, v5, 1024) )
{
if ( !strncmp(v87, byte_2874B, 9u) )
{
if ( atoi(v88) )
{
fclose(v5);
kill(v6, 9);
}
break;
}
}
fclose(v5);
}
for ( jj = 3; jj >= 0; --jj )
{
if ( *(unsigned __int8 *)(v15 + jj + 4 * ii) != (unsigned __int8)v96[((8
* (n + ((unsigned int)(n >> 31) >> 30))) & 0xFFFFFFE7)
+ 3
+ 4 * ii
- jj] )
return;
}
}
}
}
else
{
v47 = getpid();
sub_EE94(v140, 1024, &unk_28756, v47);
v46 = fopen(v140, byte_28748);
if ( v46 )
{
while ( _fgets_chk(v138, 1024, v46, 1024) )
{
if ( !strncmp(v138, byte_2874B, 9u) )
{
if ( atoi(v139) )
{
fclose(v46);
kill(v47, 9);
}
break;
}
}
fclose(v46);
}
}
}
else
{
v49 = getpid();
sub_EE94(v143, 1024, &unk_28756, v49);
v48 = fopen(v143, byte_28748);
if ( v48 )
{
while ( _fgets_chk(v141, 1024, v48, 1024) )
{
if ( !strncmp(v141, byte_2874B, 9u) )
{
if ( atoi(v142) )
{
fclose(v48);
kill(v49, 9);
}
break;
}
}
fclose(v48);
}
}
}
这个是去垃圾代码之后的:
int __fastcall sub_C010(int a1, int a2, int a3, int a4)
{
int jj; // [sp+27Ch] [bp-FD5Ch]
int ii; // [sp+28Ch] [bp-FD4Ch]
int n; // [sp+29Ch] [bp-FD3Ch]
int v8; // [sp+2B8h] [bp-FD20h]
int m; // [sp+2C8h] [bp-FD10h]
int v10; // [sp+2FCh] [bp-FCDCh]
int k; // [sp+318h] [bp-FCC0h]
int v12; // [sp+328h] [bp-FCB0h]
int j; // [sp+344h] [bp-FC94h]
_BYTE *v14; // [sp+354h] [bp-FC84h]
int i; // [sp+3ECh] [bp-FBECh]
int v16; // [sp+3FCh] [bp-FBDCh]
unsigned __int8 *v17; // [sp+40Ch] [bp-FBCCh]
int v18; // [sp+41Ch] [bp-FBBCh]
_BYTE v22[7376]; // [sp+1F30h] [bp-E0A8h] BYREF
__int64 v23; // [sp+3FB0h] [bp-C028h]
_QWORD v24[5890]; // [sp+47B8h] [bp-B820h]
v18 = sub_EF00(a1, a3, 0);
v17 = (unsigned __int8 *)sub_EF00(a1, a4, 0);
v16 = operator new[](0x10u);
for ( i = 0; i <= 15; ++i )
{
if ( i > 10 )
{
*(_BYTE *)(v16 + i) = 96;
}
else if ( *(_BYTE *)(v18 + i) == 32 )
{
*(_BYTE *)(v16 + i) = 95;
}
else
{
*(_BYTE *)(v16 + i) = *(_BYTE *)(v18 + i);
}
}
if ( 99 * (*v17 + 121) != 22176 )
return 0;
if ( sub_BFBC(v17[31] ^ 0x3E) != 1346269 )
return 0;
v14 = (_BYTE *)operator new[](0x10u);
for ( j = 0; j <= 14; ++j )
v14[j + 1] = v17[j + 1];
*v14 = 94;
v12 = operator new[](0x10u);
for ( k = 0; k <= 14; ++k )
*(_BYTE *)(v12 + k) = v17[k + 16];
*(_BYTE *)(v12 + 15) = 36;
v10 = operator new[](0x10u);
v24[0] = unk_94D8;
v24[1] = unk_94E0;
v23 = unk_94E8;
sub_13DCC(v10, v14);
for ( m = 0; m <= 15; ++m )
{
if ( *(unsigned __int8 *)(v10 + m) != *((unsigned __int8 *)v24 + m) )
return 0;
}
v8 = operator new[](0x20u);
qmemcpy(v22, &unk_94F0, 0x80u);
for ( n = 0; n <= 15; n += 4 )
{
sub_14CC4(v12 + n, 4, v8);
for ( ii = 0; ii <= 7; ++ii )
{
for ( jj = 3; jj >= 0; --jj )
{
if ( *(unsigned __int8 *)(v8 + jj + 4 * ii) != (unsigned __int8)v22[((8 * (n + ((unsigned int)(n >> 31) >> 30))) & 0xFFFFFFE7) + 3 + 4 * ii - jj] )
return 0;
}
}
}
return 1;
}
直接舒适。看这样子,v81
应该是传入的str
(下面还是叫str1
吧,不然太怪了),v82
应该是传入的str2
,那就改改变量名然后修修类型定义吧,方便分析:
int __fastcall sub_C010(int a1, int a2, int a3, int a4)
{
int k; // [sp+27Ch] [bp-FD5Ch]
int j; // [sp+28Ch] [bp-FD4Ch]
int i; // [sp+29Ch] [bp-FD3Ch]
_BYTE *v8; // [sp+2B8h] [bp-FD20h]
int i4; // [sp+2C8h] [bp-FD10h]
_BYTE *str2_first_13dcc; // [sp+2FCh] [bp-FCDCh]
int i3; // [sp+318h] [bp-FCC0h]
_BYTE *str2_second; // [sp+328h] [bp-FCB0h]
int i2; // [sp+344h] [bp-FC94h]
_BYTE *str2_first; // [sp+354h] [bp-FC84h]
int i1; // [sp+3ECh] [bp-FBECh]
char *str1_padding; // [sp+3FCh] [bp-FBDCh]
char *str2; // [sp+40Ch] [bp-FBCCh]
char *str1; // [sp+41Ch] [bp-FBBCh]
_BYTE v22[7376]; // [sp+1F30h] [bp-E0A8h] BYREF
__int64 v23; // [sp+3FB0h] [bp-C028h]
_QWORD str2_first_check[5890]; // [sp+47B8h] [bp-B820h]
str1 = (char *)sub_EF00(a1, a3, 0);
str2 = (char *)sub_EF00(a1, a4, 0);
str1_padding = (char *)operator new[](0x10u);
for ( i1 = 0; i1 <= 15; ++i1 )
{
if ( i1 > 10 )
{
str1_padding[i1] = '`';
}
else if ( str1[i1] == ' ' )
{
str1_padding[i1] = '_';
}
else
{
str1_padding[i1] = str1[i1];
}
}
if ( 99 * ((unsigned __int8)*str2 + 121) != 22176 )
return 0;
if ( sub_BFBC((unsigned __int8)str2[31] ^ 0x3E) != 1346269 )
return 0;
str2_first = (_BYTE *)operator new[](0x10u);
for ( i2 = 0; i2 <= 14; ++i2 )
str2_first[i2 + 1] = str2[i2 + 1];
*str2_first = '^';
str2_second = (_BYTE *)operator new[](0x10u);
for ( i3 = 0; i3 <= 14; ++i3 )
str2_second[i3] = str2[i3 + 16];
str2_second[15] = '$';
str2_first_13dcc = (_BYTE *)operator new[](0x10u);
str2_first_check[0] = 0x3792E3B27AD96E0FLL;
str2_first_check[1] = 0x8C18A8950DE1876DLL;
v23 = 0x3D69266D7A0A434FLL;
sub_13DCC(str2_first_13dcc, str2_first);
for ( i4 = 0; i4 <= 15; ++i4 )
{
if ( str2_first_13dcc[i4] != *((_BYTE *)str2_first_check + i4) )
return 0;
}
v8 = (_BYTE *)operator new[](0x20u);
qmemcpy(v22, byte_94F0, 0x80u);
for ( i = 0; i <= 15; i += 4 )
{
sub_14CC4((int)&str2_second[i], 4u, (int)v8);
for ( j = 0; j <= 7; ++j )
{
for ( k = 3; k >= 0; --k )
{
if ( v8[4 * j + k] != v22[((8 * (i + ((unsigned int)(i >> 31) >> 30))) & 0xFFFFFFE7) + 3 + 4 * j - k] )
return 0;
}
}
}
return 1;
}
先是对str1
进行填充和替换,得到str1_padding="iscc_xhzg!!
```"
,不过后面没有用上,猜测是哪个函数定义出问题了导致传参没传上,待会找到了是哪个函数再修。
然后看看str2
吧,先是(str2[0]+121)*99==22176
,那就反过来算一下str2[0]
是啥咯。
22176 / 99 - 121 = 103
也就是str2[0]=103='g'
。
然后是sub_BFBC(str[31]^0x3e)==1346269
,那就去看看sub_BFBC
的逻辑。
一个很经典的求斐波那契函数,那么斐波那契数1346269
是第31
个,所以str2[31]=31^0x3e=33='!'
。
那么接着回去看主函数的逻辑,将str2
分为前半部分和后半部分分别处理,得到str2_first="^"+str2[1:16]
和str2_second=str2[16:31]+"$"
。
然后是对str2_first
用sub_13DCC
处理得到str2_first_13dcc
,那就去看sub_13DCC
。
看了下不对啊,怎么就6个参数了,调用那边不是2个参数吗?回头看下调用的汇编:
确实少了几个参数没解析出来,那重新F5强刷一下,成功变成6个传参。
int __fastcall sub_C010(int a1, int a2, int a3, int a4)
{
int k; // [sp+27Ch] [bp-FD5Ch]
int j; // [sp+28Ch] [bp-FD4Ch]
int i; // [sp+29Ch] [bp-FD3Ch]
_BYTE *str2_second_14CC4; // [sp+2B8h] [bp-FD20h]
int i4; // [sp+2C8h] [bp-FD10h]
_BYTE *str2_first_13dcc; // [sp+2FCh] [bp-FCDCh]
int i3; // [sp+318h] [bp-FCC0h]
_BYTE *str2_second; // [sp+328h] [bp-FCB0h]
int i2; // [sp+344h] [bp-FC94h]
_BYTE *str2_first; // [sp+354h] [bp-FC84h]
int i1; // [sp+3ECh] [bp-FBECh]
char *str1_padding; // [sp+3FCh] [bp-FBDCh]
char *str2; // [sp+40Ch] [bp-FBCCh]
char *str1; // [sp+41Ch] [bp-FBBCh]
_BYTE str2_second_check[7376]; // [sp+1F30h] [bp-E0A8h] BYREF
__int64 str2_first_key[257]; // [sp+3FB0h] [bp-C028h] BYREF
_QWORD str2_first_check[5890]; // [sp+47B8h] [bp-B820h]
str1 = (char *)sub_EF00(a1, a3, 0);
str2 = (char *)sub_EF00(a1, a4, 0);
str1_padding = (char *)operator new[](0x10u);
for ( i1 = 0; i1 <= 15; ++i1 )
{
if ( i1 > 10 )
{
str1_padding[i1] = '`';
}
else if ( str1[i1] == ' ' )
{
str1_padding[i1] = '_';
}
else
{
str1_padding[i1] = str1[i1];
}
}
if ( 99 * ((unsigned __int8)*str2 + 121) != 22176 )
return 0;
if ( sub_BFBC((unsigned __int8)str2[31] ^ 0x3E) != 1346269 )
return 0;
str2_first = (_BYTE *)operator new[](0x10u);
for ( i2 = 0; i2 <= 14; ++i2 )
str2_first[i2 + 1] = str2[i2 + 1];
*str2_first = '^';
str2_second = (_BYTE *)operator new[](0x10u);
for ( i3 = 0; i3 <= 14; ++i3 )
str2_second[i3] = str2[i3 + 16];
str2_second[15] = '$';
str2_first_13dcc = (_BYTE *)operator new[](0x10u);
str2_first_check[0] = 0x3792E3B27AD96E0FLL;
str2_first_check[1] = 0x8C18A8950DE1876DLL;
str2_first_key[0] = 0x3D69266D7A0A434FLL;
sub_13DCC(str2_first_13dcc, str2_first, 16, str1_padding, 16, str2_first_key);
for ( i4 = 0; i4 <= 15; ++i4 )
{
if ( str2_first_13dcc[i4] != *((_BYTE *)str2_first_check + i4) )
return 0;
}
str2_second_14CC4 = (_BYTE *)operator new[](0x20u);
qmemcpy(str2_second_check, byte_94F0, 0x80u);
for ( i = 0; i <= 15; i += 4 )
{
sub_14CC4((int)&str2_second[i], 4u, (int)str2_second_14CC4);
for ( j = 0; j <= 7; ++j )
{
for ( k = 3; k >= 0; --k )
{
if ( str2_second_14CC4[4 * j + k] != str2_second_check[((8 * (i + ((unsigned int)(i >> 31) >> 30))) & 0xFFFFFFE7) + 3 + 4 * j - k] )
return 0;
}
}
}
return 1;
}
重新看sub_13DCC
(变量名称优化过了)。
int __fastcall sub_13DCC(
_BYTE *str2_first_13dcc,
_BYTE *str2_first,
int x_16,
char *str1_padding,
int y_16,
_BYTE *str2_first_key)
{
unsigned int size; // [sp+17Ch] [bp-5ACCh]
_BYTE *str2_first_key_; // [sp+184h] [bp-5AC4h]
_BYTE *v12; // [sp+234h] [bp-5A14h]
int v13[3]; // [sp+5AB0h] [bp-198h] BYREF
_BYTE str1_padding_112F4[384]; // [sp+5ABCh] [bp-18Ch] BYREF
v13[1] = 0;
v13[0] = 0;
if ( str2_first_key )
str2_first_key_ = str2_first_key;
else
str2_first_key_ = v13;
if ( y_16 == 16 )
{
sub_112F4(str1_padding_112F4, str1_padding);
}
else if ( y_16 == 24 )
{
sub_11AC4(str1_padding_112F4, str1_padding);
}
if ( (unsigned __int8)x_16 << 29 )
{
size = (x_16 & 0xFFFFFFF8) + 8;
v12 = calloc(1u, size);
_memcpy_chk(v12, str2_first, x_16, -1);
sub_13440(str1_padding_112F4, 1, size, str2_first_key_, v12, str2_first_13dcc);
free(v12);
}
else
{
sub_13440(str1_padding_112F4, 1, x_16, str2_first_key_, str2_first, str2_first_13dcc);
}
sub_FBFC(str1_padding_112F4);
return x_16;
}
先是把str1_padding
用sub_112F4
处理成str1_padding_112F4
,那就去看看sub_112F4
。
那就去看看sub_115B0
。
那就去看看sub_FF48
。
好多的位运算,开头那两段可以用我写的BitwiseExpressionSimplifier进行化简得到其本质上的运算结果。
为了方便逆向先写个正向脚本吧(写正向的时候改了好多回才测试正确)。
def sub_FF48(ipt):
def simplify():
from BitwiseExpressionSimplifier import toNOperation
base = toNOperation("(x^(y>>4))&0xf0f0f0f", 32, {'x', 'y'})
x = toNOperation("x^v6", 32, {'x'}, {'v6': base})
y = toNOperation("y^(v6<<4)", 32, {'y'}, {'v6': base})
print(x.bitwise)
print(y.bitwise)
x = toNOperation("x^(y^x)&0x10101010", 32, {'x', 'y'})
y = toNOperation("y^(y^x)&0x10101010", 32, {'x', 'y'})
print(x.bitwise)
print(y.bitwise)
simplify()
x, y = ipt[0:4], ipt[4:8]
x, y = [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)], [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)]
x, y = [(x[i] & 0b11101111) | (y[i] & 0b00010000) for i in range(4)], [(y[i] & 0b11101111) | (x[i] & 0b00010000) for i in range(4)]
mask1 = [
0x00000000, 0x00000001,
0x00000100, 0x00000101,
0x00010000, 0x00010001, 0x00010100, 0x00010101,
0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010100, 0x01010101,
]
mask2 = [
0x00000000, 0x01000000,
0x00010000, 0x01010000,
0x00000100, 0x01000100,
0x00010100, 0x01010100,
0x00000001, 0x01000001,
0x00010001, 0x01010001,
0x00000101, 0x01000101,
0x00010101, 0x01010101,
]
x = int(bytearray(x).hex(), 16)
x = (mask1[(x >> 0) & 0xf] << 3) | (mask1[(x >> 8) & 0xf] << 2) | (mask1[(x >> 16) & 0xf] << 1) | (mask1[(x >> 24) & 0xf] << 0)\
| (mask1[(x >> 5) & 0xf] << 7) | (mask1[(x >> 13) & 0xf] << 6) | (mask1[(x >> 21) & 0xf] << 5) | (mask1[(x >> 29) & 0xf] << 4)
x = x & 0x0fffffff
y = int(bytearray(y).hex(), 16)
y = (mask2[(y >> 1) & 0xf] << 3) | (mask2[(y >> 9) & 0xf] << 2) | (mask2[(y >> 17) & 0xf] << 1) | (mask2[(y >> 25) & 0xf] << 0)\
| (mask2[(y >> 4) & 0xf] << 7) | (mask2[(y >> 12) & 0xf] << 6) | (mask2[(y >> 20) & 0xf] << 5) | (mask2[(y >> 28) & 0xf] << 4)
y = y & 0x0fffffff
rtn = []
for i in range(16):
if i in {0, 1, 8, 15}:
x = ((x << 1) | (x >> 27)) & 0x0fffffff
y = ((y << 1) | (y >> 27)) & 0x0fffffff
else:
x = ((x << 2) | (x >> 26)) & 0x0fffffff
y = ((y << 2) | (y >> 26)) & 0x0fffffff
rtn.append(
0
| (x << 4) & 0b100000000000000000000000000000
| (x << 28) & 0b10000000000000000000000000000
| (x << 14) & 0b1000000000000000000000000000
| (x << 4) & 0b100000000000000000000000000
| (x << 18) & 0b10000000000000000000000000
| (x << 6) & 0b1000000000000000000000000
| (x << 9) & 0b1000000000000000000000
| (x >> 1) & 0b100000000000000000000
| (x << 18) & 0b10000000000000000000
| (x << 10) & 0b1000000000000000000
| (x << 2) & 0b100000000000000000
| (x >> 10) & 0b10000000000000000
| (y >> 13) & 0b10000000000000
| (y >> 4) & 0b1000000000000
| (y << 6) & 0b100000000000
| (y >> 1) & 0b10000000000
| (y >> 14) & 0b1000000000
| (y >> 0) & 0b100000000
| (y >> 5) & 0b100000
| (y >> 10) & 0b10000
| (y >> 3) & 0b1000
| (y >> 18) & 0b100
| (y >> 26) & 0b10
| (y >> 24) & 0b1
)
rtn.append(
0
| (x << 15) & 0b100000000000000000000000000000
| (x << 17) & 0b10000000000000000000000000000
| (x << 10) & 0b1000000000000000000000000000
| (x << 22) & 0b100000000000000000000000000
| (x >> 2) & 0b10000000000000000000000000
| (x << 1) & 0b1000000000000000000000000
| (x << 16) & 0b1000000000000000000000
| (x << 11) & 0b100000000000000000000
| (x << 3) & 0b10000000000000000000
| (x >> 6) & 0b1000000000000000000
| (x << 15) & 0b100000000000000000
| (x >> 4) & 0b10000000000000000
| (y >> 2) & 0b10000000000000
| (y << 8) & 0b1000000000000
| (y >> 14) & 0b100000000000
| (y >> 9) & 0b10000000000
| (y >> 0) & 0b1000000000
| (y << 7) & 0b100000000
| (y >> 7) & 0b100000
| (y >> 3) & 0b10000
| (y >> 14) & 0b1000
| (y << 2) & 0b100
| (y >> 21) & 0b10
| (y >> 3) & 0b1
)
for i in range(len(rtn)):
rtn[i] = bytes.fromhex(("00000000" + hex(rtn[i])[2:])[-8:])[::-1].hex()
return rtn
关于验证正向脚本的逻辑正确性,我选择的是用frida hook
去调用函数,看看随机的相同传参在原程序和正向脚本能不能出现相同的结果。
Java.perform(function () {
console.log()
const LoginActivity = Java.use('com.ctf.zzgfrev.ui.login.LoginActivity')
LoginActivity.onStart.overload().implementation = function () {
const libzzgf = Module.findBaseAddress("libzzgf.so")
console.log(`libzzgf=${libzzgf}`)
if (libzzgf != null) {
const fun_FF48_ptr = libzzgf.add(0xFF48+1)
const fun_FF48 = new NativeFunction(fun_FF48_ptr, 'int', ['pointer', 'pointer'])
const ret = Memory.alloc(4*2*16)
const input = Memory.alloc(4*2)
input.writeByteArray([3, 5, 13, 17, 25, 37, 49, 68])
ret.writeByteArray(Array(4*2*16).fill(0))
fun_FF48(ret, input)
console.log(hexdump(input, {length:4*2, ansi:true}))
console.log(hexdump(ret, {length:4*2*16, ansi:true}))
}
this.onStart.overload().call(this);
}
})
验证成功,所以现在sub_FF48
的功能理清楚了,就是个根据输入的8字节数据生成128字节数据。
那么去写个完整的正向脚本吧,把现在已知的逻辑都给写上,然后一个一个验证看看对不对,对了之后照着这个脚本逆向就完事。
当前正向脚本:
def sub_FF48(ipt: bytes) -> bytes:
x, y = ipt[0:4], ipt[4:8]
x, y = [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)], [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)]
x, y = [(x[i] & 0b11101111) | (y[i] & 0b00010000) for i in range(4)], [(y[i] & 0b11101111) | (x[i] & 0b00010000) for i in range(4)]
mask1 = [
0x00000000, 0x00000001,
0x00000100, 0x00000101,
0x00010000, 0x00010001, 0x00010100, 0x00010101,
0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010100, 0x01010101,
]
mask2 = [
0x00000000, 0x01000000,
0x00010000, 0x01010000,
0x00000100, 0x01000100,
0x00010100, 0x01010100,
0x00000001, 0x01000001,
0x00010001, 0x01010001,
0x00000101, 0x01000101,
0x00010101, 0x01010101,
]
x = int(bytearray(x).hex(), 16)
x = (mask1[(x >> 0) & 0xf] << 3) | (mask1[(x >> 8) & 0xf] << 2) | (mask1[(x >> 16) & 0xf] << 1) | (mask1[(x >> 24) & 0xf] << 0)\
| (mask1[(x >> 5) & 0xf] << 7) | (mask1[(x >> 13) & 0xf] << 6) | (mask1[(x >> 21) & 0xf] << 5) | (mask1[(x >> 29) & 0xf] << 4)
x = x & 0x0fffffff
y = int(bytearray(y).hex(), 16)
y = (mask2[(y >> 1) & 0xf] << 3) | (mask2[(y >> 9) & 0xf] << 2) | (mask2[(y >> 17) & 0xf] << 1) | (mask2[(y >> 25) & 0xf] << 0)\
| (mask2[(y >> 4) & 0xf] << 7) | (mask2[(y >> 12) & 0xf] << 6) | (mask2[(y >> 20) & 0xf] << 5) | (mask2[(y >> 28) & 0xf] << 4)
y = y & 0x0fffffff
result = []
for i in range(16):
if i in {0, 1, 8, 15}:
x = ((x << 1) | (x >> 27)) & 0x0fffffff
y = ((y << 1) | (y >> 27)) & 0x0fffffff
else:
x = ((x << 2) | (x >> 26)) & 0x0fffffff
y = ((y << 2) | (y >> 26)) & 0x0fffffff
result.append(
0
| (x << 4) & 0b100000000000000000000000000000
| (x << 28) & 0b10000000000000000000000000000
| (x << 14) & 0b1000000000000000000000000000
| (x << 4) & 0b100000000000000000000000000
| (x << 18) & 0b10000000000000000000000000
| (x << 6) & 0b1000000000000000000000000
| (x << 9) & 0b1000000000000000000000
| (x >> 1) & 0b100000000000000000000
| (x << 18) & 0b10000000000000000000
| (x << 10) & 0b1000000000000000000
| (x << 2) & 0b100000000000000000
| (x >> 10) & 0b10000000000000000
| (y >> 13) & 0b10000000000000
| (y >> 4) & 0b1000000000000
| (y << 6) & 0b100000000000
| (y >> 1) & 0b10000000000
| (y >> 14) & 0b1000000000
| (y >> 0) & 0b100000000
| (y >> 5) & 0b100000
| (y >> 10) & 0b10000
| (y >> 3) & 0b1000
| (y >> 18) & 0b100
| (y >> 26) & 0b10
| (y >> 24) & 0b1
)
result.append(
0
| (x << 15) & 0b100000000000000000000000000000
| (x << 17) & 0b10000000000000000000000000000
| (x << 10) & 0b1000000000000000000000000000
| (x << 22) & 0b100000000000000000000000000
| (x >> 2) & 0b10000000000000000000000000
| (x << 1) & 0b1000000000000000000000000
| (x << 16) & 0b1000000000000000000000
| (x << 11) & 0b100000000000000000000
| (x << 3) & 0b10000000000000000000
| (x >> 6) & 0b1000000000000000000
| (x << 15) & 0b100000000000000000
| (x >> 4) & 0b10000000000000000
| (y >> 2) & 0b10000000000000
| (y << 8) & 0b1000000000000
| (y >> 14) & 0b100000000000
| (y >> 9) & 0b10000000000
| (y >> 0) & 0b1000000000
| (y << 7) & 0b100000000
| (y >> 7) & 0b100000
| (y >> 3) & 0b10000
| (y >> 14) & 0b1000
| (y << 2) & 0b100
| (y >> 21) & 0b10
| (y >> 3) & 0b1
)
rtn = []
for i, v in enumerate(result):
rtn.extend(bytes.fromhex(("00000000" + hex(v)[2:])[-8:])[::-1])
return bytes(rtn)
def fibonacci_BFBC(index):
if index == 1 or index == 2:
return 1
v2 = fibonacci_BFBC(index - 1)
return v2 + fibonacci_BFBC(index - 2)
def sub_13DCC(str2_first_13dcc, str2_first, x_16, str1_padding, y_16, str2_first_key):
print("sub_13DCC")
print(f"sub_13DCC => {str2_first_13dcc.hex() = }")
print(f"sub_13DCC => {str2_first = }")
print(f"sub_13DCC => {x_16 = }")
print(f"sub_13DCC => {str1_padding = }")
print(f"sub_13DCC => {y_16 = }")
print(f"sub_13DCC => {str2_first_key = }")
str1_padding_112F4 = bytearray(384)
sub_112F4(str1_padding_112F4, str1_padding) # if y_16 == 16
sub_13440(str1_padding_112F4, 1, x_16, str2_first_key, str2_first, str2_first_13dcc)
print(f"❌ sub_13DCC <= {str2_first_13dcc.hex() = }")
def sub_112F4(str1_padding_112F4, str1_padding):
print("sub_112F4")
print(f"sub_112F4 => {str1_padding_112F4.hex() = }")
print(f"sub_112F4 => {str1_padding = }")
sub_115B0(str1_padding_112F4, bytearray(384), str1_padding)
print(f"✔ sub_112F4 <= {str1_padding_112F4.hex() = }")
def sub_115B0(str1_padding_112F4, a2, str1_padding):
print("sub_115B0")
print(f"sub_115B0 => {str1_padding_112F4.hex() = }")
print(f"sub_115B0 => {a2.hex() = }")
print(f"sub_115B0 => {str1_padding = }")
str1_padding_112F4[0:128] = sub_FF48(str1_padding[0:8])
a2[128:256] = sub_FF48(str1_padding[8:16])
for i in range(0, 32, 2):
a2[i*4: i*4+4] = str1_padding_112F4[(30 - i)*4:(30 - i)*4+4]
a2[(i + 1)*4:(i + 1)*4+4] = str1_padding_112F4[(31 - i)*4:(31 - i)*4+4]
str1_padding_112F4[(i + 32)*4:(i + 32)*4+4] = a2[(62 - i)*4:(62 - i)*4+4]
str1_padding_112F4[(i + 33)*4:(i + 33)*4+4] = a2[(63 - i)*4:(63 - i)*4+4]
str1_padding_112F4[(i + 64)*4:(i + 64)*4+4] = str1_padding_112F4[i*4:i*4+4]
str1_padding_112F4[(i + 65)*4:(i + 65)*4+4] = str1_padding_112F4[(i + 1)*4:(i + 1)*4+4]
a2[(i + 64)*4:(i + 64)*4+4] = a2[i*4:i*4+4]
a2[(i + 65)*4:(i + 65)*4+4] = a2[(i + 1)*4:(i + 1)*4+4]
print(f"✔ sub_115B0 <= {str1_padding_112F4.hex() = }")
print(f"✔ sub_115B0 <= {a2.hex() = }")
def sub_13440(str1_padding_112F4, x_1, x_16, str2_first_key, str2_first, str2_first_13dcc):
...
def sub_14CC4(c, x_4):
...
def sub_C010(str1: bytes, str2: bytes):
str1_padding = str1[:11].replace(b' ', b'_') + b"`````"
assert (str2[0] + 121) * 99 == 22176
assert fibonacci_BFBC(str2[31] ^ 0x3e) == 1346269
str2_first = b"^" + str2[1:16]
str2_second = str2[16:31] + b"$"
str2_first_check = bytes([0x0F, 0x6E, 0xD9, 0x7A, 0xB2, 0xE3, 0x92, 0x37] + [0x6D, 0x87, 0xE1, 0x0D, 0x95, 0xA8, 0x18, 0x8C])
str2_first_key = bytes([0x4F, 0x43, 0x0A, 0x7A, 0x6D, 0x26, 0x69, 0x3D])
str2_first_13dcc = bytearray(16)
sub_13DCC(str2_first_13dcc, str2_first, 16, str1_padding, 16, str2_first_key)
assert str2_first_13dcc == str2_first_check
str2_second_check = bytes([
0x9C, 0xCD, 0x4B, 0x31, 0xF4, 0xD9, 0xA2, 0xD3, 0xDA, 0xDC, 0x63, 0xF2, 0x46, 0x2C, 0x14, 0xE4,
0xAF, 0xBD, 0xFD, 0x0C, 0x12, 0xD3, 0x43, 0x8F, 0x0F, 0xE7, 0xE5, 0xC0, 0x3F, 0x0A, 0xFE, 0x07,
0x53, 0xA0, 0x65, 0x81, 0xAA, 0x57, 0x16, 0x3C, 0xB9, 0x09, 0x8C, 0xCE, 0x48, 0xA1, 0xC6, 0xB1,
0x62, 0x73, 0xDD, 0x8C, 0x46, 0xAC, 0x1F, 0xAF, 0xDC, 0xDC, 0xF4, 0x9F, 0x18, 0x61, 0xF4, 0x3D,
0x14, 0xCE, 0x27, 0x05, 0xE2, 0xEB, 0xBF, 0xFD, 0x07, 0x36, 0x5A, 0xA8, 0x98, 0x5B, 0xED, 0x00,
0x60, 0xCC, 0xF4, 0xDE, 0xC7, 0x77, 0x6E, 0xB2, 0x3D, 0x10, 0x6C, 0x7F, 0xC5, 0xBB, 0xDA, 0xD1,
0xA7, 0x24, 0x57, 0xA5, 0xB8, 0x05, 0xF6, 0xC2, 0xC9, 0x09, 0xE7, 0xFD, 0xA7, 0x0B, 0xC5, 0x7B,
0x6D, 0xB8, 0xB3, 0x45, 0x45, 0x4E, 0x35, 0xEF, 0x5E, 0x4A, 0xC0, 0xAE, 0x01, 0xE3, 0x3D, 0x2B,
])
for i in range(0, 16, 4):
str2_second_14CC4 = sub_14CC4(str2_second[i], 4)
for j in range(8):
for k in range(4):
assert str2_second_14CC4[4 * j + k] == str2_second_check[((8 * i) & 0xFFFFFFE7) + 4 * j + (3 - k)]
if __name__ == '__main__':
print()
sub_C010(b"iscc xhzg!!", b"g000000000000000000000000000000!")
# print(sub_FF48([3, 5, 13, 17, 25, 37, 49, 68]))
验证脚本:
function buf2hex(buffer: ArrayBuffer) {
const byteArray = new Uint8Array(buffer)
const hexParts = []
for(let i = 0; i < byteArray.length; i++) {
hexParts.push(('00' + byteArray[i].toString(16)).slice(-2))
}
return `\x1b[33m${hexParts.join('')}\x1b[0m`
}
Java.perform(function () {
console.log()
const LoginActivity = Java.use('com.ctf.zzgfrev.ui.login.LoginActivity')
LoginActivity.onStart.overload().implementation = function () {
const libzzgf = Module.findBaseAddress("libzzgf.so")
console.log(`libzzgf=${libzzgf}`)
if (libzzgf != null) {
const sub_13DCC_ptr = libzzgf.add(0x13DCC+1)
let sub_13DCC_str2_first_13dcc: NativePointer
Interceptor.attach(sub_13DCC_ptr, {
onEnter: function (args) {
console.log("sub_13DCC")
console.log(`sub_13DCC \x1b[34m=>\x1b[0m str2_first_13dcc = ${buf2hex(args[0].readByteArray(0x10)!)}`)
console.log(`sub_13DCC \x1b[34m=>\x1b[0m str2_first = ${args[1].readCString(0x10)}`)
console.log(`sub_13DCC \x1b[34m=>\x1b[0m x_16 = ${args[2]}`)
console.log(`sub_13DCC \x1b[34m=>\x1b[0m str1_padding = ${args[3].readCString(0x10)}`)
console.log(`sub_13DCC \x1b[34m=>\x1b[0m y_16 = ${args[4]}`)
console.log(`sub_13DCC \x1b[34m=>\x1b[0m str2_first_key = ${buf2hex(args[5].readByteArray(8)!)}`)
sub_13DCC_str2_first_13dcc = args[0]
},
onLeave: function (retval) {
console.log(`sub_13DCC \x1b[32m<=\x1b[0m str2_first_13dcc = ${buf2hex(sub_13DCC_str2_first_13dcc.readByteArray(0x10)!)}`)
}
})
const sub_112F4_ptr = libzzgf.add(0x112F4+1)
let sub_112F4_str1_padding_112F4: NativePointer
Interceptor.attach(sub_112F4_ptr, {
onEnter: function (args) {
console.log("sub_112F4")
console.log(`sub_112F4 \x1b[34m=>\x1b[0m str1_padding_112F4 = ${buf2hex(args[0].readByteArray(384)!)}`)
console.log(`sub_112F4 \x1b[34m=>\x1b[0m str1_padding = ${args[1].readCString(0x10)}`)
sub_112F4_str1_padding_112F4 = args[0]
},
onLeave: function (retval) {
console.log(`sub_112F4 \x1b[32m<=\x1b[0m str1_padding_112F4 = ${buf2hex(sub_112F4_str1_padding_112F4.readByteArray(384)!)}`)
}
})
const sub_115B0_ptr = libzzgf.add(0x115B0+1)
let sub_115B0_str1_padding_112F4: NativePointer
let sub_115B0_a2: NativePointer
Interceptor.attach(sub_115B0_ptr, {
onEnter: function (args) {
console.log("sub_115B0")
console.log(`sub_115B0 \x1b[34m=>\x1b[0m str1_padding_112F4 = ${buf2hex(args[0].readByteArray(384)!)}`)
console.log(`sub_115B0 \x1b[34m=>\x1b[0m a2 = ${buf2hex(args[1].readByteArray(384)!)}`)
sub_115B0_str1_padding_112F4 = args[0]
sub_115B0_a2 = args[1]
},
onLeave: function (retval) {
console.log(`sub_115B0 \x1b[32m<=\x1b[0m str1_padding_112F4 = ${buf2hex(sub_115B0_str1_padding_112F4.readByteArray(384)!)}`)
console.log(`sub_115B0 \x1b[32m<=\x1b[0m a2 = ${buf2hex(sub_115B0_a2.readByteArray(384)!)}`)
}
})
}
const LoginDataSource = Java.use('com.ctf.zzgfrev.data.LoginDataSource').$new()
console.log(
`l1ll1l1ll1l1lll1ll1l11l1l("iscc xhzg!!", "ISCC{g000000000000000000000000000000!}")`,
LoginDataSource.l1ll1l1ll1l1lll1ll1l11l1l(
"iscc xhzg!!",
"ISCC{g000000000000000000000000000000!}"
)
)
this.onStart.overload().call(this)
}
})
可以看到直到sub_112F4
调用结束,其数据都是正确的,那么接着去看sub_13440
就完事。
大致逻辑就是开个2次的循环去处理str2_first
和str2_first_key
生成的初始数str2_first_13dcc
,然后由sub_123B8
带着str1_padding_112F4
处理,接着那个memcpy
不确定要不要执行,因为IDA
的那个-1
可能是0xFFFFFFFF
,然后这样子的话就可以被执行,所以后面搞好了正向的验证一下吧,现在先不管。接着是处理循环步进,其实很明显可以看出来是分成前后两个8字节去处理,然后正好串到str2_first_13dcc
去就行了。
所以正向脚本大概如下:
def sub_13440(str1_padding_112F4, x_1, x_16, str2_first_key, str2_first, str2_first_13dcc):
for x in range(x_16//8):
for i in range(8):
str2_first_13dcc[i + 8 * x] = str2_first[i + 8 * x] ^ str2_first_key[i]
str2_first_13dcc_tmp = str2_first_13dcc[8 * x:8 * (x+1)].copy()
sub_123B8(str1_padding_112F4, str2_first_13dcc_tmp)
str2_first_13dcc[8 * x:8 * (x + 1)] = str2_first_13dcc_tmp
# memcpy
然后去看sub_123B8
,又是开始头疼的超长位运算了。
先写个开头吧,下面的for
映射先不写,看看结果对不对。
def sub_123B8(str1_padding_112F4, str2_first_13dcc):
print("sub_123B8")
print(f"sub_123B8 => {str1_padding_112F4.hex() = }")
print(f"sub_123B8 => {str2_first_13dcc.hex() = }")
def simplify():
from BitwiseExpressionSimplifier import toNOperation
base = toNOperation("(y^(x>>4))&0xf0f0f0f", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<4)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(y>>16)^x&0xffff", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<16)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(y^(x>>2))&0x33333333", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<2)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x^(y>>8))&0xff00ff", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<8)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
y = toNOperation("y>>0x1f|y<<1", 32, {'y'})
base = toNOperation("(x^y)&0xaaaaaaaa", 32, {'x'}, {'y': y})
y = toNOperation("y^base", 32, set(), {'base': base, 'y': y})
x = toNOperation("x^base", 32, {'x'}, {'base': base})
x = toNOperation("x>>0x1f|x<<1", 32, set(), {'x': x})
print(x)
print(y)
simplify()
x, y = str2_first_13dcc[0:4], str2_first_13dcc[4:8]
x, y = [(y[i] & 0xF0) | ((x[i] & 0xF0) >> 4) for i in range(4)], [((y[i] & 0x0F) << 4) | (x[i] & 0x0F) for i in range(4)]
x, y = [x[0], x[1], y[0], y[1]], [x[2], x[3], y[2], y[3]]
x, y = [(y[i] & 0xCC) | ((x[i] & 0xCC) >> 2) for i in range(4)], [((y[i] & 0x33) << 2) | (x[i] & 0x33) for i in range(4)]
x, y = [x[0], y[0], x[2], y[2]], [x[1], y[1], x[3], y[3]]
x, y = int(bytearray(x).hex(), 16), int(bytearray(y).hex(), 16)
x, y = ((x & 0x55555555) << 1) | (0xffffffff & ((y & 0x55555555) << 2) | ((y & 0x55555555) >> 30)),\
((x & 0xAAAAAAAA) << 0) | (0xffffffff & ((y & 0xAAAAAAAA) << 1) | ((y & 0xAAAAAAAA) >> 31))
print(hex(x), hex(y))
在存储的时候下断看一下寄存器值:
const sub_123B8_1275e_ptr = libzzgf.add(0x1275e+1)
Interceptor.attach(sub_123B8_1275e_ptr, {
onEnter: function (args) {
console.log("sub_123B8_1275e")
// @ts-ignore
console.log(`sub_123B8_1275e r0 = ${this.context.r0.toString()}`)
},
onLeave: function (retval) {
}
})
const sub_123B8_1276e_ptr = libzzgf.add(0x1276e+1)
Interceptor.attach(sub_123B8_1276e_ptr, {
onEnter: function (args) {
console.log("sub_123B8_1276e")
// @ts-ignore
console.log(`sub_123B8_1276e r0 = ${this.context.r0.toString()}`)
},
onLeave: function (retval) {
}
})
在1275e
是在存y
,在1276e
是在存x
,两个值和正向脚本的结果一致。
接着把剩余正向逻辑也边写边测试写通就行。
测试的时候可以在各个地方插桩,然后输出需要的寄存器或者sp
偏移的值,寄存器的上面写过实例了,下面再给个sp
的。(不过需要的是,这样读取出来的字节流顺序是反的)
Interceptor.attach(libzzgf.add(0x131c4+1), {
onEnter: function (args) {
console.log("sub_123B8_131c4")
// @ts-ignore
console.log(`sub_123B8_131c4 sp+0x110/x = ${buf2hex(this.context.sp.add(0x110).readByteArray(4)!)}`)
console.log(`sub_123B8_131c4 sp+0x10c/y = ${buf2hex(this.context.sp.add(0x10c).readByteArray(4)!)}`)
},onLeave: function (retval) {
}
})
最后得到这个123B8
函数的正向逻辑如下:
def sub_123B8(str1_padding_112F4, str2_first_13dcc):
print("sub_123B8")
print(f"sub_123B8 => {str1_padding_112F4.hex() = }")
print(f"sub_123B8 => {str2_first_13dcc.hex() = }")
def simplify():
from BitwiseExpressionSimplifier import toNOperation
base = toNOperation("(y^(x>>4))&0xf0f0f0f", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<4)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(y>>16)^x&0xffff", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<16)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(y^(x>>2))&0x33333333", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<2)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x^(y>>8))&0xff00ff", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<8)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
y = toNOperation("y>>0x1f|y<<1", 32, {'y'})
base = toNOperation("(x^y)&0xaaaaaaaa", 32, {'x'}, {'y': y})
y = toNOperation("y^base", 32, set(), {'base': base, 'y': y})
x = toNOperation("x^base", 32, {'x'}, {'base': base})
x = toNOperation("x>>0x1f|x<<1", 32, set(), {'x': x})
print(x)
print(y)
# simplify()
x, y = str2_first_13dcc[0:4], str2_first_13dcc[4:8]
x, y = [(y[i] & 0xF0) | ((x[i] & 0xF0) >> 4) for i in range(4)], [((y[i] & 0x0F) << 4) | (x[i] & 0x0F) for i in range(4)]
x, y = [x[0], x[1], y[0], y[1]], [x[2], x[3], y[2], y[3]]
x, y = [(y[i] & 0xCC) | ((x[i] & 0xCC) >> 2) for i in range(4)], [((y[i] & 0x33) << 2) | (x[i] & 0x33) for i in range(4)]
x, y = [x[0], y[0], x[2], y[2]], [x[1], y[1], x[3], y[3]]
x, y = int(bytearray(x).hex(), 16), int(bytearray(y).hex(), 16)
x, y = (0xffffffff & (((x & 0x55555555) << 1) | ((x & 0x55555555) >> 31))) | (0xffffffff & (((y & 0x55555555) << 2) | ((y & 0x55555555) >> 30))), \
(0xffffffff & (((x & 0xAAAAAAAA) << 0) | ((x & 0xAAAAAAAA) >> 32))) | (0xffffffff & (((y & 0xAAAAAAAA) << 1) | ((y & 0xAAAAAAAA) >> 31)))
mask = [[
0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000,
], [
0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010,
], [
0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080,
], [
0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000,
], [
0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002,
], [
0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100,
], [
0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200,
], [
0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004,
]]
p = 0
for i in range(8):
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ y
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p += 4
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ x
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p += 4
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
for i in range(8):
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ x
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p += 4
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ y
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p += 4
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
for i in range(8):
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ y
p += 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p += 4
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ x
p += 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p += 4
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
def simplify():
from BitwiseExpressionSimplifier import toNOperation
y = toNOperation("y>>1|y<<0x1f", 32, {'y'})
base = toNOperation("(y^x)&0xaaaaaaaa", 32, {'x'}, {'y': y})
y = toNOperation("y^base", 32, set(), {'base': base, 'y': y})
x = toNOperation("(x^base)>>1|x<<0x1f", 32, {'x'}, {'base': base})
print(x)
print(y)
base = toNOperation("(y^(x>>8))&0xff00ff", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<8)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x^(y>>2))&0x33333333", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<2)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x>>16)^y&0xffff", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<16)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x^(y>>4))&0xf0f0f0f", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<4)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
# simplify()
x, y = (0xffffffff & (((x & 0x55555555) >> 1) | ((x & 0x55555555) << 31))) | (0xffffffff & (((y & 0x55555555) >> 2) | ((y & 0x55555555) << 30))),\
(0xffffffff & (((x & 0xAAAAAAAA) >> 0) | ((x & 0xAAAAAAAA) << 32))) | (0xffffffff & (((y & 0xAAAAAAAA) >> 1) | ((y & 0xAAAAAAAA) << 31)))
x, y = bytes.fromhex(("00000000" + hex(x)[2:])[-8:]), bytes.fromhex(("00000000" + hex(y)[2:])[-8:])
x, y = [y[0], x[0], y[2], x[2]], [y[1], x[1], y[3], x[3]]
x, y = [(x[i] & 0xCC) | ((y[i] & 0xCC) >> 2) for i in range(4)], [((x[i] & 0x33) << 2) | (y[i] & 0x33) for i in range(4)]
x, y = [y[0], y[1], x[0], x[1]], [y[2], y[3], x[2], x[3]]
x, y = [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)], [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)]
str2_first_13dcc[0] = y[0]
str2_first_13dcc[1] = y[1]
str2_first_13dcc[2] = y[2]
str2_first_13dcc[3] = y[3]
str2_first_13dcc[4] = x[0]
str2_first_13dcc[5] = x[1]
str2_first_13dcc[6] = x[2]
str2_first_13dcc[7] = x[3]
print(f"✔ sub_123B8 <= {str2_first_13dcc.hex() = }")
第一轮调用验证成功。
但是通过截图我们可以看见,在第二轮调用时,从sub_13440
传入的参数就有问题了,那就回去看sub_13440
。
看来看去也就这个memcpy
有问题了,之前感觉是没执行用来迷惑的,现在想想应该是想多了,还是被执行了。
那就模拟一下吧,加个str2_first_key[0:8] = str2_first_13dcc_tmp
试试。
确实成了。那也就是说,咱们对str2
的前半段正向流程写完了。
然后下面有个前半段的结果校验了,那咱照着去写逆向就行。现在整个正向脚本如下:
def sub_FF48(ipt: bytes) -> bytes:
def simplify():
from BitwiseExpressionSimplifier import toNOperation
base = toNOperation("(x^(y>>4))&0xf0f0f0f", 32, {'x', 'y'})
x = toNOperation("x^v6", 32, {'x'}, {'v6': base})
y = toNOperation("y^(v6<<4)", 32, {'y'}, {'v6': base})
print(x.bitwise)
print(y.bitwise)
x = toNOperation("x^(y^x)&0x10101010", 32, {'x', 'y'})
y = toNOperation("y^(y^x)&0x10101010", 32, {'x', 'y'})
print(x.bitwise)
print(y.bitwise)
# simplify()
x, y = ipt[0:4], ipt[4:8]
x, y = [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)], [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)]
x, y = [(x[i] & 0b11101111) | (y[i] & 0b00010000) for i in range(4)], [(y[i] & 0b11101111) | (x[i] & 0b00010000) for i in range(4)]
mask1 = [
0x00000000, 0x00000001,
0x00000100, 0x00000101,
0x00010000, 0x00010001, 0x00010100, 0x00010101,
0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010100, 0x01010101,
]
mask2 = [
0x00000000, 0x01000000,
0x00010000, 0x01010000,
0x00000100, 0x01000100,
0x00010100, 0x01010100,
0x00000001, 0x01000001,
0x00010001, 0x01010001,
0x00000101, 0x01000101,
0x00010101, 0x01010101,
]
x = int(bytearray(x).hex(), 16)
x = (mask1[(x >> 0) & 0xf] << 3) | (mask1[(x >> 8) & 0xf] << 2) | (mask1[(x >> 16) & 0xf] << 1) | (mask1[(x >> 24) & 0xf] << 0)\
| (mask1[(x >> 5) & 0xf] << 7) | (mask1[(x >> 13) & 0xf] << 6) | (mask1[(x >> 21) & 0xf] << 5) | (mask1[(x >> 29) & 0xf] << 4)
x = x & 0x0fffffff
y = int(bytearray(y).hex(), 16)
y = (mask2[(y >> 1) & 0xf] << 3) | (mask2[(y >> 9) & 0xf] << 2) | (mask2[(y >> 17) & 0xf] << 1) | (mask2[(y >> 25) & 0xf] << 0)\
| (mask2[(y >> 4) & 0xf] << 7) | (mask2[(y >> 12) & 0xf] << 6) | (mask2[(y >> 20) & 0xf] << 5) | (mask2[(y >> 28) & 0xf] << 4)
y = y & 0x0fffffff
result = []
for i in range(16):
if i in {0, 1, 8, 15}:
x = ((x << 1) | (x >> 27)) & 0x0fffffff
y = ((y << 1) | (y >> 27)) & 0x0fffffff
else:
x = ((x << 2) | (x >> 26)) & 0x0fffffff
y = ((y << 2) | (y >> 26)) & 0x0fffffff
result.append(
0
| (x << 4) & 0b100000000000000000000000000000
| (x << 28) & 0b10000000000000000000000000000
| (x << 14) & 0b1000000000000000000000000000
| (x << 4) & 0b100000000000000000000000000
| (x << 18) & 0b10000000000000000000000000
| (x << 6) & 0b1000000000000000000000000
| (x << 9) & 0b1000000000000000000000
| (x >> 1) & 0b100000000000000000000
| (x << 18) & 0b10000000000000000000
| (x << 10) & 0b1000000000000000000
| (x << 2) & 0b100000000000000000
| (x >> 10) & 0b10000000000000000
| (y >> 13) & 0b10000000000000
| (y >> 4) & 0b1000000000000
| (y << 6) & 0b100000000000
| (y >> 1) & 0b10000000000
| (y >> 14) & 0b1000000000
| (y >> 0) & 0b100000000
| (y >> 5) & 0b100000
| (y >> 10) & 0b10000
| (y >> 3) & 0b1000
| (y >> 18) & 0b100
| (y >> 26) & 0b10
| (y >> 24) & 0b1
)
result.append(
0
| (x << 15) & 0b100000000000000000000000000000
| (x << 17) & 0b10000000000000000000000000000
| (x << 10) & 0b1000000000000000000000000000
| (x << 22) & 0b100000000000000000000000000
| (x >> 2) & 0b10000000000000000000000000
| (x << 1) & 0b1000000000000000000000000
| (x << 16) & 0b1000000000000000000000
| (x << 11) & 0b100000000000000000000
| (x << 3) & 0b10000000000000000000
| (x >> 6) & 0b1000000000000000000
| (x << 15) & 0b100000000000000000
| (x >> 4) & 0b10000000000000000
| (y >> 2) & 0b10000000000000
| (y << 8) & 0b1000000000000
| (y >> 14) & 0b100000000000
| (y >> 9) & 0b10000000000
| (y >> 0) & 0b1000000000
| (y << 7) & 0b100000000
| (y >> 7) & 0b100000
| (y >> 3) & 0b10000
| (y >> 14) & 0b1000
| (y << 2) & 0b100
| (y >> 21) & 0b10
| (y >> 3) & 0b1
)
rtn = []
for i, v in enumerate(result):
rtn.extend(bytes.fromhex(("00000000" + hex(v)[2:])[-8:])[::-1])
return bytes(rtn)
def fibonacci_BFBC(index):
if index == 1 or index == 2:
return 1
v2 = fibonacci_BFBC(index - 1)
return v2 + fibonacci_BFBC(index - 2)
def sub_13DCC(str2_first_13dcc, str2_first, x_16, str1_padding, y_16, str2_first_key):
print("sub_13DCC")
print(f"sub_13DCC => {str2_first_13dcc.hex() = }")
print(f"sub_13DCC => {str2_first = }")
print(f"sub_13DCC => {x_16 = }")
print(f"sub_13DCC => {str1_padding = }")
print(f"sub_13DCC => {y_16 = }")
print(f"sub_13DCC => {str2_first_key = }")
str1_padding_112F4 = bytearray(384)
sub_112F4(str1_padding_112F4, str1_padding) # if y_16 == 16
sub_13440(str1_padding_112F4, 1, x_16, str2_first_key, str2_first, str2_first_13dcc)
print(f"✔ sub_13DCC <= {str2_first_13dcc.hex() = }")
def sub_112F4(str1_padding_112F4, str1_padding):
print("sub_112F4")
print(f"sub_112F4 => {str1_padding_112F4.hex() = }")
print(f"sub_112F4 => {str1_padding = }")
sub_115B0(str1_padding_112F4, bytearray(384), str1_padding)
print(f"✔ sub_112F4 <= {str1_padding_112F4.hex() = }")
def sub_115B0(str1_padding_112F4, a2, str1_padding):
print("sub_115B0")
print(f"sub_115B0 => {str1_padding_112F4.hex() = }")
print(f"sub_115B0 => {a2.hex() = }")
print(f"sub_115B0 => {str1_padding = }")
str1_padding_112F4[0:128] = sub_FF48(str1_padding[0:8])
a2[128:256] = sub_FF48(str1_padding[8:16])
for i in range(0, 32, 2):
a2[i*4: i*4+4] = str1_padding_112F4[(30 - i)*4:(30 - i)*4+4]
a2[(i + 1)*4:(i + 1)*4+4] = str1_padding_112F4[(31 - i)*4:(31 - i)*4+4]
str1_padding_112F4[(i + 32)*4:(i + 32)*4+4] = a2[(62 - i)*4:(62 - i)*4+4]
str1_padding_112F4[(i + 33)*4:(i + 33)*4+4] = a2[(63 - i)*4:(63 - i)*4+4]
str1_padding_112F4[(i + 64)*4:(i + 64)*4+4] = str1_padding_112F4[i*4:i*4+4]
str1_padding_112F4[(i + 65)*4:(i + 65)*4+4] = str1_padding_112F4[(i + 1)*4:(i + 1)*4+4]
a2[(i + 64)*4:(i + 64)*4+4] = a2[i*4:i*4+4]
a2[(i + 65)*4:(i + 65)*4+4] = a2[(i + 1)*4:(i + 1)*4+4]
print(f"✔ sub_115B0 <= {str1_padding_112F4.hex() = }")
print(f"✔ sub_115B0 <= {a2.hex() = }")
def sub_13440(str1_padding_112F4, x_1, x_16, str2_first_key, str2_first, str2_first_13dcc):
print("sub_13440")
print(f"sub_13440 => {str1_padding_112F4.hex() = }")
print(f"sub_13440 => {x_1 = }")
print(f"sub_13440 => {x_16 = }")
print(f"sub_13440 => {str2_first_key = }")
print(f"sub_13440 => {str2_first = }")
print(f"sub_13440 => {str2_first_13dcc.hex() = }")
for x in range(x_16//8):
for i in range(8):
str2_first_13dcc[i + 8 * x] = str2_first[i + 8 * x] ^ str2_first_key[i]
str2_first_13dcc_tmp = str2_first_13dcc[8 * x:8 * (x+1)].copy()
sub_123B8(str1_padding_112F4, str2_first_13dcc_tmp)
str2_first_13dcc[8 * x:8 * (x + 1)] = str2_first_13dcc_tmp
str2_first_key[0:8] = str2_first_13dcc_tmp
print(f"✔ sub_115B0 <= {str2_first_13dcc.hex() = }")
def sub_123B8(str1_padding_112F4, str2_first_13dcc):
print("sub_123B8")
print(f"sub_123B8 => {str1_padding_112F4.hex() = }")
print(f"sub_123B8 => {str2_first_13dcc.hex() = }")
def simplify():
from BitwiseExpressionSimplifier import toNOperation
base = toNOperation("(y^(x>>4))&0xf0f0f0f", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<4)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(y>>16)^x&0xffff", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<16)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(y^(x>>2))&0x33333333", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<2)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x^(y>>8))&0xff00ff", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<8)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
y = toNOperation("y>>0x1f|y<<1", 32, {'y'})
base = toNOperation("(x^y)&0xaaaaaaaa", 32, {'x'}, {'y': y})
y = toNOperation("y^base", 32, set(), {'base': base, 'y': y})
x = toNOperation("x^base", 32, {'x'}, {'base': base})
x = toNOperation("x>>0x1f|x<<1", 32, set(), {'x': x})
print(x)
print(y)
# simplify()
x, y = str2_first_13dcc[0:4], str2_first_13dcc[4:8]
x, y = [(y[i] & 0xF0) | ((x[i] & 0xF0) >> 4) for i in range(4)], [((y[i] & 0x0F) << 4) | (x[i] & 0x0F) for i in range(4)]
x, y = [x[0], x[1], y[0], y[1]], [x[2], x[3], y[2], y[3]]
x, y = [(y[i] & 0xCC) | ((x[i] & 0xCC) >> 2) for i in range(4)], [((y[i] & 0x33) << 2) | (x[i] & 0x33) for i in range(4)]
x, y = [x[0], y[0], x[2], y[2]], [x[1], y[1], x[3], y[3]]
x, y = int(bytearray(x).hex(), 16), int(bytearray(y).hex(), 16)
x, y = (0xffffffff & (((x & 0x55555555) << 1) | ((x & 0x55555555) >> 31))) | (0xffffffff & (((y & 0x55555555) << 2) | ((y & 0x55555555) >> 30))), \
(0xffffffff & (((x & 0xAAAAAAAA) << 0) | ((x & 0xAAAAAAAA) >> 32))) | (0xffffffff & (((y & 0xAAAAAAAA) << 1) | ((y & 0xAAAAAAAA) >> 31)))
mask = [[
0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000,
], [
0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010,
], [
0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080,
], [
0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000,
], [
0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002,
], [
0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100,
], [
0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200,
], [
0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004,
]]
p = 0
for i in range(8):
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ y
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p += 4
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ x
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p += 4
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
for i in range(8):
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ x
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p += 4
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ y
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p += 4
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
for i in range(8):
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ y
p += 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p += 4
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ x
p += 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p += 4
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
def simplify():
from BitwiseExpressionSimplifier import toNOperation
y = toNOperation("y>>1|y<<0x1f", 32, {'y'})
base = toNOperation("(y^x)&0xaaaaaaaa", 32, {'x'}, {'y': y})
y = toNOperation("y^base", 32, set(), {'base': base, 'y': y})
x = toNOperation("(x^base)>>1|x<<0x1f", 32, {'x'}, {'base': base})
print(x)
print(y)
base = toNOperation("(y^(x>>8))&0xff00ff", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<8)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x^(y>>2))&0x33333333", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<2)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x>>16)^y&0xffff", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<16)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x^(y>>4))&0xf0f0f0f", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<4)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
# simplify()
x, y = (0xffffffff & (((x & 0x55555555) >> 1) | ((x & 0x55555555) << 31))) | (0xffffffff & (((y & 0x55555555) >> 2) | ((y & 0x55555555) << 30))),\
(0xffffffff & (((x & 0xAAAAAAAA) >> 0) | ((x & 0xAAAAAAAA) << 32))) | (0xffffffff & (((y & 0xAAAAAAAA) >> 1) | ((y & 0xAAAAAAAA) << 31)))
x, y = bytes.fromhex(("00000000" + hex(x)[2:])[-8:]), bytes.fromhex(("00000000" + hex(y)[2:])[-8:])
x, y = [y[0], x[0], y[2], x[2]], [y[1], x[1], y[3], x[3]]
x, y = [(x[i] & 0xCC) | ((y[i] & 0xCC) >> 2) for i in range(4)], [((x[i] & 0x33) << 2) | (y[i] & 0x33) for i in range(4)]
x, y = [y[0], y[1], x[0], x[1]], [y[2], y[3], x[2], x[3]]
x, y = [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)], [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)]
str2_first_13dcc[0] = y[0]
str2_first_13dcc[1] = y[1]
str2_first_13dcc[2] = y[2]
str2_first_13dcc[3] = y[3]
str2_first_13dcc[4] = x[0]
str2_first_13dcc[5] = x[1]
str2_first_13dcc[6] = x[2]
str2_first_13dcc[7] = x[3]
print(f"✔ sub_123B8 <= {str2_first_13dcc.hex() = }")
def sub_14CC4(c, x_4):
...
def sub_C010(str1: bytes, str2: bytes):
str1_padding = str1[:11].replace(b' ', b'_') + b"`````"
assert (str2[0] + 121) * 99 == 22176
assert fibonacci_BFBC(str2[31] ^ 0x3e) == 1346269
str2_first = b"^" + str2[1:16]
str2_second = str2[16:31] + b"$"
str2_first_check = bytes([0x0F, 0x6E, 0xD9, 0x7A, 0xB2, 0xE3, 0x92, 0x37] + [0x6D, 0x87, 0xE1, 0x0D, 0x95, 0xA8, 0x18, 0x8C])
str2_first_key = bytearray([0x4F, 0x43, 0x0A, 0x7A, 0x6D, 0x26, 0x69, 0x3D])
str2_first_13dcc = bytearray(16)
sub_13DCC(str2_first_13dcc, str2_first, 16, str1_padding, 16, str2_first_key)
# 现在正向到这里了
assert str2_first_13dcc == str2_first_check
str2_second_check = bytes([
0x9C, 0xCD, 0x4B, 0x31, 0xF4, 0xD9, 0xA2, 0xD3, 0xDA, 0xDC, 0x63, 0xF2, 0x46, 0x2C, 0x14, 0xE4,
0xAF, 0xBD, 0xFD, 0x0C, 0x12, 0xD3, 0x43, 0x8F, 0x0F, 0xE7, 0xE5, 0xC0, 0x3F, 0x0A, 0xFE, 0x07,
0x53, 0xA0, 0x65, 0x81, 0xAA, 0x57, 0x16, 0x3C, 0xB9, 0x09, 0x8C, 0xCE, 0x48, 0xA1, 0xC6, 0xB1,
0x62, 0x73, 0xDD, 0x8C, 0x46, 0xAC, 0x1F, 0xAF, 0xDC, 0xDC, 0xF4, 0x9F, 0x18, 0x61, 0xF4, 0x3D,
0x14, 0xCE, 0x27, 0x05, 0xE2, 0xEB, 0xBF, 0xFD, 0x07, 0x36, 0x5A, 0xA8, 0x98, 0x5B, 0xED, 0x00,
0x60, 0xCC, 0xF4, 0xDE, 0xC7, 0x77, 0x6E, 0xB2, 0x3D, 0x10, 0x6C, 0x7F, 0xC5, 0xBB, 0xDA, 0xD1,
0xA7, 0x24, 0x57, 0xA5, 0xB8, 0x05, 0xF6, 0xC2, 0xC9, 0x09, 0xE7, 0xFD, 0xA7, 0x0B, 0xC5, 0x7B,
0x6D, 0xB8, 0xB3, 0x45, 0x45, 0x4E, 0x35, 0xEF, 0x5E, 0x4A, 0xC0, 0xAE, 0x01, 0xE3, 0x3D, 0x2B,
])
for i in range(0, 16, 4):
str2_second_14CC4 = sub_14CC4(str2_second[i], 4)
for j in range(8):
for k in range(4):
assert str2_second_14CC4[4 * j + k] == str2_second_check[((8 * i) & 0xFFFFFFE7) + 4 * j + (3 - k)]
if __name__ == '__main__':
print()
sub_C010(b"iscc xhzg!!", b"g000000000000000000000000000000!")
据此边写边调(向正向脚本传测试参数,然后把结果代入逆向脚本测试,每步计算都下断点康康数据和正向的那地方是不是一致,不一致那肯定是写错了),慢慢写出逆向脚本如下:
def sub_112F4(str1_padding_112F4, str1_padding):
print("sub_112F4")
print(f"sub_112F4 => {str1_padding_112F4.hex() = }")
print(f"sub_112F4 => {str1_padding = }")
sub_115B0(str1_padding_112F4, bytearray(384), str1_padding)
print(f"✔ sub_112F4 <= {str1_padding_112F4.hex() = }")
def sub_115B0(str1_padding_112F4, a2, str1_padding):
print("sub_115B0")
print(f"sub_115B0 => {str1_padding_112F4.hex() = }")
print(f"sub_115B0 => {a2.hex() = }")
print(f"sub_115B0 => {str1_padding = }")
str1_padding_112F4[0:128] = sub_FF48(str1_padding[0:8])
a2[128:256] = sub_FF48(str1_padding[8:16])
for i in range(0, 32, 2):
a2[i*4: i*4+4] = str1_padding_112F4[(30 - i)*4:(30 - i)*4+4]
a2[(i + 1)*4:(i + 1)*4+4] = str1_padding_112F4[(31 - i)*4:(31 - i)*4+4]
str1_padding_112F4[(i + 32)*4:(i + 32)*4+4] = a2[(62 - i)*4:(62 - i)*4+4]
str1_padding_112F4[(i + 33)*4:(i + 33)*4+4] = a2[(63 - i)*4:(63 - i)*4+4]
str1_padding_112F4[(i + 64)*4:(i + 64)*4+4] = str1_padding_112F4[i*4:i*4+4]
str1_padding_112F4[(i + 65)*4:(i + 65)*4+4] = str1_padding_112F4[(i + 1)*4:(i + 1)*4+4]
a2[(i + 64)*4:(i + 64)*4+4] = a2[i*4:i*4+4]
a2[(i + 65)*4:(i + 65)*4+4] = a2[(i + 1)*4:(i + 1)*4+4]
print(f"✔ sub_115B0 <= {str1_padding_112F4.hex() = }")
print(f"✔ sub_115B0 <= {a2.hex() = }")
def sub_FF48(ipt: bytes) -> bytes:
def simplify():
from BitwiseExpressionSimplifier import toNOperation
base = toNOperation("(x^(y>>4))&0xf0f0f0f", 32, {'x', 'y'})
x = toNOperation("x^v6", 32, {'x'}, {'v6': base})
y = toNOperation("y^(v6<<4)", 32, {'y'}, {'v6': base})
print(x.bitwise)
print(y.bitwise)
x = toNOperation("x^(y^x)&0x10101010", 32, {'x', 'y'})
y = toNOperation("y^(y^x)&0x10101010", 32, {'x', 'y'})
print(x.bitwise)
print(y.bitwise)
# simplify()
x, y = ipt[0:4], ipt[4:8]
x, y = [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)], [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)]
x, y = [(x[i] & 0b11101111) | (y[i] & 0b00010000) for i in range(4)], [(y[i] & 0b11101111) | (x[i] & 0b00010000) for i in range(4)]
mask1 = [
0x00000000, 0x00000001,
0x00000100, 0x00000101,
0x00010000, 0x00010001, 0x00010100, 0x00010101,
0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010100, 0x01010101,
]
mask2 = [
0x00000000, 0x01000000,
0x00010000, 0x01010000,
0x00000100, 0x01000100,
0x00010100, 0x01010100,
0x00000001, 0x01000001,
0x00010001, 0x01010001,
0x00000101, 0x01000101,
0x00010101, 0x01010101,
]
x = int(bytearray(x).hex(), 16)
x = (mask1[(x >> 0) & 0xf] << 3) | (mask1[(x >> 8) & 0xf] << 2) | (mask1[(x >> 16) & 0xf] << 1) | (mask1[(x >> 24) & 0xf] << 0)\
| (mask1[(x >> 5) & 0xf] << 7) | (mask1[(x >> 13) & 0xf] << 6) | (mask1[(x >> 21) & 0xf] << 5) | (mask1[(x >> 29) & 0xf] << 4)
x = x & 0x0fffffff
y = int(bytearray(y).hex(), 16)
y = (mask2[(y >> 1) & 0xf] << 3) | (mask2[(y >> 9) & 0xf] << 2) | (mask2[(y >> 17) & 0xf] << 1) | (mask2[(y >> 25) & 0xf] << 0)\
| (mask2[(y >> 4) & 0xf] << 7) | (mask2[(y >> 12) & 0xf] << 6) | (mask2[(y >> 20) & 0xf] << 5) | (mask2[(y >> 28) & 0xf] << 4)
y = y & 0x0fffffff
result = []
for i in range(16):
if i in {0, 1, 8, 15}:
x = ((x << 1) | (x >> 27)) & 0x0fffffff
y = ((y << 1) | (y >> 27)) & 0x0fffffff
else:
x = ((x << 2) | (x >> 26)) & 0x0fffffff
y = ((y << 2) | (y >> 26)) & 0x0fffffff
result.append(
0
| (x << 4) & 0b100000000000000000000000000000
| (x << 28) & 0b10000000000000000000000000000
| (x << 14) & 0b1000000000000000000000000000
| (x << 4) & 0b100000000000000000000000000
| (x << 18) & 0b10000000000000000000000000
| (x << 6) & 0b1000000000000000000000000
| (x << 9) & 0b1000000000000000000000
| (x >> 1) & 0b100000000000000000000
| (x << 18) & 0b10000000000000000000
| (x << 10) & 0b1000000000000000000
| (x << 2) & 0b100000000000000000
| (x >> 10) & 0b10000000000000000
| (y >> 13) & 0b10000000000000
| (y >> 4) & 0b1000000000000
| (y << 6) & 0b100000000000
| (y >> 1) & 0b10000000000
| (y >> 14) & 0b1000000000
| (y >> 0) & 0b100000000
| (y >> 5) & 0b100000
| (y >> 10) & 0b10000
| (y >> 3) & 0b1000
| (y >> 18) & 0b100
| (y >> 26) & 0b10
| (y >> 24) & 0b1
)
result.append(
0
| (x << 15) & 0b100000000000000000000000000000
| (x << 17) & 0b10000000000000000000000000000
| (x << 10) & 0b1000000000000000000000000000
| (x << 22) & 0b100000000000000000000000000
| (x >> 2) & 0b10000000000000000000000000
| (x << 1) & 0b1000000000000000000000000
| (x << 16) & 0b1000000000000000000000
| (x << 11) & 0b100000000000000000000
| (x << 3) & 0b10000000000000000000
| (x >> 6) & 0b1000000000000000000
| (x << 15) & 0b100000000000000000
| (x >> 4) & 0b10000000000000000
| (y >> 2) & 0b10000000000000
| (y << 8) & 0b1000000000000
| (y >> 14) & 0b100000000000
| (y >> 9) & 0b10000000000
| (y >> 0) & 0b1000000000
| (y << 7) & 0b100000000
| (y >> 7) & 0b100000
| (y >> 3) & 0b10000
| (y >> 14) & 0b1000
| (y << 2) & 0b100
| (y >> 21) & 0b10
| (y >> 3) & 0b1
)
rtn = []
for i, v in enumerate(result):
rtn.extend(bytes.fromhex(("00000000" + hex(v)[2:])[-8:])[::-1])
return bytes(rtn)
def sub_123B8_re(str1_padding_112F4, str2_first_13dcc):
x, y = bytearray(4), bytearray(4)
y[0] = str2_first_13dcc[0]
y[1] = str2_first_13dcc[1]
y[2] = str2_first_13dcc[2]
y[3] = str2_first_13dcc[3]
x[0] = str2_first_13dcc[4]
x[1] = str2_first_13dcc[5]
x[2] = str2_first_13dcc[6]
x[3] = str2_first_13dcc[7]
x, y = [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)], [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)]
x, y = [x[2], x[3], y[2], y[3]], [x[0], x[1], y[0], y[1]]
x, y = [(x[i] & 0xCC) | ((y[i] & 0xCC) >> 2) for i in range(4)], [((x[i] & 0x33) << 2) | (y[i] & 0x33) for i in range(4)]
x, y = [x[1], y[1], x[3], y[3]], [x[0], y[0], x[2], y[2]]
x, y = int(bytearray(x).hex(), 16), int(bytearray(y).hex(), 16)
x, y = (0xffffffff & (((x & 0xAAAAAAAA) << 1) | ((x & 0xAAAAAAAA) >> 31))) | (0xffffffff & (((y & 0xAAAAAAAA) << 0) | ((y & 0xAAAAAAAA) >> 32))), \
(0xffffffff & (((x & 0x55555555) << 2) | ((x & 0x55555555) >> 30))) | (0xffffffff & (((y & 0x55555555) << 1) | ((y & 0x55555555) >> 31)))
mask = [[
0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000,
], [
0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010,
], [
0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080,
], [
0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000,
], [
0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002,
], [
0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100,
], [
0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200,
], [
0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004,
]]
p = 0
for i in range(24):
p += 4 * 4
for i in range(8):
p -= 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ x
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
p -= 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ y
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
for i in range(8):
p -= 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ y
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
p -= 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ x
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
for i in range(8):
p -= 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ x
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
p -= 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ y
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
assert p == 0
x, y = (0xffffffff & (((x & 0xAAAAAAAA) >> 1) | ((x & 0xAAAAAAAA) << 31))) | (0xffffffff & (((y & 0xAAAAAAAA) >> 0) | ((y & 0xAAAAAAAA) << 32))), \
(0xffffffff & (((x & 0x55555555) >> 2) | ((x & 0x55555555) << 30))) | (0xffffffff & (((y & 0x55555555) >> 1) | ((y & 0x55555555) << 31)))
x, y = bytes.fromhex(("00000000" + hex(x)[2:])[-8:]), bytes.fromhex(("00000000" + hex(y)[2:])[-8:])
x, y = [x[0], y[0], x[2], y[2]], [x[1], y[1], x[3], y[3]]
x, y = [((x[i] & 0x33) << 2) | (y[i] & 0x33) for i in range(4)], [(x[i] & 0xCC) | ((y[i] & 0xCC) >> 2) for i in range(4)]
x, y = [x[0], x[1], y[0], y[1]], [x[2], x[3], y[2], y[3]]
x, y = [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)], [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)]
str2_first_13dcc[0:4] = x
str2_first_13dcc[4:8] = y
def main():
str1 = b"iscc xhzg!!"
str1_padding = str1[:11].replace(b' ', b'_') + b"`````"
str2_first = bytearray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
str2_first_13dcc = bytearray([0x0F, 0x6E, 0xD9, 0x7A, 0xB2, 0xE3, 0x92, 0x37] + [0x6D, 0x87, 0xE1, 0x0D, 0x95, 0xA8, 0x18, 0x8C])
# str2_first_13dcc = bytearray(b'Y\xfey&\xb7\xc0v\xfe\x0f\xef\x9c\xf3\xd6\x80\x1bv') # 测试用 "^000000000000000"
str2_first_key = bytearray([0x4F, 0x43, 0x0A, 0x7A, 0x6D, 0x26, 0x69, 0x3D])
str1_padding_112F4 = bytearray(384)
sub_112F4(str1_padding_112F4, str1_padding) # str1_padding_112F4 = sub_112F4(str1_padding)
for x in range(2):
str2_first_13dcc_backup = str2_first_13dcc[8 * x:8 * (x + 1)].copy()
str2_first_13dcc_tmp = str2_first_13dcc[8 * x:8 * (x + 1)].copy()
sub_123B8_re(str1_padding_112F4, str2_first_13dcc_tmp)
str2_first_13dcc[8 * x:8 * (x + 1)] = str2_first_13dcc_tmp
for i in range(8):
str2_first[i + 8 * x] = str2_first_13dcc[i + 8 * x] ^ str2_first_key[i]
str2_first_key[0:8] = str2_first_13dcc_backup
print(str2_first)
if __name__ == '__main__':
main()
成功拿到str2的前半段^0sh_Y0u_Ar3_R34
,首位替换之前就是str2='g0sh_Y0u_Ar3_R34'
。
那现在就剩下用来处理str2
后半段的sub_14CC4
这个大函数了(应该是大函数吧,还没看)。
去看了这个函数,主要就一个对sub_15C38
的调用。
大概逻辑就是:
def sub_14CC4(str2_second_i, x_4):
print("sub_14CC4")
print(f"sub_14CC4 => {str2_second_i.hex() = }")
print(f"sub_14CC4 => {x_4 = }")
v14 = bytearray(128)
v14[0:4] = str2_second_i[0:4]
v14[4] = 0x80
v14[64 - 4] = 4 >> 21
v14[64 - 3] = 4 >> 13
v14[64 - 2] = 4 >> 5
v14[64 - 1] = 4 << 3
str2_second_14CC4 = 0x6A09E667.to_bytes(4, "little") + \
0xBB67AE85.to_bytes(4, "little") + \
0x3C6EF372.to_bytes(4, "little") + \
0xA54FF53A.to_bytes(4, "little") + \
0x510E527F.to_bytes(4, "little") + \
0x9B05688C.to_bytes(4, "little") + \
0x1F83D9AB.to_bytes(4, "little") + \
0x5BE0CD19.to_bytes(4, "little")
for i in range(64 >> 6):
sub_15C38(v14[64*i:64*(i+1)], str2_second_14CC4)
print(f"❌ sub_14CC4 <= {str2_second_14CC4.hex() = }")
return str2_second_14CC4[0:32]
def sub_15C38(a1, a2):
print("sub_15C38")
print(f"sub_15C38 => {a1.hex() = }")
print(f"sub_15C38 => {a2.hex() = }")
print(f"❌ sub_15C38 <= {a2.hex() = }")
...
写个脚本打一下调用堆栈。
const sub_14CC4_ptr = libzzgf.add(0x14CC4+1)
let sub_14CC4_str2_second_i: NativePointer
let sub_14CC4_str2_second_14CC4: NativePointer
Interceptor.attach(sub_14CC4_ptr, {
onEnter: function (args) {
console.log("sub_14CC4")
console.log(`sub_14CC4 \x1b[34m=>\x1b[0m str2_second_i = ${buf2hex(args[0].readByteArray(4)!)}`)
console.log(`sub_14CC4 \x1b[34m=>\x1b[0m x_4 = ${args[1]}`)
console.log(`sub_14CC4 \x1b[34m=>\x1b[0m str2_second_14CC4 = ${args[2].toString()}`)
sub_14CC4_str2_second_i = args[0]
sub_14CC4_str2_second_14CC4 = args[2]
},
onLeave: function (retval) {
console.log(`sub_14CC4 \x1b[32m<=\x1b[0m str2_second_i = ${buf2hex(sub_14CC4_str2_second_i.readByteArray(4)!)}`)
console.log(`sub_14CC4 \x1b[32m<=\x1b[0m str2_second_14CC4 = ${buf2hex(sub_14CC4_str2_second_14CC4.readByteArray(32)!)}`)
}
})
const sub_15C38_ptr = libzzgf.add(0x15C38+1)
let sub_15C38_a1: NativePointer
let sub_15C38_a2: NativePointer
Interceptor.attach(sub_15C38_ptr, {
onEnter: function (args) {
console.log("sub_15C38")
console.log(`sub_15C38 \x1b[34m=>\x1b[0m a1 = ${buf2hex(args[0].readByteArray(64)!)}`)
console.log(`sub_15C38 \x1b[34m=>\x1b[0m a2 = ${buf2hex(args[1].readByteArray(32)!)}`)
sub_15C38_a1 = args[0]
sub_15C38_a2 = args[1]
},
onLeave: function (retval) {
console.log(`sub_15C38 \x1b[32m<=\x1b[0m a1 = ${buf2hex(sub_15C38_a1.readByteArray(64)!)}`)
console.log(`sub_15C38 \x1b[32m<=\x1b[0m a2 = ${buf2hex(sub_15C38_a2.readByteArray(32)!)}`)
}
})
发现传参都没啥问题。
那就去看sub_15C38
的逻辑。
int __fastcall sub_15C38(int a1, int *a2)
{
_DWORD *v2; // r0
int v4; // [sp+220h] [bp-8AF0h]
int i; // [sp+224h] [bp-8AECh]
int j; // [sp+224h] [bp-8AECh]
int k; // [sp+224h] [bp-8AECh]
int v8; // [sp+23Ch] [bp-8AD4h]
int v9; // [sp+240h] [bp-8AD0h]
int v10; // [sp+244h] [bp-8ACCh]
int v11; // [sp+248h] [bp-8AC8h]
int v12; // [sp+24Ch] [bp-8AC4h]
int v13; // [sp+250h] [bp-8AC0h]
int v14; // [sp+254h] [bp-8ABCh]
int v15; // [sp+258h] [bp-8AB8h]
int v16; // [sp+25Ch] [bp-8AB4h]
int v17; // [sp+260h] [bp-8AB0h]
_DWORD v18[64]; // [sp+8C04h] [bp-10Ch] BYREF
v4 = 0;
for ( i = 0; i <= 15; ++i )
{
v18[i] = bswap32(*(a1 + v4));
v4 += 4;
}
for ( j = 16; j <= 63; ++j )
{
v2 = &v18[j];
*v2 = (__ROR4__(*(v2 - 2), 17) ^ __ROR4__(*(v2 - 2), 19) ^ (*(v2 - 2) >> 10))
+ *(v2 - 7)
+ (__ROR4__(*(v2 - 15), 7) ^ __ROR4__(*(v2 - 15), 18) ^ (*(v2 - 15) >> 3))
+ *(v2 - 16);
}
v17 = *a2;
v16 = a2[1];
v15 = a2[2];
v14 = a2[3];
v13 = a2[4];
v12 = a2[5];
v11 = a2[6];
v10 = a2[7];
for ( k = 0; k <= 63; ++k )
{
v9 = v10
+ (__ROR4__(v13, 6) ^ __ROR4__(v13, 11) ^ __ROR4__(v13, 25))
+ (v12 & v13 ^ v11 & ~v13)
+ dword_287D4[k]
+ v18[k];
v8 = (__ROR4__(v17, 2) ^ __ROR4__(v17, 13) ^ __ROR4__(v17, 22)) + (v17 & v16 ^ v17 & v15 ^ v16 & v15);
v10 = v11;
v11 = v12;
v12 = v13;
v13 = v14 + v9;
v14 = v15;
v15 = v16;
v16 = v17;
v17 = v9 + v8;
}
*a2 += v17;
a2[1] += v16;
a2[2] += v15;
a2[3] += v14;
a2[4] += v13;
a2[5] += v12;
a2[6] += v11;
a2[7] += v10;
return 0;
}
虽然也是位运算,但和之前的比起来就短太多了。
不过这回参杂进来了加法运算,可能要出问题,因为有溢出情况,待会逆向可能比较麻烦。不过这个现在还不需要担心,先借着frida
边写边调把正向脚本写出来。
def sub_15C38(a1, a2):
print("sub_15C38")
print(f"sub_15C38 => {a1.hex() = }")
print(f"sub_15C38 => {a2.hex() = }")
v18 = [0 for _ in range(64)]
for i in range(16):
v18[i] = int(bytearray(a1[i*4:(i+1)*4]).hex(), 16)
for i in range(16, 64):
v18[i] = ((0xffffffff & ((v18[i-2] >> 0x11) | (v18[i-2] << 0x0f))) ^
(0xffffffff & ((v18[i-2] >> 0x13) | (v18[i-2] << 0x0d))) ^
(0xffffffff & (v18[i - 2] >> 0x0a))) + \
v18[i-7] + \
((0xffffffff & ((v18[i - 15] >> 0x07) | (v18[i - 15] << 0x19))) ^
(0xffffffff & ((v18[i - 15] >> 0x12) | (v18[i - 15] << 0x0e))) ^
(0xffffffff & (v18[i - 15] >> 0x03))) + \
v18[i-16]
v18[i] &= 0xffffffff
mask = [
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
]
v10 = [int(bytearray(a2[i * 4:(i + 1) * 4][::-1]).hex(), 16) for i in range(7, -1, -1)]
for i in range(64):
a = v10[0] + \
((0xffffffff & ((v10[3] >> 0x06) | (v10[3] << 0x1a))) ^
(0xffffffff & ((v10[3] >> 0x0b) | (v10[3] << 0x15))) ^
(0xffffffff & ((v10[3] >> 0x19) | (v10[3] << 0x07)))) + \
(0xffffffff & (v10[2] & v10[3] ^ v10[1] & ~v10[3])) + \
mask[i] + \
v18[i]
a &= 0xffffffff
b = ((0xffffffff & ((v10[7] >> 0x02) | (v10[7] << 0x1e))) ^
(0xffffffff & ((v10[7] >> 0x0d) | (v10[7] << 0x13))) ^
(0xffffffff & ((v10[7] >> 0x16) | (v10[7] << 0x0a)))) + \
(0xffffffff & (v10[7] & v10[6] ^ v10[7] & v10[5] ^ v10[6] & v10[5]))
b &= 0xffffffff
v10[0:8] = v10[1:8] + [b]
v10[3] = 0xffffffff & (v10[3] + a)
v10[7] = 0xffffffff & (v10[7] + a)
for i in range(8):
a2[i * 4:(i + 1) * 4] = (0xffffffff & (v10[7-i] + int(bytearray(a2[i * 4:(i + 1) * 4][::-1]).hex(), 16))).to_bytes(4, "little")
print(f"✔ sub_15C38 <= {a2.hex() = }")
改了半天逻辑终于验证成功。
那么现在就需要开始逆向了,有一说一这个加法确实头疼。
算了还是写个脚本去爆破吧,挂服务器上挂一天应该就差不多了。
def sub_C010(str1: bytes, str2: bytes):
str1_padding = str1[:11].replace(b' ', b'_') + b"`````"
assert (str2[0] + 121) * 99 == 22176
assert fibonacci_BFBC(str2[31] ^ 0x3e) == 1346269
str2_first = b"^" + str2[1:16]
str2_second = str2[16:31] + b"$"
str2_first_check = bytes([0x0F, 0x6E, 0xD9, 0x7A, 0xB2, 0xE3, 0x92, 0x37] + [0x6D, 0x87, 0xE1, 0x0D, 0x95, 0xA8, 0x18, 0x8C])
str2_first_key = bytearray([0x4F, 0x43, 0x0A, 0x7A, 0x6D, 0x26, 0x69, 0x3D])
str2_first_13dcc = bytearray(16)
sub_13DCC(str2_first_13dcc, str2_first, 16, str1_padding, 16, str2_first_key)
# 现在正向到这里了
assert str2_first_13dcc == str2_first_check
str2_second_check = bytes([
0x9C, 0xCD, 0x4B, 0x31, 0xF4, 0xD9, 0xA2, 0xD3, 0xDA, 0xDC, 0x63, 0xF2, 0x46, 0x2C, 0x14, 0xE4,
0xAF, 0xBD, 0xFD, 0x0C, 0x12, 0xD3, 0x43, 0x8F, 0x0F, 0xE7, 0xE5, 0xC0, 0x3F, 0x0A, 0xFE, 0x07,
0x53, 0xA0, 0x65, 0x81, 0xAA, 0x57, 0x16, 0x3C, 0xB9, 0x09, 0x8C, 0xCE, 0x48, 0xA1, 0xC6, 0xB1,
0x62, 0x73, 0xDD, 0x8C, 0x46, 0xAC, 0x1F, 0xAF, 0xDC, 0xDC, 0xF4, 0x9F, 0x18, 0x61, 0xF4, 0x3D,
0x14, 0xCE, 0x27, 0x05, 0xE2, 0xEB, 0xBF, 0xFD, 0x07, 0x36, 0x5A, 0xA8, 0x98, 0x5B, 0xED, 0x00,
0x60, 0xCC, 0xF4, 0xDE, 0xC7, 0x77, 0x6E, 0xB2, 0x3D, 0x10, 0x6C, 0x7F, 0xC5, 0xBB, 0xDA, 0xD1,
0xA7, 0x24, 0x57, 0xA5, 0xB8, 0x05, 0xF6, 0xC2, 0xC9, 0x09, 0xE7, 0xFD, 0xA7, 0x0B, 0xC5, 0x7B,
0x6D, 0xB8, 0xB3, 0x45, 0x45, 0x4E, 0x35, 0xEF, 0x5E, 0x4A, 0xC0, 0xAE, 0x01, 0xE3, 0x3D, 0x2B,
])
FLAG = ""
for i in range(0, 16, 4):
nextX = False
for x1 in range(0x20, 0x80):
print(i, x1)
if nextX:
break
for x2 in range(0x20, 0x80):
print(i, x1, x2)
if nextX:
break
for x3 in range(0x20, 0x80):
print(i, x1, x2, x3)
if nextX:
break
for x4 in range(0x20, 0x80):
str2_second_14CC4 = sub_14CC4(bytes([x1, x2, x3, x4]), 4)
flag = True
for j in range(8):
if not flag:
break
for k in range(4):
if str2_second_14CC4[4 * j + k] != str2_second_check[((8 * i) & 0xFFFFFFE7) + 4 * j + (3 - k)]:
flag = False
break
if flag:
print(bytes([x1, x2, x3, x4]))
FLAG += bytes([x1, x2, x3, x4]).decode()
nextX = True
break
# str2_second_14CC4 = sub_14CC4(str2_second[i:i+4], 4)
# for j in range(8):
# for k in range(4):
# assert str2_second_14CC4[4 * j + k] == str2_second_check[((8 * i) & 0xFFFFFFE7) + 4 * j + (3 - k)]
if not nextX:
print(FLAG)
print("ERR")
return
print(FLAG)
if __name__ == '__main__':
print()
sub_C010(b"iscc xhzg!!", b"g0sh_Y0u_Ar3_R34000000000000000!")
第二天起床一看,成功拿下!
所以flag就是ISCC{g0sh_Y0u_Ar3_R34lly_4_zZgF_M4N!!}
。
结束
最后附上脚本:
正向:
def sub_FF48(ipt: bytes) -> bytes:
def simplify():
from BitwiseExpressionSimplifier import toNOperation
base = toNOperation("(x^(y>>4))&0xf0f0f0f", 32, {'x', 'y'})
x = toNOperation("x^v6", 32, {'x'}, {'v6': base})
y = toNOperation("y^(v6<<4)", 32, {'y'}, {'v6': base})
print(x.bitwise)
print(y.bitwise)
x = toNOperation("x^(y^x)&0x10101010", 32, {'x', 'y'})
y = toNOperation("y^(y^x)&0x10101010", 32, {'x', 'y'})
print(x.bitwise)
print(y.bitwise)
# simplify()
x, y = ipt[0:4], ipt[4:8]
x, y = [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)], [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)]
x, y = [(x[i] & 0b11101111) | (y[i] & 0b00010000) for i in range(4)], [(y[i] & 0b11101111) | (x[i] & 0b00010000) for i in range(4)]
mask1 = [
0x00000000, 0x00000001,
0x00000100, 0x00000101,
0x00010000, 0x00010001, 0x00010100, 0x00010101,
0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010100, 0x01010101,
]
mask2 = [
0x00000000, 0x01000000,
0x00010000, 0x01010000,
0x00000100, 0x01000100,
0x00010100, 0x01010100,
0x00000001, 0x01000001,
0x00010001, 0x01010001,
0x00000101, 0x01000101,
0x00010101, 0x01010101,
]
x = int(bytearray(x).hex(), 16)
x = (mask1[(x >> 0) & 0xf] << 3) | (mask1[(x >> 8) & 0xf] << 2) | (mask1[(x >> 16) & 0xf] << 1) | (mask1[(x >> 24) & 0xf] << 0)\
| (mask1[(x >> 5) & 0xf] << 7) | (mask1[(x >> 13) & 0xf] << 6) | (mask1[(x >> 21) & 0xf] << 5) | (mask1[(x >> 29) & 0xf] << 4)
x = x & 0x0fffffff
y = int(bytearray(y).hex(), 16)
y = (mask2[(y >> 1) & 0xf] << 3) | (mask2[(y >> 9) & 0xf] << 2) | (mask2[(y >> 17) & 0xf] << 1) | (mask2[(y >> 25) & 0xf] << 0)\
| (mask2[(y >> 4) & 0xf] << 7) | (mask2[(y >> 12) & 0xf] << 6) | (mask2[(y >> 20) & 0xf] << 5) | (mask2[(y >> 28) & 0xf] << 4)
y = y & 0x0fffffff
result = []
for i in range(16):
if i in {0, 1, 8, 15}:
x = ((x << 1) | (x >> 27)) & 0x0fffffff
y = ((y << 1) | (y >> 27)) & 0x0fffffff
else:
x = ((x << 2) | (x >> 26)) & 0x0fffffff
y = ((y << 2) | (y >> 26)) & 0x0fffffff
result.append(
0
| (x << 4) & 0b100000000000000000000000000000
| (x << 28) & 0b10000000000000000000000000000
| (x << 14) & 0b1000000000000000000000000000
| (x << 4) & 0b100000000000000000000000000
| (x << 18) & 0b10000000000000000000000000
| (x << 6) & 0b1000000000000000000000000
| (x << 9) & 0b1000000000000000000000
| (x >> 1) & 0b100000000000000000000
| (x << 18) & 0b10000000000000000000
| (x << 10) & 0b1000000000000000000
| (x << 2) & 0b100000000000000000
| (x >> 10) & 0b10000000000000000
| (y >> 13) & 0b10000000000000
| (y >> 4) & 0b1000000000000
| (y << 6) & 0b100000000000
| (y >> 1) & 0b10000000000
| (y >> 14) & 0b1000000000
| (y >> 0) & 0b100000000
| (y >> 5) & 0b100000
| (y >> 10) & 0b10000
| (y >> 3) & 0b1000
| (y >> 18) & 0b100
| (y >> 26) & 0b10
| (y >> 24) & 0b1
)
result.append(
0
| (x << 15) & 0b100000000000000000000000000000
| (x << 17) & 0b10000000000000000000000000000
| (x << 10) & 0b1000000000000000000000000000
| (x << 22) & 0b100000000000000000000000000
| (x >> 2) & 0b10000000000000000000000000
| (x << 1) & 0b1000000000000000000000000
| (x << 16) & 0b1000000000000000000000
| (x << 11) & 0b100000000000000000000
| (x << 3) & 0b10000000000000000000
| (x >> 6) & 0b1000000000000000000
| (x << 15) & 0b100000000000000000
| (x >> 4) & 0b10000000000000000
| (y >> 2) & 0b10000000000000
| (y << 8) & 0b1000000000000
| (y >> 14) & 0b100000000000
| (y >> 9) & 0b10000000000
| (y >> 0) & 0b1000000000
| (y << 7) & 0b100000000
| (y >> 7) & 0b100000
| (y >> 3) & 0b10000
| (y >> 14) & 0b1000
| (y << 2) & 0b100
| (y >> 21) & 0b10
| (y >> 3) & 0b1
)
rtn = []
for i, v in enumerate(result):
rtn.extend(bytes.fromhex(("00000000" + hex(v)[2:])[-8:])[::-1])
return bytes(rtn)
def fibonacci_BFBC(index):
if index == 1 or index == 2:
return 1
v2 = fibonacci_BFBC(index - 1)
return v2 + fibonacci_BFBC(index - 2)
def sub_13DCC(str2_first_13dcc, str2_first, x_16, str1_padding, y_16, str2_first_key):
print("sub_13DCC")
print(f"sub_13DCC => {str2_first_13dcc.hex() = }")
print(f"sub_13DCC => {str2_first = }")
print(f"sub_13DCC => {x_16 = }")
print(f"sub_13DCC => {str1_padding = }")
print(f"sub_13DCC => {y_16 = }")
print(f"sub_13DCC => {str2_first_key = }")
str1_padding_112F4 = bytearray(384)
sub_112F4(str1_padding_112F4, str1_padding) # if y_16 == 16
sub_13440(str1_padding_112F4, 1, x_16, str2_first_key, str2_first, str2_first_13dcc)
print(f"✔ sub_13DCC <= {str2_first_13dcc.hex() = }")
def sub_112F4(str1_padding_112F4, str1_padding):
print("sub_112F4")
print(f"sub_112F4 => {str1_padding_112F4.hex() = }")
print(f"sub_112F4 => {str1_padding = }")
sub_115B0(str1_padding_112F4, bytearray(384), str1_padding)
print(f"✔ sub_112F4 <= {str1_padding_112F4.hex() = }")
def sub_115B0(str1_padding_112F4, a2, str1_padding):
print("sub_115B0")
print(f"sub_115B0 => {str1_padding_112F4.hex() = }")
print(f"sub_115B0 => {a2.hex() = }")
print(f"sub_115B0 => {str1_padding = }")
str1_padding_112F4[0:128] = sub_FF48(str1_padding[0:8])
a2[128:256] = sub_FF48(str1_padding[8:16])
for i in range(0, 32, 2):
a2[i*4: i*4+4] = str1_padding_112F4[(30 - i)*4:(30 - i)*4+4]
a2[(i + 1)*4:(i + 1)*4+4] = str1_padding_112F4[(31 - i)*4:(31 - i)*4+4]
str1_padding_112F4[(i + 32)*4:(i + 32)*4+4] = a2[(62 - i)*4:(62 - i)*4+4]
str1_padding_112F4[(i + 33)*4:(i + 33)*4+4] = a2[(63 - i)*4:(63 - i)*4+4]
str1_padding_112F4[(i + 64)*4:(i + 64)*4+4] = str1_padding_112F4[i*4:i*4+4]
str1_padding_112F4[(i + 65)*4:(i + 65)*4+4] = str1_padding_112F4[(i + 1)*4:(i + 1)*4+4]
a2[(i + 64)*4:(i + 64)*4+4] = a2[i*4:i*4+4]
a2[(i + 65)*4:(i + 65)*4+4] = a2[(i + 1)*4:(i + 1)*4+4]
print(f"✔ sub_115B0 <= {str1_padding_112F4.hex() = }")
print(f"✔ sub_115B0 <= {a2.hex() = }")
def sub_13440(str1_padding_112F4, x_1, x_16, str2_first_key, str2_first, str2_first_13dcc):
print("sub_13440")
print(f"sub_13440 => {str1_padding_112F4.hex() = }")
print(f"sub_13440 => {x_1 = }")
print(f"sub_13440 => {x_16 = }")
print(f"sub_13440 => {str2_first_key = }")
print(f"sub_13440 => {str2_first = }")
print(f"sub_13440 => {str2_first_13dcc.hex() = }")
for x in range(x_16//8):
for i in range(8):
str2_first_13dcc[i + 8 * x] = str2_first[i + 8 * x] ^ str2_first_key[i]
str2_first_13dcc_tmp = str2_first_13dcc[8 * x:8 * (x+1)].copy()
sub_123B8(str1_padding_112F4, str2_first_13dcc_tmp)
str2_first_13dcc[8 * x:8 * (x + 1)] = str2_first_13dcc_tmp
str2_first_key[0:8] = str2_first_13dcc_tmp
print(f"✔ sub_115B0 <= {str2_first_13dcc.hex() = }")
def sub_123B8(str1_padding_112F4, str2_first_13dcc):
print("sub_123B8")
print(f"sub_123B8 => {str1_padding_112F4.hex() = }")
print(f"sub_123B8 => {str2_first_13dcc.hex() = }")
def simplify():
from BitwiseExpressionSimplifier import toNOperation
base = toNOperation("(y^(x>>4))&0xf0f0f0f", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<4)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(y>>16)^x&0xffff", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<16)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(y^(x>>2))&0x33333333", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<2)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x^(y>>8))&0xff00ff", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<8)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
y = toNOperation("y>>0x1f|y<<1", 32, {'y'})
base = toNOperation("(x^y)&0xaaaaaaaa", 32, {'x'}, {'y': y})
y = toNOperation("y^base", 32, set(), {'base': base, 'y': y})
x = toNOperation("x^base", 32, {'x'}, {'base': base})
x = toNOperation("x>>0x1f|x<<1", 32, set(), {'x': x})
print(x)
print(y)
# simplify()
x, y = str2_first_13dcc[0:4], str2_first_13dcc[4:8]
x, y = [(y[i] & 0xF0) | ((x[i] & 0xF0) >> 4) for i in range(4)], [((y[i] & 0x0F) << 4) | (x[i] & 0x0F) for i in range(4)]
x, y = [x[0], x[1], y[0], y[1]], [x[2], x[3], y[2], y[3]]
x, y = [(y[i] & 0xCC) | ((x[i] & 0xCC) >> 2) for i in range(4)], [((y[i] & 0x33) << 2) | (x[i] & 0x33) for i in range(4)]
x, y = [x[0], y[0], x[2], y[2]], [x[1], y[1], x[3], y[3]]
x, y = int(bytearray(x).hex(), 16), int(bytearray(y).hex(), 16)
x, y = (0xffffffff & (((x & 0x55555555) << 1) | ((x & 0x55555555) >> 31))) | (0xffffffff & (((y & 0x55555555) << 2) | ((y & 0x55555555) >> 30))), \
(0xffffffff & (((x & 0xAAAAAAAA) << 0) | ((x & 0xAAAAAAAA) >> 32))) | (0xffffffff & (((y & 0xAAAAAAAA) << 1) | ((y & 0xAAAAAAAA) >> 31)))
mask = [[
0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000,
], [
0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010,
], [
0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080,
], [
0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000,
], [
0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002,
], [
0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100,
], [
0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200,
], [
0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004,
]]
p = 0
for i in range(8):
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ y
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p += 4
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ x
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p += 4
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
for i in range(8):
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ x
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p += 4
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ y
p += 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p += 4
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
for i in range(8):
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ y
p += 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p += 4
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ x
p += 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p += 4
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
def simplify():
from BitwiseExpressionSimplifier import toNOperation
y = toNOperation("y>>1|y<<0x1f", 32, {'y'})
base = toNOperation("(y^x)&0xaaaaaaaa", 32, {'x'}, {'y': y})
y = toNOperation("y^base", 32, set(), {'base': base, 'y': y})
x = toNOperation("(x^base)>>1|x<<0x1f", 32, {'x'}, {'base': base})
print(x)
print(y)
base = toNOperation("(y^(x>>8))&0xff00ff", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<8)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x^(y>>2))&0x33333333", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<2)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x>>16)^y&0xffff", 32, {'x', 'y'})
x, y = toNOperation("y^base", 32, {'x', 'y'}, {'base': base}), toNOperation("x^(base<<16)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
base = toNOperation("(x^(y>>4))&0xf0f0f0f", 32, {'x', 'y'})
x, y = toNOperation("x^base", 32, {'x', 'y'}, {'base': base}), toNOperation("y^(base<<4)", 32, {'x', 'y'}, {'base': base})
print(x)
print(y)
# simplify()
x, y = (0xffffffff & (((x & 0x55555555) >> 1) | ((x & 0x55555555) << 31))) | (0xffffffff & (((y & 0x55555555) >> 2) | ((y & 0x55555555) << 30))),\
(0xffffffff & (((x & 0xAAAAAAAA) >> 0) | ((x & 0xAAAAAAAA) << 32))) | (0xffffffff & (((y & 0xAAAAAAAA) >> 1) | ((y & 0xAAAAAAAA) << 31)))
x, y = bytes.fromhex(("00000000" + hex(x)[2:])[-8:]), bytes.fromhex(("00000000" + hex(y)[2:])[-8:])
x, y = [y[0], x[0], y[2], x[2]], [y[1], x[1], y[3], x[3]]
x, y = [(x[i] & 0xCC) | ((y[i] & 0xCC) >> 2) for i in range(4)], [((x[i] & 0x33) << 2) | (y[i] & 0x33) for i in range(4)]
x, y = [y[0], y[1], x[0], x[1]], [y[2], y[3], x[2], x[3]]
x, y = [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)], [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)]
str2_first_13dcc[0] = y[0]
str2_first_13dcc[1] = y[1]
str2_first_13dcc[2] = y[2]
str2_first_13dcc[3] = y[3]
str2_first_13dcc[4] = x[0]
str2_first_13dcc[5] = x[1]
str2_first_13dcc[6] = x[2]
str2_first_13dcc[7] = x[3]
print(f"✔ sub_123B8 <= {str2_first_13dcc.hex() = }")
def sub_14CC4(str2_second_i, x_4):
# print("sub_14CC4")
# print(f"sub_14CC4 => {str2_second_i.hex() = }")
# print(f"sub_14CC4 => {x_4 = }")
v14 = bytearray(128)
v14[0:4] = str2_second_i[0:4]
v14[4] = 0x80
v14[64 - 4] = 4 >> 21
v14[64 - 3] = 4 >> 13
v14[64 - 2] = 4 >> 5
v14[64 - 1] = 4 << 3
str2_second_14CC4 = bytearray(
0x6A09E667.to_bytes(4, "little") +
0xBB67AE85.to_bytes(4, "little") +
0x3C6EF372.to_bytes(4, "little") +
0xA54FF53A.to_bytes(4, "little") +
0x510E527F.to_bytes(4, "little") +
0x9B05688C.to_bytes(4, "little") +
0x1F83D9AB.to_bytes(4, "little") +
0x5BE0CD19.to_bytes(4, "little")
)
for i in range(64 >> 6):
sub_15C38(v14[64*i:64*(i+1)], str2_second_14CC4)
# print(f"✔ sub_14CC4 <= {str2_second_14CC4.hex() = }")
return str2_second_14CC4[0:32]
def sub_15C38(a1, a2):
# print("sub_15C38")
# print(f"sub_15C38 => {a1.hex() = }")
# print(f"sub_15C38 => {a2.hex() = }")
v18 = [0 for _ in range(64)]
for i in range(16):
v18[i] = int(bytearray(a1[i*4:(i+1)*4]).hex(), 16)
for i in range(16, 64):
v18[i] = ((0xffffffff & ((v18[i-2] >> 0x11) | (v18[i-2] << 0x0f))) ^
(0xffffffff & ((v18[i-2] >> 0x13) | (v18[i-2] << 0x0d))) ^
(0xffffffff & (v18[i - 2] >> 0x0a))) + \
v18[i-7] + \
((0xffffffff & ((v18[i - 15] >> 0x07) | (v18[i - 15] << 0x19))) ^
(0xffffffff & ((v18[i - 15] >> 0x12) | (v18[i - 15] << 0x0e))) ^
(0xffffffff & (v18[i - 15] >> 0x03))) + \
v18[i-16]
v18[i] &= 0xffffffff
mask = [
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
]
v10 = [int(bytearray(a2[i * 4:(i + 1) * 4][::-1]).hex(), 16) for i in range(7, -1, -1)]
for i in range(64):
a = v10[0] + \
((0xffffffff & ((v10[3] >> 0x06) | (v10[3] << 0x1a))) ^
(0xffffffff & ((v10[3] >> 0x0b) | (v10[3] << 0x15))) ^
(0xffffffff & ((v10[3] >> 0x19) | (v10[3] << 0x07)))) + \
(0xffffffff & (v10[2] & v10[3] ^ v10[1] & ~v10[3])) + \
mask[i] + \
v18[i]
a &= 0xffffffff
b = ((0xffffffff & ((v10[7] >> 0x02) | (v10[7] << 0x1e))) ^
(0xffffffff & ((v10[7] >> 0x0d) | (v10[7] << 0x13))) ^
(0xffffffff & ((v10[7] >> 0x16) | (v10[7] << 0x0a)))) + \
(0xffffffff & (v10[7] & v10[6] ^ v10[7] & v10[5] ^ v10[6] & v10[5]))
b &= 0xffffffff
v10[0:8] = v10[1:8] + [b]
v10[3] = 0xffffffff & (v10[3] + a)
v10[7] = 0xffffffff & (v10[7] + a)
for i in range(8):
a2[i * 4:(i + 1) * 4] = (0xffffffff & (v10[7-i] + int(bytearray(a2[i * 4:(i + 1) * 4][::-1]).hex(), 16))).to_bytes(4, "little")
# print(f"✔ sub_15C38 <= {a2.hex() = }")
def sub_C010(str1: bytes, str2: bytes):
str1_padding = str1[:11].replace(b' ', b'_') + b"`````"
assert (str2[0] + 121) * 99 == 22176
assert fibonacci_BFBC(str2[31] ^ 0x3e) == 1346269
str2_first = b"^" + str2[1:16]
str2_second = str2[16:31] + b"$"
str2_first_check = bytes([0x0F, 0x6E, 0xD9, 0x7A, 0xB2, 0xE3, 0x92, 0x37] + [0x6D, 0x87, 0xE1, 0x0D, 0x95, 0xA8, 0x18, 0x8C])
str2_first_key = bytearray([0x4F, 0x43, 0x0A, 0x7A, 0x6D, 0x26, 0x69, 0x3D])
str2_first_13dcc = bytearray(16)
sub_13DCC(str2_first_13dcc, str2_first, 16, str1_padding, 16, str2_first_key)
# 现在正向到这里了
assert str2_first_13dcc == str2_first_check
str2_second_check = bytes([
0x9C, 0xCD, 0x4B, 0x31, 0xF4, 0xD9, 0xA2, 0xD3, 0xDA, 0xDC, 0x63, 0xF2, 0x46, 0x2C, 0x14, 0xE4,
0xAF, 0xBD, 0xFD, 0x0C, 0x12, 0xD3, 0x43, 0x8F, 0x0F, 0xE7, 0xE5, 0xC0, 0x3F, 0x0A, 0xFE, 0x07,
0x53, 0xA0, 0x65, 0x81, 0xAA, 0x57, 0x16, 0x3C, 0xB9, 0x09, 0x8C, 0xCE, 0x48, 0xA1, 0xC6, 0xB1,
0x62, 0x73, 0xDD, 0x8C, 0x46, 0xAC, 0x1F, 0xAF, 0xDC, 0xDC, 0xF4, 0x9F, 0x18, 0x61, 0xF4, 0x3D,
0x14, 0xCE, 0x27, 0x05, 0xE2, 0xEB, 0xBF, 0xFD, 0x07, 0x36, 0x5A, 0xA8, 0x98, 0x5B, 0xED, 0x00,
0x60, 0xCC, 0xF4, 0xDE, 0xC7, 0x77, 0x6E, 0xB2, 0x3D, 0x10, 0x6C, 0x7F, 0xC5, 0xBB, 0xDA, 0xD1,
0xA7, 0x24, 0x57, 0xA5, 0xB8, 0x05, 0xF6, 0xC2, 0xC9, 0x09, 0xE7, 0xFD, 0xA7, 0x0B, 0xC5, 0x7B,
0x6D, 0xB8, 0xB3, 0x45, 0x45, 0x4E, 0x35, 0xEF, 0x5E, 0x4A, 0xC0, 0xAE, 0x01, 0xE3, 0x3D, 0x2B,
])
FLAG = ""
for i in range(0, 16, 4):
nextX = False
for x1 in range(0x20, 0x80):
print(i, x1)
if nextX:
break
for x2 in range(0x20, 0x80):
print(i, x1, x2)
if nextX:
break
for x3 in range(0x20, 0x80):
print(i, x1, x2, x3)
if nextX:
break
for x4 in range(0x20, 0x80):
str2_second_14CC4 = sub_14CC4(bytes([x1, x2, x3, x4]), 4)
flag = True
for j in range(8):
if not flag:
break
for k in range(4):
if str2_second_14CC4[4 * j + k] != str2_second_check[((8 * i) & 0xFFFFFFE7) + 4 * j + (3 - k)]:
flag = False
break
if flag:
print(bytes([x1, x2, x3, x4]))
FLAG += bytes([x1, x2, x3, x4]).decode()
nextX = True
break
# str2_second_14CC4 = sub_14CC4(str2_second[i:i+4], 4)
# for j in range(8):
# for k in range(4):
# assert str2_second_14CC4[4 * j + k] == str2_second_check[((8 * i) & 0xFFFFFFE7) + 4 * j + (3 - k)]
if not nextX:
print(FLAG)
print("ERR")
return
print(FLAG)
if __name__ == '__main__':
print()
sub_C010(b"iscc xhzg!!", b"g0sh_Y0u_Ar3_R34000000000000000!")
逆向:
def sub_112F4(str1_padding_112F4, str1_padding):
print("sub_112F4")
print(f"sub_112F4 => {str1_padding_112F4.hex() = }")
print(f"sub_112F4 => {str1_padding = }")
sub_115B0(str1_padding_112F4, bytearray(384), str1_padding)
print(f"✔ sub_112F4 <= {str1_padding_112F4.hex() = }")
def sub_115B0(str1_padding_112F4, a2, str1_padding):
print("sub_115B0")
print(f"sub_115B0 => {str1_padding_112F4.hex() = }")
print(f"sub_115B0 => {a2.hex() = }")
print(f"sub_115B0 => {str1_padding = }")
str1_padding_112F4[0:128] = sub_FF48(str1_padding[0:8])
a2[128:256] = sub_FF48(str1_padding[8:16])
for i in range(0, 32, 2):
a2[i*4: i*4+4] = str1_padding_112F4[(30 - i)*4:(30 - i)*4+4]
a2[(i + 1)*4:(i + 1)*4+4] = str1_padding_112F4[(31 - i)*4:(31 - i)*4+4]
str1_padding_112F4[(i + 32)*4:(i + 32)*4+4] = a2[(62 - i)*4:(62 - i)*4+4]
str1_padding_112F4[(i + 33)*4:(i + 33)*4+4] = a2[(63 - i)*4:(63 - i)*4+4]
str1_padding_112F4[(i + 64)*4:(i + 64)*4+4] = str1_padding_112F4[i*4:i*4+4]
str1_padding_112F4[(i + 65)*4:(i + 65)*4+4] = str1_padding_112F4[(i + 1)*4:(i + 1)*4+4]
a2[(i + 64)*4:(i + 64)*4+4] = a2[i*4:i*4+4]
a2[(i + 65)*4:(i + 65)*4+4] = a2[(i + 1)*4:(i + 1)*4+4]
print(f"✔ sub_115B0 <= {str1_padding_112F4.hex() = }")
print(f"✔ sub_115B0 <= {a2.hex() = }")
def sub_FF48(ipt: bytes) -> bytes:
def simplify():
from BitwiseExpressionSimplifier import toNOperation
base = toNOperation("(x^(y>>4))&0xf0f0f0f", 32, {'x', 'y'})
x = toNOperation("x^v6", 32, {'x'}, {'v6': base})
y = toNOperation("y^(v6<<4)", 32, {'y'}, {'v6': base})
print(x.bitwise)
print(y.bitwise)
x = toNOperation("x^(y^x)&0x10101010", 32, {'x', 'y'})
y = toNOperation("y^(y^x)&0x10101010", 32, {'x', 'y'})
print(x.bitwise)
print(y.bitwise)
# simplify()
x, y = ipt[0:4], ipt[4:8]
x, y = [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)], [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)]
x, y = [(x[i] & 0b11101111) | (y[i] & 0b00010000) for i in range(4)], [(y[i] & 0b11101111) | (x[i] & 0b00010000) for i in range(4)]
mask1 = [
0x00000000, 0x00000001,
0x00000100, 0x00000101,
0x00010000, 0x00010001, 0x00010100, 0x00010101,
0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010100, 0x01010101,
]
mask2 = [
0x00000000, 0x01000000,
0x00010000, 0x01010000,
0x00000100, 0x01000100,
0x00010100, 0x01010100,
0x00000001, 0x01000001,
0x00010001, 0x01010001,
0x00000101, 0x01000101,
0x00010101, 0x01010101,
]
x = int(bytearray(x).hex(), 16)
x = (mask1[(x >> 0) & 0xf] << 3) | (mask1[(x >> 8) & 0xf] << 2) | (mask1[(x >> 16) & 0xf] << 1) | (mask1[(x >> 24) & 0xf] << 0)\
| (mask1[(x >> 5) & 0xf] << 7) | (mask1[(x >> 13) & 0xf] << 6) | (mask1[(x >> 21) & 0xf] << 5) | (mask1[(x >> 29) & 0xf] << 4)
x = x & 0x0fffffff
y = int(bytearray(y).hex(), 16)
y = (mask2[(y >> 1) & 0xf] << 3) | (mask2[(y >> 9) & 0xf] << 2) | (mask2[(y >> 17) & 0xf] << 1) | (mask2[(y >> 25) & 0xf] << 0)\
| (mask2[(y >> 4) & 0xf] << 7) | (mask2[(y >> 12) & 0xf] << 6) | (mask2[(y >> 20) & 0xf] << 5) | (mask2[(y >> 28) & 0xf] << 4)
y = y & 0x0fffffff
result = []
for i in range(16):
if i in {0, 1, 8, 15}:
x = ((x << 1) | (x >> 27)) & 0x0fffffff
y = ((y << 1) | (y >> 27)) & 0x0fffffff
else:
x = ((x << 2) | (x >> 26)) & 0x0fffffff
y = ((y << 2) | (y >> 26)) & 0x0fffffff
result.append(
0
| (x << 4) & 0b100000000000000000000000000000
| (x << 28) & 0b10000000000000000000000000000
| (x << 14) & 0b1000000000000000000000000000
| (x << 4) & 0b100000000000000000000000000
| (x << 18) & 0b10000000000000000000000000
| (x << 6) & 0b1000000000000000000000000
| (x << 9) & 0b1000000000000000000000
| (x >> 1) & 0b100000000000000000000
| (x << 18) & 0b10000000000000000000
| (x << 10) & 0b1000000000000000000
| (x << 2) & 0b100000000000000000
| (x >> 10) & 0b10000000000000000
| (y >> 13) & 0b10000000000000
| (y >> 4) & 0b1000000000000
| (y << 6) & 0b100000000000
| (y >> 1) & 0b10000000000
| (y >> 14) & 0b1000000000
| (y >> 0) & 0b100000000
| (y >> 5) & 0b100000
| (y >> 10) & 0b10000
| (y >> 3) & 0b1000
| (y >> 18) & 0b100
| (y >> 26) & 0b10
| (y >> 24) & 0b1
)
result.append(
0
| (x << 15) & 0b100000000000000000000000000000
| (x << 17) & 0b10000000000000000000000000000
| (x << 10) & 0b1000000000000000000000000000
| (x << 22) & 0b100000000000000000000000000
| (x >> 2) & 0b10000000000000000000000000
| (x << 1) & 0b1000000000000000000000000
| (x << 16) & 0b1000000000000000000000
| (x << 11) & 0b100000000000000000000
| (x << 3) & 0b10000000000000000000
| (x >> 6) & 0b1000000000000000000
| (x << 15) & 0b100000000000000000
| (x >> 4) & 0b10000000000000000
| (y >> 2) & 0b10000000000000
| (y << 8) & 0b1000000000000
| (y >> 14) & 0b100000000000
| (y >> 9) & 0b10000000000
| (y >> 0) & 0b1000000000
| (y << 7) & 0b100000000
| (y >> 7) & 0b100000
| (y >> 3) & 0b10000
| (y >> 14) & 0b1000
| (y << 2) & 0b100
| (y >> 21) & 0b10
| (y >> 3) & 0b1
)
rtn = []
for i, v in enumerate(result):
rtn.extend(bytes.fromhex(("00000000" + hex(v)[2:])[-8:])[::-1])
return bytes(rtn)
def sub_123B8_re(str1_padding_112F4, str2_first_13dcc):
x, y = bytearray(4), bytearray(4)
y[0] = str2_first_13dcc[0]
y[1] = str2_first_13dcc[1]
y[2] = str2_first_13dcc[2]
y[3] = str2_first_13dcc[3]
x[0] = str2_first_13dcc[4]
x[1] = str2_first_13dcc[5]
x[2] = str2_first_13dcc[6]
x[3] = str2_first_13dcc[7]
x, y = [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)], [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)]
x, y = [x[2], x[3], y[2], y[3]], [x[0], x[1], y[0], y[1]]
x, y = [(x[i] & 0xCC) | ((y[i] & 0xCC) >> 2) for i in range(4)], [((x[i] & 0x33) << 2) | (y[i] & 0x33) for i in range(4)]
x, y = [x[1], y[1], x[3], y[3]], [x[0], y[0], x[2], y[2]]
x, y = int(bytearray(x).hex(), 16), int(bytearray(y).hex(), 16)
x, y = (0xffffffff & (((x & 0xAAAAAAAA) << 1) | ((x & 0xAAAAAAAA) >> 31))) | (0xffffffff & (((y & 0xAAAAAAAA) << 0) | ((y & 0xAAAAAAAA) >> 32))), \
(0xffffffff & (((x & 0x55555555) << 2) | ((x & 0x55555555) >> 30))) | (0xffffffff & (((y & 0x55555555) << 1) | ((y & 0x55555555) >> 31)))
mask = [[
0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000,
], [
0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010,
], [
0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080,
], [
0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000,
], [
0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002,
], [
0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100,
], [
0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200,
], [
0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004,
]]
p = 0
for i in range(24):
p += 4 * 4
for i in range(8):
p -= 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ x
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
p -= 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ y
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
for i in range(8):
p -= 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ y
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
p -= 4
b = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p+4][::-1]).hex(), 16) ^ x
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
for i in range(8):
p -= 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (x >> 4 | x << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ x
y ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
p -= 4
b = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ (0xffffffff & (y >> 4 | y << 28))
p -= 4
a = int(bytearray(str1_padding_112F4[p:p + 4][::-1]).hex(), 16) ^ y
x ^= mask[3][(a >> 24) & 0x3f] ^ \
mask[0][(a >> 0) & 0x3f] ^ \
mask[1][(a >> 8) & 0x3f] ^ \
mask[2][(a >> 16) & 0x3f] ^ \
mask[7][(b >> 24) & 0x3f] ^ \
mask[4][(b >> 0) & 0x3f] ^ \
mask[5][(b >> 8) & 0x3f] ^ \
mask[6][(b >> 16) & 0x3f]
assert p == 0
x, y = (0xffffffff & (((x & 0xAAAAAAAA) >> 1) | ((x & 0xAAAAAAAA) << 31))) | (0xffffffff & (((y & 0xAAAAAAAA) >> 0) | ((y & 0xAAAAAAAA) << 32))), \
(0xffffffff & (((x & 0x55555555) >> 2) | ((x & 0x55555555) << 30))) | (0xffffffff & (((y & 0x55555555) >> 1) | ((y & 0x55555555) << 31)))
x, y = bytes.fromhex(("00000000" + hex(x)[2:])[-8:]), bytes.fromhex(("00000000" + hex(y)[2:])[-8:])
x, y = [x[0], y[0], x[2], y[2]], [x[1], y[1], x[3], y[3]]
x, y = [((x[i] & 0x33) << 2) | (y[i] & 0x33) for i in range(4)], [(x[i] & 0xCC) | ((y[i] & 0xCC) >> 2) for i in range(4)]
x, y = [x[0], x[1], y[0], y[1]], [x[2], x[3], y[2], y[3]]
x, y = [((x[i] & 0x0F) << 4) | (y[i] & 0x0F) for i in range(4)], [(x[i] & 0xF0) | ((y[i] & 0xF0) >> 4) for i in range(4)]
str2_first_13dcc[0:4] = x
str2_first_13dcc[4:8] = y
def main():
str1 = b"iscc xhzg!!"
str1_padding = str1[:11].replace(b' ', b'_') + b"`````"
str2_first = bytearray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
str2_first_13dcc = bytearray([0x0F, 0x6E, 0xD9, 0x7A, 0xB2, 0xE3, 0x92, 0x37] + [0x6D, 0x87, 0xE1, 0x0D, 0x95, 0xA8, 0x18, 0x8C])
# str2_first_13dcc = bytearray(b'Y\xfey&\xb7\xc0v\xfe\x0f\xef\x9c\xf3\xd6\x80\x1bv') # 测试用 "^000000000000000"
str2_first_key = bytearray([0x4F, 0x43, 0x0A, 0x7A, 0x6D, 0x26, 0x69, 0x3D])
str1_padding_112F4 = bytearray(384)
sub_112F4(str1_padding_112F4, str1_padding) # str1_padding_112F4 = sub_112F4(str1_padding)
for x in range(2):
str2_first_13dcc_backup = str2_first_13dcc[8 * x:8 * (x + 1)].copy()
str2_first_13dcc_tmp = str2_first_13dcc[8 * x:8 * (x + 1)].copy()
sub_123B8_re(str1_padding_112F4, str2_first_13dcc_tmp)
str2_first_13dcc[8 * x:8 * (x + 1)] = str2_first_13dcc_tmp
for i in range(8):
str2_first[i + 8 * x] = str2_first_13dcc[i + 8 * x] ^ str2_first_key[i]
str2_first_key[0:8] = str2_first_13dcc_backup
print(str2_first)
if __name__ == '__main__':
main()
ISCC{g0sh_Y0u_Ar3_R34lly_4_zZgF_M4N!!}
Comments NOTHING