记一次安卓的so花指令逆向

发布于 2022-07-29  438 次阅读


记一次安卓的so花指令逆向

题目来源为ISCC 2022的擂台题,最终就1解,严重怀疑是出题人开的小号,毕竟两个人的id十分接近,所以注册时间都差不多,而且这题上题的时间距离比赛结束就1天了,这题的各种套路明摆着来耗时间的,能用1天解出来的绝对是大手子。

题目附件:Mobile-zzgf_revenge-2022.05.24.apk

观察逻辑

先看一下activity入口搁哪,原来是叫com.ctf.zzgfrev.ui.login.LoginActivity

file

翻了一下视图层的逻辑,代码是一片糨糊...大概能猜测除了loginViewModel.login函数,其他的对解题都没啥用。

file

套娃到loginRepository.login去。

file

然后是dataSource.l1ll1l1ll1l1lll1ll1l11lll

file

可以看出来有俩判断,一个是java层的l1ll1l1ll1l1ll1ll1l1ll1ll函数,一个是native层的l1ll1l1ll1l11ll1ll1l11l1l函数。

file

前半部分

l1ll1l1ll1l1ll1ll1l1ll1ll主要就是个4字节key21, 84, 50, 14用来循环异或然后再用O0O0O0O00O0O0OO0O0O00O.O0O0O0O0OO000OO000O00O加密最后和:jC^.oj[n)46W>比较。

那么去看看O0O0O0O00O0O0OO0O0O00O.O0O0O0O0OO000OO000O00O,是用一个自定义字节流和一个乱序码表进行加密。

file

file

其中映射规律比较绕,懒得看了,直接尝试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);
    }
})

file

可以发现是个类似于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!!

file

后半部分

那现在去看l1ll1l1ll1l11ll1ll1l11l1l函数,在so里面没找到,所以是动态加载的。

file

通杀脚本frida_hook_libart走一波看看,发现在0xc011-1

file

但是IDA打开F5一下发现JUMPOUT了,去看下汇编,妥妥的花指令。

file

file

那就patch+删除重建大法去修呗,具体可参考:[原创]分享一个对抗JUMPOUT的小技巧-Android安全-看雪论坛

patch前:

file

patch后:

file

然后回到函数开头,删除了然后P一下重建(因为在哪P就会以哪为函数开头去自动识别,所以刚才删除之前先回到函数开头,删除后就不方便找了,只能G地址过去)。

删除:

file

重建:

file

重新F5:

file

发现出来了新的花指令点,那就继续G过去,猜测应该是0xC340那个BX R0跳转到0xC344

file

所以把R0给patch成0xC344然后再删除重建。

后续这个函数里还有几十个花指令点,大致分为两类,一类是反复横跳式花指令,也就是上面的那种BBX跳跳跳的,另一类是插入垃圾代码导致代码量暴增的,其特征是以getpid()调用为开头,如下图,实际上有用的就354~355两行,剩下的全是垃圾代码。

file

写个idapython脚本把当前位置所在代码段(正常情况是给start段去花,除非你光标在data段哈哈哈)去花吧,脚本主要思路就是根据那俩花指令的特征去匹配,然后匹配出来了在开头就直接B到真实地址去。

比如说反复横跳的又分为两种,一种是BPC+1的,一种是BPC+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的逻辑。

file

一个很经典的求斐波那契函数,那么斐波那契数1346269是第31个,所以str2[31]=31^0x3e=33='!'

那么接着回去看主函数的逻辑,将str2分为前半部分和后半部分分别处理,得到str2_first="^"+str2[1:16]str2_second=str2[16:31]+"$"

然后是对str2_firstsub_13DCC处理得到str2_first_13dcc,那就去看sub_13DCC

图 1

看了下不对啊,怎么就6个参数了,调用那边不是2个参数吗?回头看下调用的汇编:

file

确实少了几个参数没解析出来,那重新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_paddingsub_112F4处理成str1_padding_112F4,那就去看看sub_112F4

那就去看看sub_115B0

那就去看看sub_FF48

图 2

好多的位运算,开头那两段可以用我写的BitwiseExpressionSimplifier进行化简得到其本质上的运算结果。

图 8

为了方便逆向先写个正向脚本吧(写正向的时候改了好多回才测试正确)。

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);
    }
})

图 4

图 3

验证成功,所以现在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就完事。

图 5

大致逻辑就是开个2次的循环去处理str2_firststr2_first_key生成的初始数str2_first_13dcc,然后由sub_123B8带着str1_padding_112F4处理,接着那个memcpy不确定要不要执行,因为IDA的那个-1可能是0xFFFFFFFF,然后这样子的话就可以被执行,所以后面搞好了正向的验证一下吧,现在先不管。接着是处理循环步进,其实很明显可以看出来是分成前后两个8字节去处理,然后正好串到str2_first_13dcc去就行了。

图 6

所以正向脚本大概如下:

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,又是开始头疼的超长位运算了。

图 7

先写个开头吧,下面的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,两个值和正向脚本的结果一致。

图 10

接着把剩余正向逻辑也边写边测试写通就行。

测试的时候可以在各个地方插桩,然后输出需要的寄存器或者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() = }")

第一轮调用验证成功。

图 12

但是通过截图我们可以看见,在第二轮调用时,从sub_13440传入的参数就有问题了,那就回去看sub_13440

看来看去也就这个memcpy有问题了,之前感觉是没执行用来迷惑的,现在想想应该是想多了,还是被执行了。

图 13

那就模拟一下吧,加个str2_first_key[0:8] = str2_first_13dcc_tmp试试。

图 14

确实成了。那也就是说,咱们对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'

图 15

那现在就剩下用来处理str2后半段的sub_14CC4这个大函数了(应该是大函数吧,还没看)。

图 16

去看了这个函数,主要就一个对sub_15C38的调用。

图 17

大概逻辑就是:

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)!)}`)
    }
})

发现传参都没啥问题。

图 19

那就去看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() = }")

改了半天逻辑终于验证成功。

图 20

那么现在就需要开始逆向了,有一说一这个加法确实头疼。

算了还是写个脚本去爆破吧,挂服务器上挂一天应该就差不多了。

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!")

第二天起床一看,成功拿下!

图 1

所以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!!}


The End