-
-
[原创]]看雪.京东 2018CTF-第五题分析
-
2018-6-25 13:05 5359
-
一、初步分析APK
1、解压APK后发现2个文件与代码相关:classes.dex和libexecute_table.so。
2、使用JEB打开apk 如下:
AAA46ESAB.kadoaskdopaskdadpakdpaosk 用于校验输入key是否合法,lkdakjudajndn函数是native函数,位于so文件中,用于key校验,返回1表示校验成功,其它校验失败。
3、使用010查看so文件是否被更改,如下图:
可以看出section段被修改了。直接修改header,让section偏移为0, section 段个数为0 ,使IDA利用segment段进行分析。修改后IDA可以分析出来对系统函数调用了。见下图:
准备工作做完开始进调试分析。
二、初始化函数分析
android对so调用的顺序是 init函数---> jni_onload。(对于如何断在初始化函数和jni_onload 可以看这个帖子IDA调试 android so文件的10个技巧)
so文件使用字符串对象操作进行代码的混淆,因此需要分析出相关字符串函数的含义,分析字符串对象处理函数是解这题的关键。分析的方法可以看输入和输出进行猜测,基本上都可以猜出来。
1、init_proc函数(啥也没干,混淆)
_DWORD *init_proc() { int v0; // r4 _DWORD *result; // r0 unsigned int v2; // r7 int v3; // r2 int v4; // r3 const char *v5; // r1 int v6; // r2 int v7; // r3 int v8; // r2 int v9; // r3 int v10; // r2 int v11; // r3 int v12; // [sp+8h] [bp-F8h] unsigned __int8 *v13; // [sp+Ch] [bp-F4h] int v14; // [sp+10h] [bp-F0h] char v15; // [sp+14h] [bp-ECh] char v16; // [sp+18h] [bp-E8h] char v17; // [sp+1Ch] [bp-E4h] char v18; // [sp+20h] [bp-E0h] int string_ASBQ838ZquyW; // [sp+24h] [bp-DCh] int v20; // [sp+2Ch] [bp-D4h] int v21; // [sp+30h] [bp-D0h] newString1(&string_ASBQ838ZquyW, (int)"ASBQ838ZquyW"); v0 = sub_8A68(&string_ASBQ838ZquyW); result = deleteString(&string_ASBQ838ZquyW); if ( v0 ) // v0=0 { newString1(&v12, (int)"333"); newString1(&v13, (int)"%*s%d"); newString1(&v14, (int)"UYetrq736UMayFindMe233"); CreateUnknowStructFunc((int)&string_ASBQ838ZquyW, 24); sub_F0A4((int)&v20, &v13); sub_DD44(&v15, &v21); sub_191A8(&v13); v2 = *v13; if ( std::operator==<char>(&v14, &v15) ) { newString1(&v18, (int)"DABD786ABH"); if ( v2 == 1 ) { v5 = "8a7d9Vduya"; } else if ( v2 >= 1 ) { if ( v2 == 2 ) v5 = "73812huvVQ"; else v5 = "daj87YBDASYBvy"; } else { v5 = "UDHA47DBsd"; } SetStringNull((int)&v13, (int)v5, v3, v4); copyString((int)&v13, (int)&v18); deleteString(&v18); } if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&v14, &v15) ) { SetStringNull((int)&v13, (int)&unk_30735, v6, v7); newString1(&v16, (int)"DU8NABvA"); copyStringFromLocation((int)&v18, &v16, 0, 1u); copyString((int)&v13, (int)&v18); deleteString(&v18); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&v13, &unk_30735) ) SetStringNull((int)&v13, (int)&unk_30735, v8, v9); copyStringFromLocation((int)&v17, &v16, 1u, 2u); copyString((int)&v13, (int)&v17); deleteString(&v17); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&v13, &unk_30735) ) SetStringNull((int)&v13, (int)&unk_30735, v10, v11); deleteString(&v16); } GetStringBuf(&v16, (int *)&v13); deleteString(&v15); sub_DBAC(&string_ASBQ838ZquyW); deleteString(&v14); StringChange((int)&v12, (int)&v16); deleteString(&v16); deleteString(&v13); if ( std::operator==<char,std::char_traits<char>,std::allocator<char>>(&v12, "333") ) sleep_0(0); result = deleteString(&v12); } return result; }上面的有些函数可能参数个数不对,不过不影响分析。
2、初始化函数数组
LOAD:00034CD0 5D 62 00 00 DCD initfunction1+1 LOAD:00034CD4 5D 63 00 00 DCD initfunction2+1 LOAD:00034CD8 4D 65 00 00 DCD initfunction3+1 ; 啥也没做 LOAD:00034CDC BD 67 00 00 DCD sub_67BC+1 ; 创建反调试线程 LOAD:00034CE0 DD 6C 00 00 DCD sub_6CDC+1 LOAD:00034CE4 49 70 00 00 DCD sub_7048+1 LOAD:00034CE8 8D 73 00 00 DCD sub_738C+1 LOAD:00034CEC C5 76 00 00 DCD sub_76C4+1 LOAD:00034CF0 69 78 00 00 DCD sub_7868+1 LOAD:00034CF4 85 78 00 00 DCD sub_7884+1 LOAD:00034CF8 C5 78 00 00 DCD sub_78C4+1 LOAD:00034CFC D5 78 00 00 DCD sub_78D4+1 LOAD:00034D00 B1 79 00 00 DCD sub_79B0+1 LOAD:00034D04 8D 7A 00 00 DCD sub_7A8C+1init_array函数先于jni_onload 函数运行,jni_onload应该被加密了,而上面的函数应该存在对其解密。3、函数625D该函数作用:36090 = lkdakjudajndn 函数地址,用于使用动态注册jni函数。其它的都是混淆。4、函数635D该函数主要作用: dword_36094 = 0x64。其它的都是混淆。5、函数654D该函数啥也没做。6、函数67BC该函数主要用于创建反调试线程B8BC,其它的没用。_DWORD *sub_67BC() { char *v0; // r8 int *v1; // r8 unsigned int v2; // r10 int v3; // r2 int v4; // r3 const char *v5; // r1 int v6; // r2 int v7; // r3 int v8; // r2 int v9; // r3 int v10; // r2 int v11; // r3 char *v12; // r0 unsigned int v13; // r11 int v14; // r2 int v15; // r3 const char *v16; // r1 int v17; // r2 int v18; // r3 int v19; // r2 int v20; // r3 int v21; // r2 int v22; // r3 int malloc_20; // [sp+4h] [bp-1DCh] char v25; // [sp+Ch] [bp-1D4h] int string_daka97YGBB; // [sp+10h] [bp-1D0h] char v27; // [sp+14h] [bp-1CCh] int v28; // [sp+18h] [bp-1C8h] char v29; // [sp+1Ch] [bp-1C4h] int string_UYetrq736UMayFindMe233; // [sp+20h] [bp-1C0h] char v31; // [sp+24h] [bp-1BCh] char v32; // [sp+28h] [bp-1B8h] char v33; // [sp+2Ch] [bp-1B4h] int v34; // [sp+30h] [bp-1B0h] int string_A782E192B81NICAIsan38Qz; // [sp+34h] [bp-1ACh] char string_52651; // [sp+38h] [bp-1A8h] char string_33687; // [sp+3Ch] [bp-1A4h] char v38; // [sp+40h] [bp-1A0h] char v39; // [sp+48h] [bp-198h] char v40; // [sp+4Ch] [bp-194h] char v41; // [sp+FCh] [bp-E4h] int v42; // [sp+104h] [bp-DCh] int v43; // [sp+108h] [bp-D8h] malloc_20 = operator new(0x20u); sub_C8A0(malloc_20); newString1(&string_A782E192B81NICAIsan38Qz, (int)"A782E192B81NICAIsan38Qz"); CreateUnknowStructFunc((int)&v38, 24); hextoString((int)&v39, 52651); sub_DD44(&string_52651, &v40); v0 = (_BYTE *)(&loc_CD76 + 2); // V0=CD78 if ( !std::operator==<char>(&string_A782E192B81NICAIsan38Qz, &string_52651) ) v0 = (_BYTE *)(&loc_CDAA + 1); // V0=CDAB if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&string_52651, &string_A782E192B81NICAIsan38Qz) ) { CreateUnknowStructFunc((int)&v41, 24); hextoString((int)&v42, 33687); sub_DD44(&string_33687, &v43); v0 = (char *)std::operator==<char,std::char_traits<char>,std::allocator<char>>(&string_33687, "0d87a"); deleteString(&string_33687); sub_DBAC(&v41); if ( v0 ) v0 = (char *)off_35CFC + 0x4A04F; } deleteString(&string_52651); sub_DBAC(&v38); deleteString(&string_A782E192B81NICAIsan38Qz); newString1(&v25, (int)"94DASIH78bdgskl998"); if ( !v0 ) { // pthread_create (*(void (__fastcall **)(char *, _DWORD, void (*)(), _DWORD))(malloc_20 + 28))(&string_33687, 0, anti_debug, 0); v1 = &string_daka97YGBB; newString1(&string_daka97YGBB, (int)"daka97YGBB"); newString1(&string_UYetrq736UMayFindMe233, (int)"UYetrq736UMayFindMe233"); CreateUnknowStructFunc((int)&v38, 24); sub_F0A4((int)&v39, &string_daka97YGBB); sub_DD44(&v31, &v40); sub_191A8(&string_daka97YGBB); v2 = *(unsigned __int8 *)string_daka97YGBB; if ( std::operator==<char>(&string_UYetrq736UMayFindMe233, &v31) ) { newString1(&v41, (int)"DABD786ABH"); if ( v2 == 1 ) { v5 = "8a7d9Vduya"; } else if ( v2 >= 1 ) { if ( v2 == 2 ) v5 = "73812huvVQ"; else v5 = "daj87YBDASYBvy"; } else { v5 = "UDHA47DBsd"; } SetStringNull((int)&string_daka97YGBB, (int)v5, v3, v4); copyString((int)&string_daka97YGBB, (int)&v41); deleteString(&v41); } if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&string_UYetrq736UMayFindMe233, &v31) ) { SetStringNull((int)&string_daka97YGBB, (int)&unk_30735, v6, v7); newString1(&v41, (int)"DU8NABvA"); copyStringFromLocation((int)&v33, &v41, 0, 1u); copyString((int)&string_daka97YGBB, (int)&v33); deleteString(&v33); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&string_daka97YGBB, &unk_30735) ) SetStringNull((int)&string_daka97YGBB, (int)&unk_30735, v8, v9); copyStringFromLocation((int)&v32, &v41, 1u, 2u); copyString((int)&string_daka97YGBB, (int)&v32); deleteString(&v32); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&string_daka97YGBB, &unk_30735) ) SetStringNull((int)&string_daka97YGBB, (int)&unk_30735, v10, v11); deleteString(&v41); } GetStringBuf(&v27, &string_daka97YGBB); deleteString(&v31); sub_DBAC(&v38); deleteString(&string_UYetrq736UMayFindMe233); copyString((int)&v25, (int)&v27); v12 = &v27; LABEL_40: deleteString(v12); deleteString(v1); return deleteString(&v25); } if ( v0 != (char *)-1 ) { sub_5F68((int)&v33, 0, (int)sub_8100, 0); v1 = &v28; newString1(&v28, (int)"%*s%d"); newString1(&v34, (int)"UYetrq736UMayFindMe233"); CreateUnknowStructFunc((int)&v41, 24); sub_F0A4((int)&v42, &v28); sub_DD44(&string_A782E192B81NICAIsan38Qz, &v43); sub_191A8(&v28); v13 = *(unsigned __int8 *)v28; if ( std::operator==<char>(&v34, &string_A782E192B81NICAIsan38Qz) ) { newString1(&v38, (int)"DABD786ABH"); if ( v13 == 1 ) { v16 = "8a7d9Vduya"; } else if ( v13 >= 1 ) { if ( v13 == 2 ) v16 = "73812huvVQ"; else v16 = "daj87YBDASYBvy"; } else { v16 = "UDHA47DBsd"; } SetStringNull((int)&v28, (int)v16, v14, v15); copyString((int)&v28, (int)&v38); deleteString(&v38); } if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&v34, &string_A782E192B81NICAIsan38Qz) ) { SetStringNull((int)&v28, (int)&unk_30735, v17, v18); newString1(&v38, (int)"DU8NABvA"); copyStringFromLocation((int)&string_33687, &v38, 0, 1u); copyString((int)&v28, (int)&string_33687); deleteString(&string_33687); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&v28, &unk_30735) ) SetStringNull((int)&v28, (int)&unk_30735, v19, v20); copyStringFromLocation((int)&string_52651, &v38, 1u, 2u); copyString((int)&v28, (int)&string_52651); deleteString(&string_52651); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&v28, &unk_30735) ) SetStringNull((int)&v28, (int)&unk_30735, v21, v22); deleteString(&v38); } GetStringBuf(&v29, &v28); deleteString(&string_A782E192B81NICAIsan38Qz); sub_DBAC(&v41); deleteString(&v34); copyString((int)&v25, (int)&v29); v12 = &v29; goto LABEL_40; } if ( std::operator==<char,std::char_traits<char>,std::allocator<char>>(&v25, "94DASIH78bdgskl998") ) sub_5F68((int)&v41, 0, (int)sub_8100, 0); return deleteString(&v25); }后面的函数懒得分析,应该是代码解密的。先不管,看下反调线程。三、反调试线程 B8BC这个函数也加入了很多字符串垃圾指令。其主要做如下几件事:1、解密字符串“tracePid”。2、解密字符串“%*s%d”。3、解密字符串“/proc/self/status”。4、打开文件 “/proc/self/status”,一行一行读取,一直找到 “tracePid”为止。5、调用scanf获取tracePid的数值。6、如果 tracePid > 0, 则全局变量0x36098 = 0xBD9813BA,否则 0x36098 = 0x2333AE83。7 、线程sleep 5秒。0x36098 的值在对输入key进行变换时有用到,当程序处于调试状态时,会使key计算出错。过掉反调试方法很多,但是无论用啥方法必须要使0x36098 赋值为 0x2333AE83 。可以让线程进入死循环,或者让线程终止,或者让线程sleep(100000)秒,也可以直接修改逻辑让tracePid恒等于0。void anti_debug() { unsigned int v0; // r9 int v1; // r2 int v2; // r3 const char *v3; // r1 int v4; // r2 int v5; // r3 int v6; // r2 int v7; // r3 int v8; // r2 int v9; // r3 signed int v10; // r10 unsigned int i; // r7 int v12; // r11 unsigned int j; // r6 signed int v14; // r9 unsigned int k; // r7 int v16; // r10 unsigned int v17; // r5 signed int v18; // r9 unsigned int l; // r9 int v20; // r11 unsigned int v21; // r5 unsigned int v22; // r8 int v23; // r2 int v24; // r3 const char *v25; // r1 int v26; // r2 int v27; // r3 int v28; // r2 int v29; // r3 int v30; // r2 int v31; // r3 int v32; // r3 char *readBuf_1; // r6 int v34; // r3 char *v35; // r7 int string_format_3; // r0 int v37; // r3 int v38; // r2 char *v39; // r10 int fd; // [sp+0h] [bp-1080h] char v41; // [sp+8h] [bp-1078h] char v42; // [sp+8h] [bp-1078h] unsigned int v43; // [sp+18h] [bp-1068h] int *v44; // [sp+18h] [bp-1068h] int new_20; // [sp+1Ch] [bp-1064h] char v46; // [sp+30h] [bp-1050h] unsigned __int8 read_1ByteBuf; // [sp+58h] [bp-1028h] int string_W302sWW6O6WWb0b6W; // [sp+5Ch] [bp-1024h] char string_AG60As3wWPCAsA6A; // [sp+60h] [bp-1020h] int string_NULL_U8; // [sp+64h] [bp-101Ch] _BYTE *string_NULL; // [sp+68h] [bp-1018h] int string_racePid; // [sp+6Ch] [bp-1014h] int string_AG60As3wWPCAsA6A_1; // [sp+70h] [bp-1010h] int sring_P5U6UP2UsCP20CUW2; // [sp+74h] [bp-100Ch] int string_proc_self_status; // [sp+78h] [bp-1008h] int buf_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2; // [sp+7Ch] [bp-1004h] int string_format_2; // [sp+80h] [bp-1000h] int string_format_1; // [sp+84h] [bp-FFCh] int string_NULL_3; // [sp+88h] [bp-FF8h] char v60; // [sp+8Ch] [bp-FF4h] int string_UYetrq736UMayFindMe233; // [sp+90h] [bp-FF0h] char string_W302sWW6O6WWb0b6W_2; // [sp+94h] [bp-FECh] char v63; // [sp+98h] [bp-FE8h] char string_D; // [sp+9Ch] [bp-FE4h] int string_BQ366EYdQs_1; // [sp+A0h] [bp-FE0h] char string_22_1; // [sp+A4h] [bp-FDCh] int string_A782E192B81NICAIsan38Qz; // [sp+A8h] [bp-FD8h] char string_1321; // [sp+ACh] [bp-FD4h] char string_BQ366EYdQs; // [sp+B0h] [bp-FD0h] char string_AG60As3wWPCAsA6A_2; // [sp+B4h] [bp-FCCh] int string_NULL_2; // [sp+B8h] [bp-FC8h] int string_BQ366EYdQs_2; // [sp+BCh] [bp-FC4h] char string_22_3; // [sp+C0h] [bp-FC0h] int string_A782E192B81NICAIsan38Qz_1; // [sp+C4h] [bp-FBCh] char string_1321_1; // [sp+C8h] [bp-FB8h] char v76; // [sp+CCh] [bp-FB4h] char string_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2; // [sp+D0h] [bp-FB0h] int string_NULL_1; // [sp+D4h] [bp-FACh] int string_BQ366EYdQs_3; // [sp+D8h] [bp-FA8h] char string_22_4; // [sp+DCh] [bp-FA4h] char v81; // [sp+E0h] [bp-FA0h] char v82; // [sp+E4h] [bp-F9Ch] char v83; // [sp+E8h] [bp-F98h] char string_PW0PwWZ60Z_1; // [sp+ECh] [bp-F94h] int string_format; // [sp+F0h] [bp-F90h] int string_UYetrq736UMayFindMe233_2; // [sp+F4h] [bp-F8Ch] char string_UYetrq736UMayFindMe233_1_1; // [sp+F8h] [bp-F88h] char string_U8; // [sp+FCh] [bp-F84h] char v89; // [sp+100h] [bp-F80h] int string_A782E192B81NICAIsan38Qz_2; // [sp+104h] [bp-F7Ch] char string_100; // [sp+108h] [bp-F78h] int string_A782E192B81NICAIsan38Qz_3; // [sp+10Ch] [bp-F74h] char buf_3928; // [sp+110h] [bp-F70h] char v94; // [sp+114h] [bp-F6Ch] int v95; // [sp+11Ch] [bp-F64h] int v96; // [sp+120h] [bp-F60h] char v97; // [sp+1D0h] [bp-EB0h] char string_22; // [sp+1D8h] [bp-EA8h] int v99; // [sp+1DCh] [bp-EA4h] char v100; // [sp+28Ch] [bp-DF4h] int v101; // [sp+294h] [bp-DECh] char v102; // [sp+298h] [bp-DE8h] char v103; // [sp+348h] [bp-D38h] int string_22_2; // [sp+350h] [bp-D30h] char v105; // [sp+354h] [bp-D2Ch] char v106; // [sp+404h] [bp-C7Ch] int v107; // [sp+40Ch] [bp-C74h] int v108; // [sp+410h] [bp-C70h] char string_readBuf; // [sp+4C0h] [bp-BC0h] char v110; // [sp+4C8h] [bp-BB8h] int v111; // [sp+4CCh] [bp-BB4h] char tracePid; // [sp+57Ch] [bp-B04h] int v113; // [sp+584h] [bp-AFCh] char v114; // [sp+588h] [bp-AF8h] char string_33687; // [sp+638h] [bp-A48h] int v116; // [sp+640h] [bp-A40h] int v117; // [sp+644h] [bp-A3Ch] int string_DU8NABvA_1; // [sp+6F4h] [bp-98Ch] int v119; // [sp+6FCh] [bp-984h] int v120; // [sp+700h] [bp-980h] char string_DU8NABvA; // [sp+7B0h] [bp-8D0h] char string_UYetrq736UMayFindMe233_1; // [sp+7B8h] [bp-8C8h] int v123; // [sp+7BCh] [bp-8C4h] char readBuf; // [sp+86Ch] [bp-814h] char v125; // [sp+96Bh] [bp-715h] char v126; // [sp+C54h] [bp-42Ch] char v127[1003]; // [sp+C55h] [bp-42Bh] int v128; // [sp+1054h] [bp-2Ch] v128 = *(_DWORD *)off_35CEC; new_20 = operator new(0x20u); sub_C8A0(new_20); newString1(&string_W302sWW6O6WWb0b6W, (int)"W302sWW6O6WWb0b6W"); GetStringBuf(&string_NULL_U8, &string_W302sWW6O6WWb0b6W); newString1(&string_UYetrq736UMayFindMe233, (int)"UYetrq736UMayFindMe233"); CreateUnknowStructFunc((int)&v94, 24); sub_F0A4((int)&v95, &string_NULL_U8); sub_DD44(&string_W302sWW6O6WWb0b6W_2, &v96); sub_191A8(&string_NULL_U8); v0 = *(unsigned __int8 *)string_NULL_U8; if ( std::operator==<char>(&string_UYetrq736UMayFindMe233, &string_W302sWW6O6WWb0b6W_2) ) { newString1(&string_DU8NABvA, (int)"DABD786ABH"); if ( v0 == 1 ) { v3 = "8a7d9Vduya"; } else if ( v0 >= 1 ) { if ( v0 == 2 ) v3 = "73812huvVQ"; else v3 = "daj87YBDASYBvy"; } else { v3 = "UDHA47DBsd"; } SetStringNull((int)&string_NULL_U8, (int)v3, v1, v2); copyString((int)&string_NULL_U8, (int)&string_DU8NABvA); deleteString(&string_DU8NABvA); } if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>( &string_UYetrq736UMayFindMe233, &string_W302sWW6O6WWb0b6W_2) ) { SetStringNull((int)&string_NULL_U8, (int)&unk_30735, v4, v5); newString1(&string_DU8NABvA, (int)"DU8NABvA"); copyStringFromLocation((int)&string_D, &string_DU8NABvA, 0, 1u); copyString((int)&string_NULL_U8, (int)&string_D); deleteString(&string_D); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&string_NULL_U8, &unk_30735) ) SetStringNull((int)&string_NULL_U8, (int)&unk_30735, v6, v7); copyStringFromLocation((int)&v63, &string_DU8NABvA, 1u, 2u); copyString((int)&string_NULL_U8, (int)&v63); deleteString(&v63); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&string_NULL_U8, &unk_30735) ) SetStringNull((int)&string_NULL_U8, (int)&unk_30735, v8, v9); deleteString(&string_DU8NABvA); } GetStringBuf(&string_NULL, &string_NULL_U8); deleteString(&string_W302sWW6O6WWb0b6W_2); sub_DBAC(&v94); deleteString(&string_UYetrq736UMayFindMe233); sub_B870((int *)&string_AG60As3wWPCAsA6A, (int)"AG60As3wWPCAsA6A", &string_NULL); deleteString(&string_NULL); deleteString(&string_NULL_U8); GetStringBuf(&string_AG60As3wWPCAsA6A_1, (int *)&string_AG60As3wWPCAsA6A); newString1(&string_racePid, (int)&unk_30735); GetStringBuf(&string_AG60As3wWPCAsA6A_2, &string_AG60As3wWPCAsA6A_1); newString1(&string_NULL_2, (int)&unk_30735); newString1(&string_BQ366EYdQs_1, (int)"BQ366EYdQs3716UCANDOIT666"); CreateUnknowStructFunc((int)&v97, 24); hextoString((int)&string_22, 22); sub_DD44(&string_22_1, &v99); copyStringFromLocation((int)&string_BQ366EYdQs, &string_BQ366EYdQs_1, 0, 0xAu); StringChange((int)&string_BQ366EYdQs_1, (int)&string_BQ366EYdQs); deleteString(&string_BQ366EYdQs); if ( std::operator==<char>(&string_BQ366EYdQs_1, &string_22_1) ) v10 = 50; else v10 = 1; // =1 deleteString(&string_22_1); sub_DBAC(&v97); deleteString(&string_BQ366EYdQs_1); if ( !(*(_DWORD *)(*(_DWORD *)&string_AG60As3wWPCAsA6A_2 - 12) % (unsigned int)(v10 + 1)) ) { for ( i = 0; i < *(_DWORD *)(*(_DWORD *)&string_AG60As3wWPCAsA6A_2 - 12) / (unsigned int)(v10 + 1); ++i ) { v41 = *((_BYTE *)off_35D00 + *(unsigned __int8 *)(*(_DWORD *)&string_AG60As3wWPCAsA6A_2 + *(_DWORD *)(*(_DWORD *)&string_AG60As3wWPCAsA6A_2 - 12) - 1 - i) + 119) | 16 * *((_BYTE *)off_35D00 + *(unsigned __int8 *)(*(_DWORD *)&string_AG60As3wWPCAsA6A_2 + i) + 0x77); newString1(&string_A782E192B81NICAIsan38Qz, (int)"A782E192B81NICAIsan38Qz"); CreateUnknowStructFunc((int)&v100, 24); hextoString((int)&v101, 1321); sub_DD44(&string_1321, &v102); LOBYTE(v12) = 0xF6u; if ( !std::operator==<char>(&string_A782E192B81NICAIsan38Qz, &string_1321) ) LOBYTE(v12) = 41; if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>( &string_1321, &string_A782E192B81NICAIsan38Qz) ) { CreateUnknowStructFunc((int)&string_DU8NABvA, 24); hextoString((int)&string_UYetrq736UMayFindMe233_1, 33687); sub_DD44(&string_DU8NABvA_1, &v123); v12 = std::operator==<char,std::char_traits<char>,std::allocator<char>>(&string_DU8NABvA_1, "0d87a");// v12=0 deleteString(&string_DU8NABvA_1); sub_DBAC(&string_DU8NABvA); if ( v12 ) LOBYTE(v12) = (_BYTE)off_35CFC + 79; } deleteString(&string_1321); sub_DBAC(&v100); deleteString(&string_A782E192B81NICAIsan38Qz); CreateStringByChar(&string_NULL_2, v41 + v12);// 空字符串 } } StringChange((int)&string_AG60As3wWPCAsA6A_1, (int)&string_NULL_2); deleteString(&string_NULL_2); deleteString(&string_AG60As3wWPCAsA6A_2); for ( j = 0; j < *(_DWORD *)(string_AG60As3wWPCAsA6A_1 - 12); ++j ) CreateStringByChar( &string_racePid, *((_BYTE *)off_35CF0 + (*(unsigned __int8 *)(string_AG60As3wWPCAsA6A_1 + j) ^ 0x22) + 31)); deleteString(&string_AG60As3wWPCAsA6A_1); newString1(&sring_P5U6UP2UsCP20CUW2, (int)"P5U6UP2UsCP20CUW2"); stringStrCat(&buf_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2, &string_W302sWW6O6WWb0b6W, (int)&sring_P5U6UP2UsCP20CUW2); newString1(&string_proc_self_status, (int)&unk_30735); GetStringBuf(&string_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2, &buf_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2); newString1(&string_NULL_1, (int)&unk_30735); newString1(&string_BQ366EYdQs_2, (int)"BQ366EYdQs3716UCANDOIT666"); CreateUnknowStructFunc((int)&v103, 24); hextoString((int)&string_22_2, 22); sub_DD44(&string_22_3, &v105); copyStringFromLocation((int)&v76, &string_BQ366EYdQs_2, 0, 0xAu); StringChange((int)&string_BQ366EYdQs_2, (int)&v76); deleteString(&v76); if ( std::operator==<char>(&string_BQ366EYdQs_2, &string_22_3) ) v14 = 50; else v14 = 1; deleteString(&string_22_3); sub_DBAC(&v103); deleteString(&string_BQ366EYdQs_2); if ( !(*(_DWORD *)(*(_DWORD *)&string_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2 - 12) % (unsigned int)(v14 + 1)) ) { for ( k = 0; k < *(_DWORD *)(*(_DWORD *)&string_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2 - 12) / (unsigned int)(v14 + 1); ++k ) { v42 = *((_BYTE *)off_35D00 + *(unsigned __int8 *)(*(_DWORD *)&string_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2 + *(_DWORD *)(*(_DWORD *)&string_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2 - 12) - 1 - k) + 119) | 16 * *((_BYTE *)off_35D00 + *(unsigned __int8 *)(*(_DWORD *)&string_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2 + k) + 119); newString1(&string_A782E192B81NICAIsan38Qz_1, (int)"A782E192B81NICAIsan38Qz"); CreateUnknowStructFunc((int)&v106, 24); hextoString((int)&v107, 1321); sub_DD44(&string_1321_1, &v108); LOBYTE(v16) = -10; if ( !std::operator==<char>(&string_A782E192B81NICAIsan38Qz_1, &string_1321_1) ) LOBYTE(v16) = 41; if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>( &string_1321_1, &string_A782E192B81NICAIsan38Qz_1) ) { CreateUnknowStructFunc((int)&string_DU8NABvA, 24); hextoString((int)&string_UYetrq736UMayFindMe233_1, 33687); sub_DD44(&string_DU8NABvA_1, &v123); v16 = std::operator==<char,std::char_traits<char>,std::allocator<char>>(&string_DU8NABvA_1, "0d87a"); deleteString(&string_DU8NABvA_1); sub_DBAC(&string_DU8NABvA); if ( v16 ) LOBYTE(v16) = (_BYTE)off_35CFC + 79; } deleteString(&string_1321_1); sub_DBAC(&v106); deleteString(&string_A782E192B81NICAIsan38Qz_1); CreateStringByChar(&string_NULL_1, v42 + v16); } } StringChange((int)&buf_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2, (int)&string_NULL_1); v17 = 0; deleteString(&string_NULL_1); deleteString(&string_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2); while ( v17 < *(_DWORD *)(buf_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2 - 12) ) CreateStringByChar( &string_proc_self_status, *((_BYTE *)off_35CF4 + (*(unsigned __int8 *)(buf_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2 + v17++) ^ 0x11) + 31)); deleteString(&buf_W302sWW6O6WWb0b6WP5U6UP2UsCP20CUW2); newString1(&string_format_1, (int)"PW0PwWZ60Z"); newString1(&string_format_2, (int)&unk_30735); GetStringBuf(&string_PW0PwWZ60Z_1, &string_format_1); newString1(&string_format, (int)&unk_30735); newString1(&string_BQ366EYdQs_3, (int)"BQ366EYdQs3716UCANDOIT666"); CreateUnknowStructFunc((int)&string_readBuf, 24); hextoString((int)&v110, 22); sub_DD44(&string_22_4, &v111); copyStringFromLocation((int)&v83, &string_BQ366EYdQs_3, 0, 0xAu); StringChange((int)&string_BQ366EYdQs_3, (int)&v83); deleteString(&v83); if ( std::operator==<char>(&string_BQ366EYdQs_3, &string_22_4) ) v18 = 50; else v18 = 1; deleteString(&string_22_4); sub_DBAC(&string_readBuf); deleteString(&string_BQ366EYdQs_3); v43 = v18 + 1; // v43=2 if ( !(*(_DWORD *)(*(_DWORD *)&string_PW0PwWZ60Z_1 - 12) % (unsigned int)(v18 + 1)) ) { for ( l = 0; l < *(_DWORD *)(*(_DWORD *)&string_PW0PwWZ60Z_1 - 12) / v43; ++l ) { v46 = *((_BYTE *)off_35D00 + *(unsigned __int8 *)(*(_DWORD *)&string_PW0PwWZ60Z_1 + *(_DWORD *)(*(_DWORD *)&string_PW0PwWZ60Z_1 - 12) - 1 - l) + 119) | 16 * *((_BYTE *)off_35D00 + *(unsigned __int8 *)(*(_DWORD *)&string_PW0PwWZ60Z_1 + l) + 119); newString1(&v81, (int)"A782E192B81NICAIsan38Qz"); CreateUnknowStructFunc((int)&tracePid, 24); hextoString((int)&v113, 1321); sub_DD44(&v82, &v114); LOBYTE(v20) = -10; if ( !std::operator==<char>(&v81, &v82) ) LOBYTE(v20) = 41; if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&v82, &v81) ) { CreateUnknowStructFunc((int)&string_DU8NABvA, 24); hextoString((int)&string_UYetrq736UMayFindMe233_1, 33687); sub_DD44(&string_DU8NABvA_1, &v123); v20 = std::operator==<char,std::char_traits<char>,std::allocator<char>>(&string_DU8NABvA_1, "0d87a"); deleteString(&string_DU8NABvA_1); sub_DBAC(&string_DU8NABvA); if ( v20 ) LOBYTE(v20) = (_BYTE)off_35CFC + 79; } deleteString(&v82); sub_DBAC(&tracePid); deleteString(&v81); CreateStringByChar(&string_format, v46 + v20);// %*s%d } } StringChange((int)&string_format_1, (int)&string_format); v21 = 0; deleteString(&string_format); deleteString(&string_PW0PwWZ60Z_1); while ( v21 < *(_DWORD *)(string_format_1 - 12) ) CreateStringByChar( &string_format_2, *((_BYTE *)off_35CF0 + (*(unsigned __int8 *)(string_format_1 + v21++) ^ 0x22) + 31)); deleteString(&string_format_1); memset_0((int)&v126, 0, 1024); *g_0xDA78DE8A = 0xDA78DE8A; // 0xDA78DE8A GetStringBuf(&string_NULL_3, &string_proc_self_status); newString1(&string_UYetrq736UMayFindMe233_2, (int)"UYetrq736UMayFindMe233"); CreateUnknowStructFunc((int)&string_DU8NABvA, 24); sub_F0A4((int)&string_UYetrq736UMayFindMe233_1, &string_NULL_3); sub_DD44(&string_UYetrq736UMayFindMe233_1_1, &v123); sub_191A8(&string_NULL_3); v22 = *(unsigned __int8 *)string_NULL_3; if ( std::operator==<char>(&string_UYetrq736UMayFindMe233_2, &string_UYetrq736UMayFindMe233_1_1) ) { newString1(&string_DU8NABvA_1, (int)"DABD786ABH"); if ( v22 == 1 ) { v25 = "8a7d9Vduya"; } else if ( v22 >= 1 ) { if ( v22 == 2 ) v25 = "73812huvVQ"; else v25 = "daj87YBDASYBvy"; } else { v25 = "UDHA47DBsd"; } SetStringNull((int)&string_NULL_3, (int)v25, v23, v24); copyString((int)&string_NULL_3, (int)&string_DU8NABvA_1); deleteString(&string_DU8NABvA_1); } if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>( &string_UYetrq736UMayFindMe233_2, &string_UYetrq736UMayFindMe233_1_1) ) { SetStringNull((int)&string_NULL_3, (int)&unk_30735, v26, v27);// 走这里 newString1(&string_DU8NABvA_1, (int)"DU8NABvA"); copyStringFromLocation((int)&v89, &string_DU8NABvA_1, 0, 1u); copyString((int)&string_NULL_3, (int)&v89); deleteString(&v89); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&string_NULL_3, &unk_30735) ) SetStringNull((int)&string_NULL_3, (int)&unk_30735, v28, v29); copyStringFromLocation((int)&string_U8, &string_DU8NABvA_1, 1u, 2u); copyString((int)&string_NULL_3, (int)&string_U8); deleteString(&string_U8); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&string_NULL_3, &unk_30735) ) SetStringNull((int)&string_NULL_3, (int)&unk_30735, v30, v31); deleteString(&string_DU8NABvA_1); } GetStringBuf(&v60, &string_NULL_3); deleteString(&string_UYetrq736UMayFindMe233_1_1); sub_DBAC(&string_DU8NABvA); deleteString(&string_UYetrq736UMayFindMe233_2); copyString((int)&string_racePid, (int)&v60); deleteString(&v60); deleteString(&string_NULL_3); while ( 1 ) { fd = (*(int (__fastcall **)(int, _DWORD))(new_20 + 20))(string_proc_self_status, 0);// fopen if ( fd ) { memset_0((int)&readBuf, 0, 1000); while ( 1 ) // 读一行 { *(_WORD *)&read_1ByteBuf = 0; readBuf_1 = &readBuf; do { if ( !(*(int (__fastcall **)(int, unsigned __int8 *, signed int))(new_20 + 12))(fd, &read_1ByteBuf, 1) )// read break; v32 = read_1ByteBuf; *readBuf_1++ = read_1ByteBuf; if ( v32 == 0xA ) break; } while ( readBuf_1 != &v125 ); v34 = read_1ByteBuf; *readBuf_1 = 0; if ( !v34 && readBuf_1 == &readBuf || !&readBuf ) goto LABEL_83; newString1(&string_readBuf, (int)&readBuf); if ( stringCmp((int)&string_readBuf, &string_racePid, 0) != -1 ) break; deleteString(&string_readBuf); } newString1(&string_A782E192B81NICAIsan38Qz_2, (int)"A782E192B81NICAIsan38Qz"); CreateUnknowStructFunc((int)&string_33687, 24); hextoString((int)&v116, 100); sub_DD44(&string_100, &v117); if ( std::operator==<char>(&string_A782E192B81NICAIsan38Qz_2, &string_100) ) v35 = (_BYTE *)(&word_30 + 1); else v35 = (char *)&dword_64; if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>( &string_100, &string_A782E192B81NICAIsan38Qz_2) ) { CreateUnknowStructFunc((int)&string_DU8NABvA, 24); hextoString((int)&string_UYetrq736UMayFindMe233_1, 33687); sub_DD44(&string_DU8NABvA_1, &v123); v35 = (char *)std::operator==<char,std::char_traits<char>,std::allocator<char>>(&string_DU8NABvA_1, "0d87a"); deleteString(&string_DU8NABvA_1); sub_DBAC(&string_DU8NABvA); if ( v35 ) v35 = (char *)off_35CFC + 303183; } deleteString(&string_100); sub_DBAC(&string_33687); deleteString(&string_A782E192B81NICAIsan38Qz_2); string_format_3 = string_format_2; *(_DWORD *)&tracePid = v35; v37 = 0; v38 = *(_DWORD *)(string_format_2 - 12); while ( v37 < v38 ) { *(&v126 + v37) = *(_BYTE *)(string_format_3 + v37); ++v37; } v127[v38 & ~(v38 >> 31)] = 0; (*(void (__fastcall **)(_DWORD))(new_20 + 4))(*(_DWORD *)&string_readBuf);// sscanf if ( *(_DWORD *)&tracePid <= 0 ) { v44 = g_0xDA78DE8A; newString1(&string_A782E192B81NICAIsan38Qz_3, (int)"A782E192B81NICAIsan38Qz"); CreateUnknowStructFunc((int)&string_DU8NABvA_1, 24); hextoString((int)&v119, 3928); sub_DD44(&buf_3928, &v120); v39 = (_BYTE *)(&stru_F18 + 13); if ( !std::operator==<char>(&string_A782E192B81NICAIsan38Qz_3, &buf_3928) ) v39 = (_BYTE *)&stru_F58; if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>( &buf_3928, &string_A782E192B81NICAIsan38Qz_3) ) { CreateUnknowStructFunc((int)&string_DU8NABvA, 24); hextoString((int)&string_UYetrq736UMayFindMe233_1, 33687); sub_DD44(&string_33687, &v123); v39 = (char *)std::operator==<char,std::char_traits<char>,std::allocator<char>>(&string_33687, "0d87a"); deleteString(&string_33687); sub_DBAC(&string_DU8NABvA); if ( v39 ) v39 = (char *)off_35CFC + 303183; } deleteString(&buf_3928); sub_DBAC(&string_DU8NABvA_1); deleteString(&string_A782E192B81NICAIsan38Qz_3); *v44 = (int)(v39 + 0x2333AE83); } else { *g_0xDA78DE8A = 0xBD9813BA; ((void (__fastcall *)(_DWORD))loc_7B68)(0); } deleteString(&string_readBuf); LABEL_83: (*(void (__fastcall **)(int))(new_20 + 16))(fd); } (*(void (__fastcall **)(signed int))(new_20 + 24))(5); } }四、jni_onload函数此函数不能直接下断点,否则可能会使代码解密失败,可以直接在libdvm中下断点。这个函数主要作用是动态注册native lkdakjudajndn函数 从这里可知 lkdakjudajndn函数地址为:AC98。这个函数是真正的key校验过程。五、函数 lkdakjudajndn AC98该函数比较大,主要做了如下事情:1、将输入key的jstring对象转换成 cstring对象 。2、key长度必须大于等于10,小于等于20。3、将输入key置换到最后一位,变成key_change1。4、索引 索引 0x7FC2 ,key_change2[i] = 0x7FC2[ key_change1[i]],得到 key_change2。5、将 key_change2按照字节进行低4位与高四位的置换生成 key_change3。6、将 key_change3以4字节形式与 0x36098内容进行异或,当处于调试状态是其值为 0xBD9813BA,否则为 0x2333AE83。得到 key_change4,从这里可知key长度为0x10。7、将 key_change4相邻2字节交换,得到 key_change5 ,即 key_change5[2i] = key_change4[2i+1] key_change5[2i + 1] = key_change4[2i]。8、 再次 索引7FC2 ,key_change6[i] = 7FC2[ key_change5 [i]], 得到 key_change6。9、将 key_change6的第一字符置换到最后位置,得到 key_change7。10、将 key_change7的所有字符的高4位对字符串“A3Cw6Gb0OZWPU52s ”进行索引,组成 key_change8_highString, 将 key_change7所有字符的低4位对字符串“A3Cw6Gb0OZWPU52s”进行索引,并进行倒序。组成 key_change8_lowString, 然后将 key_change8_highString与 key_change8_lowString进行拼接生成 key_change8。11、生成字符串“3ww3U53wOAWG333wwPZ56GGw0PO02OUW”。12、将 key_change8 与 “3ww3U53wOAWG333wwPZ56GGw0PO02OUW”比较,相等返回1,否则返回其他。该函数也被加密了,下面是解密后的:char *__fastcall lkdakjudajndn(struct _JNIEnv *a1) { char *inputKey; // r0 char *v2; // r4 unsigned int i; // r4 int v4; // r2 int v5; // r3 char v6; // r6 unsigned int j; // r4 int v8; // r2 int v9; // r3 char *v10; // r6 int v11; // r8 int v12; // r2 int v13; // r3 signed int v14; // r10 unsigned int v15; // r7 char v16; // r8 unsigned int keylen; // r2 int v18; // r2 int v19; // r3 int v20; // r2 int v21; // r3 unsigned int v22; // r7 unsigned int v23; // r8 int string_A3Cw6Gb0OZWPU52s_1; // ST10_4 int v25; // ST10_4 int lowkeyChar; // ST10_4 unsigned int string_3d8ahnb1_1; // r6 int v28; // r2 int v29; // r3 const char *v30; // r1 int v31; // r2 int v32; // r3 int v33; // r2 int v34; // r3 int v35; // r2 int v36; // r3 int *v37; // r0 int inputKeyString; // [sp+20h] [bp-6B8h] int newInputKeyBuf; // [sp+24h] [bp-6B4h] int inputKeyBuf; // [sp+28h] [bp-6B0h] int buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW; // [sp+2Ch] [bp-6ACh] _BYTE *string_3d8ahnb1_is_U8; // [sp+30h] [bp-6A8h] char buf_U8; // [sp+34h] [bp-6A4h] char string_3; // [sp+38h] [bp-6A0h] char buf_3w; // [sp+3Ch] [bp-69Ch] char buf_3ww; // [sp+40h] [bp-698h] char string_aA782e192b81nic; // [sp+44h] [bp-694h] char v49; // [sp+48h] [bp-690h] int string_A3Cw6Gb0OZWPU52s; // [sp+4Ch] [bp-68Ch] int string_0; // [sp+50h] [bp-688h] int string_0_1; // [sp+54h] [bp-684h] int v53; // [sp+58h] [bp-680h] char v54; // [sp+5Ch] [bp-67Ch] int newstring_BQ366EYdQs_1; // [sp+60h] [bp-678h] char buf_44678; // [sp+64h] [bp-674h] int string_A782E192B81NICAIsan38Qz; // [sp+68h] [bp-670h] char string_3373080; // [sp+6Ch] [bp-66Ch] int newstring_BQ366EYdQs; // [sp+70h] [bp-668h] char buf_29285; // [sp+74h] [bp-664h] char *v61; // [sp+78h] [bp-660h] char v62; // [sp+7Ch] [bp-65Ch] char string_BQ366EYdQs_1; // [sp+80h] [bp-658h] char string_BQ366EYdQs; // [sp+84h] [bp-654h] char newintputKey_buf; // [sp+88h] [bp-650h] char v66; // [sp+8Ch] [bp-64Ch] char v67; // [sp+90h] [bp-648h] int v68; // [sp+94h] [bp-644h] char v69; // [sp+98h] [bp-640h] char v70; // [sp+9Ch] [bp-63Ch] char input_KeyBuffer_location0; // [sp+A0h] [bp-638h] int inputKeyBuf_location1; // [sp+A4h] [bp-634h] char inputKeyBuf_last1; // [sp+A8h] [bp-630h] int string_UYetrq736UMayFindMe233; // [sp+ACh] [bp-62Ch] char buf_3d8ahnb1; // [sp+B0h] [bp-628h] char string_U8; // [sp+B4h] [bp-624h] char string_D; // [sp+B8h] [bp-620h] int buf_BQ366EYdQs3716UCANDOIT666; // [sp+BCh] [bp-61Ch] char string_0_2; // [sp+C0h] [bp-618h] char buf_BQ366EYdQs; // [sp+C4h] [bp-614h] int v81; // [sp+C8h] [bp-610h] char v82; // [sp+CCh] [bp-60Ch] char unknowStruct1; // [sp+D0h] [bp-608h] char string_1; // [sp+D8h] [bp-600h] int v85; // [sp+DCh] [bp-5FCh] char v86; // [sp+18Ch] [bp-54Ch] int v87; // [sp+194h] [bp-544h] char v88; // [sp+198h] [bp-540h] char v89; // [sp+248h] [bp-490h] char v90; // [sp+250h] [bp-488h] int v91; // [sp+254h] [bp-484h] char v92; // [sp+304h] [bp-3D4h] char v93; // [sp+30Ch] [bp-3CCh] char v94; // [sp+310h] [bp-3C8h] char v95; // [sp+3C0h] [bp-318h] char v96; // [sp+3C8h] [bp-310h] char v97; // [sp+3CCh] [bp-30Ch] char v98; // [sp+47Ch] [bp-25Ch] char v99; // [sp+484h] [bp-254h] char v100; // [sp+488h] [bp-250h] char buf_33687; // [sp+538h] [bp-1A0h] char v102; // [sp+540h] [bp-198h] char v103; // [sp+544h] [bp-194h] char string_DU8NABvA; // [sp+5F4h] [bp-E4h] int string_33687_0; // [sp+5FCh] [bp-DCh] int v106; // [sp+600h] [bp-D8h] inputKey = (char *)(*(int (**)(void))(*(_DWORD *)a1 + 676))(); newString1(&inputKeyString, (int)inputKey); newString1(&string_aA782e192b81nic, (int)"A782E192B81NICAIsan38Qz"); CreateUnknowStructFunc((int)&unknowStruct1, 24); hextoString((int)&string_1, 1); sub_DD44(&v49, &v85); v2 = (_BYTE *)(&stru_908 + 10); if ( !std::operator==<char>(&string_aA782e192b81nic, &v49) ) v2 = (_BYTE *)(&dword_0 + 1); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&v49, &string_aA782e192b81nic) ) { CreateUnknowStructFunc((int)&string_DU8NABvA, 24); hextoString((int)&string_33687_0, 33687); sub_DD44(&buf_33687, &v106); v2 = (char *)std::operator==<char,std::char_traits<char>,std::allocator<char>>(&buf_33687, "0d87a"); deleteString(&buf_33687); sub_DBAC(&string_DU8NABvA); } if ( v2 == (_BYTE *)&dword_0 + 1 ) v2 = (char *)off_35CFC + 303183; deleteString(&v49); sub_DBAC(&unknowStruct1); deleteString(&string_aA782e192b81nic); if ( (unsigned int)(*(_DWORD *)(inputKeyString - 12) - 0xA) <= 0xA )// key长度要小于等于20 { GetStringBuf(&inputKeyBuf, &inputKeyString);// inputKeyBuf = C0ngRa7U1AtIoN2U newString1(&newInputKeyBuf, (int)&unk_30735); copyStringFromLocation((int)&inputKeyBuf_location1, &inputKeyBuf, 1u, *(_DWORD *)(inputKeyBuf - 12)); copyStringFromLocation((int)&input_KeyBuffer_location0, &inputKeyBuf, 0, 1u); stringStrCat(&inputKeyBuf_last1, &inputKeyBuf_location1, (int)&input_KeyBuffer_location0);// 将第一个字符放到最后一个位置上 StringChange((int)&inputKeyBuf, (int)&inputKeyBuf_last1);// inputKeyBuf=inputKeyBuf_last1 deleteString(&inputKeyBuf_last1); deleteString(&input_KeyBuffer_location0); deleteString(&inputKeyBuf_location1); // inputKeyBuf = 0ngRa7U1AtIoN2UC for ( i = 0; i < *(_DWORD *)(inputKeyBuf - 12); ++i )// 根据输入的key进行从字典中索引然后创建新的字符串 CreateStringByChar(&newInputKeyBuf, *((_BYTE *)off_35CF8 + *(unsigned __int8 *)(inputKeyBuf + i) + 0x21)); StringChange((int)&inputKeyBuf, (int)&newInputKeyBuf);// 此时 inputKeyBuf变成新的了 SetStringNull((int)&newInputKeyBuf, (int)&unk_30735, v4, v5);// 此时81 bb b1 70 c9 d8 64 41 ad 4f c4 bd e2 19 64 11 newString1(&newstring_BQ366EYdQs, (int)"BQ366EYdQs3716UCANDOIT666"); CreateUnknowStructFunc((int)&v95, 24); hextoString((int)&v96, 29285); sub_DD44(&buf_29285, &v97); copyStringFromLocation((int)&string_BQ366EYdQs, &newstring_BQ366EYdQs, 0, 0xAu); StringChange((int)&newstring_BQ366EYdQs, (int)&string_BQ366EYdQs);// 变成10个了 deleteString(&string_BQ366EYdQs); if ( std::operator==<char>(&newstring_BQ366EYdQs, &buf_29285) ) v6 = 50; else v6 = 1; deleteString(&buf_29285); sub_DBAC(&v95); deleteString(&newstring_BQ366EYdQs); for ( j = 0; j < *(_DWORD *)(inputKeyBuf - 12); ++j ) CreateStringByChar( // 进行低4位和高位的切换,并且创建新的string &newInputKeyBuf, ((*(_BYTE *)(inputKeyBuf + j) & 0xF) << 4 * v6) | (*(_BYTE *)(inputKeyBuf + j) >> 4)); StringChange((int)&inputKeyBuf, (int)&newInputKeyBuf);// 此时inputKey每个字节的低4位和高4位进行切换了 // 此时18 bb 1b 07 9c 8d 46 14 da f4 4c db 2e 91 46 11 SetStringNull((int)&newInputKeyBuf, (int)&unk_30735, v8, v9); newString1(&string_A782E192B81NICAIsan38Qz, (int)"A782E192B81NICAIsan38Qz"); CreateUnknowStructFunc((int)&v92, 24); hextoString((int)&v93, 3373080); sub_DD44(&string_3373080, &v94); v10 = (char *)3373029; if ( !std::operator==<char>(&string_A782E192B81NICAIsan38Qz, &string_3373080) ) v10 = (char *)3373080; if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>( &string_3373080, &string_A782E192B81NICAIsan38Qz) ) { CreateUnknowStructFunc((int)&string_DU8NABvA, 24); hextoString((int)&string_33687_0, 33687); sub_DD44(&buf_33687, &v106); v10 = (char *)std::operator==<char,std::char_traits<char>,std::allocator<char>>(&buf_33687, "0d87a"); deleteString(&buf_33687); sub_DBAC(&string_DU8NABvA); if ( v10 ) v10 = (char *)off_35CFC + 0x4A04F; } deleteString(&string_3373080); sub_DBAC(&v92); deleteString(&string_A782E192B81NICAIsan38Qz);// 对输入的key4字节与 DA78DE8A进行亦或 v11 = 0; do // 0x36090 { // // 36098 = DA78DE8A CreateStringByChar(&newInputKeyBuf, v10[inputKeyBuf + v11] ^ dword_36098); CreateStringByChar(&newInputKeyBuf, BYTE1(dword_36098) ^ *(_BYTE *)(inputKeyBuf + v11 + 1)); CreateStringByChar(&newInputKeyBuf, BYTE2(dword_36098) ^ *(_BYTE *)(inputKeyBuf + v11 + 2)); CreateStringByChar(&newInputKeyBuf, *(_BYTE *)(inputKeyBuf + v11 + 3) ^ HIBYTE(dword_36098)); v11 += 4; } while ( v11 != 0x10 ); // 证明输入的key为16个字节 StringChange((int)&inputKeyBuf, (int)&newInputKeyBuf); SetStringNull((int)&newInputKeyBuf, (int)&unk_30735, v12, v13); newString1(&newstring_BQ366EYdQs_1, (int)"BQ366EYdQs3716UCANDOIT666"); CreateUnknowStructFunc((int)&v89, 24); hextoString((int)&v90, 44678); sub_DD44(&buf_44678, &v91); copyStringFromLocation((int)&string_BQ366EYdQs_1, &newstring_BQ366EYdQs_1, 0, 0xAu); StringChange((int)&newstring_BQ366EYdQs_1, (int)&string_BQ366EYdQs_1); deleteString(&string_BQ366EYdQs_1); if ( std::operator==<char>(&newstring_BQ366EYdQs_1, &buf_44678) ) v14 = 50; else v14 = 1; deleteString(&buf_44678); sub_DBAC(&v89); v15 = 0; deleteString(&newstring_BQ366EYdQs_1); // 此时key =9b 15 28 24 1f 23 75 37 59 5a 7f f8 ad 3f 75 32 while ( 1 ) { // 对输入key进行相邻字节交换 keylen = *(_DWORD *)(inputKeyBuf - 12); if ( v15 >= keylen >> 1 ) break; v16 = *(_BYTE *)(inputKeyBuf + 2 * v15); CreateStringByChar(&newInputKeyBuf, *(_BYTE *)(inputKeyBuf + v14 + 2 * v15)); CreateStringByChar(&newInputKeyBuf, v16); ++v15; } if ( keylen & 1 ) { copyStringFromLocation((int)&v70, &inputKeyBuf, keylen - 1, 1u); copyString((int)&newInputKeyBuf, (int)&v70); deleteString(&v70); } StringChange((int)&inputKeyBuf, (int)&newInputKeyBuf);// 此时key进行了相邻字节交换 // 此时15 9b 24 28 23 1f 37 75 5a 59 f8 7f 3f ad 32 75 // SetStringNull((int)&newInputKeyBuf, (int)&unk_30735, v18, v19); while ( (unsigned int)v10 < *(_DWORD *)(inputKeyBuf - 12) )// 再次对字典7FC2开始索引 CreateStringByChar(&newInputKeyBuf, *((_BYTE *)off_35CF8 + (unsigned __int8)(v10++)[inputKeyBuf] + 33)); StringChange((int)&inputKeyBuf, (int)&newInputKeyBuf);// inputKeyBuf= 33 1a 3c 38 1e c7 d8 1b 37 83 05 a5 54 1d 19 1b SetStringNull((int)&newInputKeyBuf, (int)&unk_30735, v20, v21); newString1(&v53, (int)"BQ366EYdQs3716UCANDOIT666"); CreateUnknowStructFunc((int)&v86, 24); hextoString((int)&v87, 154634026); sub_DD44(&v54, &v88); copyStringFromLocation((int)&v62, &v53, 0, 0xAu); StringChange((int)&v53, (int)&v62); deleteString(&v62); if ( std::operator==<char>(&v53, &v54) ) v22 = 50; else v22 = 1; // v22=1 deleteString(&v54); sub_DBAC(&v86); deleteString(&v53); copyStringFromLocation((int)&v68, &inputKeyBuf, v22, *(_DWORD *)(inputKeyBuf - 12)); copyStringFromLocation((int)&v67, &inputKeyBuf, 0, v22); stringStrCat(&v69, &v68, (int)&v67); StringChange((int)&newInputKeyBuf, (int)&v69);// 此时 newintputKey_buf 第一个字节被置换到最后一个字节 // 1a 3c 38 1e c7 d8 1b 37 83 05 a5 54 1d 19 1b 33 deleteString(&v69); deleteString(&v67); deleteString(&v68); GetStringBuf(&newintputKey_buf, &newInputKeyBuf); newString1(&string_A3Cw6Gb0OZWPU52s, (int)"A3Cw6Gb0OZWPU52s"); newString1(&string_0, (int)&unk_30735); newString1(&string_0_1, (int)&unk_30735); v23 = 0; while ( v23 < *(_DWORD *)(*(_DWORD *)&newintputKey_buf - 12) )// 此时 newintputKey_buf = 13 3b 39 1d c4 d5 15 33 87 0b a8 57 1e 18 1c 3a { // string_0放A3Cw6Gb0OZWPU52s按照高4位索引的string // string_1放A3Cw6Gb0OZWPU52s按照低位索引的string string_A3Cw6Gb0OZWPU52s_1 = string_A3Cw6Gb0OZWPU52s; sub_191A8(&newintputKey_buf); CreateStringByChar( // 将输入key按字节/16 然后从A3Cw6Gb0OZWPU52s中按照索引获取 &string_0, *(_BYTE *)(string_A3Cw6Gb0OZWPU52s_1 + ((unsigned int)*(unsigned __int8 *)(*(_DWORD *)&newintputKey_buf + v23) >> 4))); v25 = string_A3Cw6Gb0OZWPU52s; sub_191A8(&newintputKey_buf); lowkeyChar = *(unsigned __int8 *)(v25 + (*(_BYTE *)(*(_DWORD *)&newintputKey_buf + v23) & 0xF));// 然后字节&0xF 再从A3Cw6Gb0OZWPU52s中索引 v61 = (char *)off_35D04 + 12; createStringByLen((int *)&v61, *(_DWORD *)(string_0_1 - 12) + 1); sub_19520((int *)&v61, 1u, lowkeyChar); sub_193C4((int *)&v61, (_BYTE **)&string_0_1); StringChange((int)&string_0_1, (int)&v61); ++v23; deleteString(&v61); } stringStrCat(&v66, &string_0, (int)&string_0_1);// 高位4位与第4位分别索引获取的子串 // 3ww3U53wOAWG333wWUO20OP0wGG65ZPw // // 这个应该是真实的 // 3ww3U53wOAWG333wwPZ56GGw0PO02OUW // 3ww3U53wOAWG333wwPZ56GGw0PO02OUW deleteString(&string_0_1); deleteString(&string_0); deleteString(&string_A3Cw6Gb0OZWPU52s); StringChange((int)&newInputKeyBuf, (int)&v66);// inputkey变成了高位索引和低位索引的string了 deleteString(&v66); deleteString(&newintputKey_buf); deleteString(&inputKeyBuf); newString1(&string_3d8ahnb1_is_U8, (int)"3d8ahnb1"); newString1(&string_UYetrq736UMayFindMe233, (int)"UYetrq736UMayFindMe233"); CreateUnknowStructFunc((int)&v98, 24); sub_F0A4((int)&v99, &string_3d8ahnb1_is_U8); sub_DD44(&buf_3d8ahnb1, &v100); sub_191A8(&string_3d8ahnb1_is_U8); string_3d8ahnb1_1 = (unsigned __int8)*string_3d8ahnb1_is_U8; if ( std::operator==<char>(&string_UYetrq736UMayFindMe233, &buf_3d8ahnb1) )// 不等 { newString1(&string_DU8NABvA, (int)"DABD786ABH"); if ( string_3d8ahnb1_1 == 1 ) { v30 = "8a7d9Vduya"; } else if ( string_3d8ahnb1_1 >= 1 ) { if ( string_3d8ahnb1_1 == 2 ) v30 = "73812huvVQ"; else v30 = "daj87YBDASYBvy"; } else { v30 = "UDHA47DBsd"; } SetStringNull((int)&string_3d8ahnb1_is_U8, (int)v30, v28, v29); copyString((int)&string_3d8ahnb1_is_U8, (int)&string_DU8NABvA); deleteString(&string_DU8NABvA); } if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>( &string_UYetrq736UMayFindMe233, &buf_3d8ahnb1) ) { SetStringNull((int)&string_3d8ahnb1_is_U8, (int)&unk_30735, v31, v32);// 进来 newString1(&string_DU8NABvA, (int)"DU8NABvA"); copyStringFromLocation((int)&string_D, &string_DU8NABvA, 0, 1u); copyString((int)&string_3d8ahnb1_is_U8, (int)&string_D); deleteString(&string_D); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&string_3d8ahnb1_is_U8, &unk_30735) ) SetStringNull((int)&string_3d8ahnb1_is_U8, (int)&unk_30735, v33, v34);// 又变成空了 copyStringFromLocation((int)&string_U8, &string_DU8NABvA, 1u, 2u); copyString((int)&string_3d8ahnb1_is_U8, (int)&string_U8);// 又变成U8了 deleteString(&string_U8); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&string_3d8ahnb1_is_U8, &unk_30735) ) SetStringNull((int)&string_3d8ahnb1_is_U8, (int)&unk_30735, v35, v36);// 又设置成空了 deleteString(&string_DU8NABvA); } GetStringBuf(&buf_U8, (int *)&string_3d8ahnb1_is_U8);// 到这里了 deleteString(&buf_3d8ahnb1); sub_DBAC(&v98); deleteString(&string_UYetrq736UMayFindMe233); std::operator+<char,std::char_traits<char>,std::allocator<char>>(&string_3, &buf_U8, '3'); std::operator+<char,std::char_traits<char>,std::allocator<char>>(&buf_3w, &string_3, 'w'); std::operator+<char,std::char_traits<char>,std::allocator<char>>(&buf_3ww, &buf_3w, 'w'); std::operator+<char,std::char_traits<char>,std::allocator<char>>( &buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, &buf_3ww, '3'); deleteString(&buf_3ww); deleteString(&buf_3w); deleteString(&string_3); deleteString(&buf_U8); deleteString(&string_3d8ahnb1_is_U8); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>( &buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, &unk_30735) ) { sub_19504(&buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, "U5"); CreateStringByChar(&buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, '3'); CreateStringByChar(&buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, 'w'); } if ( *(_DWORD *)(buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW - 12) ) { sub_19504(&buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, "OAWG"); CreateStringByChar(&buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, '3'); CreateStringByChar(&buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, '3'); CreateStringByChar(&buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, '3'); } CreateStringByChar(&buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, 119); CreateStringByChar(&buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, 119); sub_19504(&buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW, "PZ56GGw0PO02OUW"); if ( std::operator==<char>(&newInputKeyBuf, &buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW) && *(_DWORD *)(inputKeyString - 12) == 16 ) { newString1(&buf_BQ366EYdQs3716UCANDOIT666, (int)"BQ366EYdQs3716UCANDOIT666"); CreateUnknowStructFunc((int)&string_DU8NABvA, 24); hextoString((int)&string_33687_0, 0); sub_DD44(&string_0_2, &v106); copyStringFromLocation((int)&buf_BQ366EYdQs, &buf_BQ366EYdQs3716UCANDOIT666, 0, 0xAu); StringChange((int)&buf_BQ366EYdQs3716UCANDOIT666, (int)&buf_BQ366EYdQs); deleteString(&buf_BQ366EYdQs); if ( std::operator==<char>(&buf_BQ366EYdQs3716UCANDOIT666, &string_0_2) ) v2 = (char *)&word_32; else v2 = (_BYTE *)(&dword_0 + 1); deleteString(&string_0_2); sub_DBAC(&string_DU8NABvA); v37 = &buf_BQ366EYdQs3716UCANDOIT666; } else { newString1(&v81, (int)"A782E192B81NICAIsan38Qz"); CreateUnknowStructFunc((int)&buf_33687, 24); hextoString((int)&v102, 1); sub_DD44(&v82, &v103); v2 = (_BYTE *)(&stru_908 + 10); if ( !std::operator==<char>(&v81, &v82) ) v2 = (_BYTE *)(&dword_0 + 1); if ( std::operator!=<char,std::char_traits<char>,std::allocator<char>>(&v82, &v81) ) { CreateUnknowStructFunc((int)&string_DU8NABvA, 24); hextoString((int)&string_33687_0, 33687); sub_DD44(&v98, &v106); v2 = (char *)std::operator==<char,std::char_traits<char>,std::allocator<char>>(&v98, "0d87a"); deleteString(&v98); sub_DBAC(&string_DU8NABvA); } if ( v2 == (_BYTE *)&dword_0 + 1 ) v2 = (char *)off_35CFC + 303183; deleteString(&v82); sub_DBAC(&buf_33687); v37 = &v81; } deleteString(v37); deleteString(&buf_3ww3U53wOAWG333wwPZ56GGw0PO02OUW); deleteString(&newInputKeyBuf); } deleteString(&inputKeyString); return v2; }六、计算key下面是vc的代码:unsigned char g_indexKey[0x100] = { 0x40, 0x50, 0x78, 0x7A, 0x29, 0x88, 0xF7, 0x06, 0x21, 0x09, 0xF3, 0x5C, 0x95, 0xAE, 0x66, 0x12, 0x8F, 0x85, 0xC8, 0x5A, 0xBF, 0x33, 0x3D, 0x86, 0x90, 0x8C, 0xED, 0xD5, 0x8B, 0xA4, 0xC5, 0xC7, 0xEA, 0xF6, 0x79, 0x1E, 0x3C, 0xBA, 0x97, 0x4E, 0x38, 0x60, 0x08, 0xDD, 0xFA, 0xB3, 0xDE, 0x77, 0x81, 0x41, 0x19, 0xF4, 0x52, 0x6B, 0xFF, 0xD8, 0x2A, 0xC2, 0xBC, 0xB9, 0xE7, 0x91, 0xE9, 0x54, 0x82, 0xAD, 0x7E, 0x11, 0x35, 0x93, 0xB0, 0xA1, 0x18, 0xC4, 0x53, 0x0A, 0x74, 0x2F, 0xE2, 0x17, 0x98, 0x0C, 0x70, 0x92, 0x47, 0x64, 0x16, 0xFE, 0x75, 0x83, 0x37, 0x8D, 0x07, 0x72, 0x25, 0x04, 0xB7, 0xC9, 0xCE, 0x0E, 0x9E, 0xEB, 0xCF, 0xB1, 0xDB, 0x71, 0x56, 0xAF, 0x39, 0xF0, 0xBB, 0xBD, 0x46, 0x32, 0xE6, 0x9F, 0x4F, 0x1B, 0x4D, 0x68, 0xF2, 0x4B, 0x2E, 0xCB, 0x20, 0xD2, 0x0B, 0xA5, 0xEE, 0xE1, 0xA9, 0x2B, 0x84, 0x14, 0x67, 0x63, 0x6F, 0x3E, 0x7F, 0xFD, 0xB6, 0xFC, 0x55, 0x7C, 0x5F, 0xF8, 0x4C, 0x65, 0x2C, 0x30, 0xEF, 0x48, 0xD7, 0x0D, 0x0F, 0x1A, 0x5E, 0xC0, 0x3A, 0x57, 0x6A, 0x31, 0x00, 0xF1, 0x59, 0x10, 0xB8, 0x9A, 0x43, 0x73, 0xA3, 0x6E, 0x26, 0x1D, 0x13, 0x15, 0x89, 0x5D, 0xDA, 0x61, 0xD1, 0x6C, 0xD3, 0xE0, 0xD9, 0x1F, 0xD4, 0x49, 0xEC, 0xE3, 0xD0, 0x34, 0x36, 0xC6, 0x24, 0xE4, 0xF5, 0xAA, 0x9B, 0xB2, 0x4A, 0xDF, 0xAC, 0x96, 0xDC, 0xE8, 0xA0, 0xF9, 0xC1, 0x9C, 0xCA, 0x9D, 0x27, 0xC3, 0xBE, 0x87, 0x28, 0xCC, 0x99, 0xE5, 0x45, 0x58, 0x94, 0x23, 0x22, 0xFB, 0x02, 0x01, 0x03, 0x8A, 0x7B, 0xB5, 0x1C, 0xA7, 0x44, 0xCD, 0xA2, 0x51, 0x8E, 0x3F, 0x42, 0xD6, 0x69, 0xAB, 0x62, 0x3B, 0x7D, 0xA6, 0x05, 0x2D, 0xA8, 0x80, 0x6D, 0xB4, 0x76, 0x5B, }; bool GetKey(unsigned char *lastKey, unsigned int keyLen) { unsigned int i, j; unsigned char temp; unsigned char lowByte = 0; unsigned char highByte = 0; unsigned char* highKey = (unsigned char*)"3ww3U53wOAWG333w"; unsigned char* lowKey = (unsigned char*)"wPZ56GGw0PO02OUW"; unsigned char* constKey = (unsigned char*)"A3Cw6Gb0OZWPU52s"; memset(lastKey, 0, keyLen); //索引constKey for (i = 0; i < keyLen; i++) { for (j = 0; j < keyLen; j++) { if (highKey[i] == constKey[j]) break; } if (j >= keyLen) return false; highByte = j << 4; for (j = 0; j < keyLen; j++) { if (lowKey[i] == constKey[j]) break; } if (j >= keyLen) return false; lowByte = j; lastKey[i] |= highByte; lastKey[keyLen - 1 - i] |= lowByte; } //最后一个字节置换到第一个位置 temp = lastKey[keyLen-1]; for (i = keyLen-1; i >0; i--) { lastKey[i] = lastKey[i - 1]; } lastKey[i] = temp; //索引g_indexKey for (i = 0; i < keyLen; i++) { for (j = 0; j < 256; j++) { if (lastKey[i] == g_indexKey[j]) break; } if (j >= 256) return false; lastKey[i] = j; } //相邻字节交换 for (i = 0; i < (keyLen>>1); i++) { temp = lastKey[i * 2]; lastKey[i * 2] = lastKey[i * 2 + 1]; lastKey[i * 2 + 1] = temp; } //与0x2333AE83异或 unsigned int eorConstKey = 0x2333AE83; unsigned int* p = (unsigned int*)lastKey; for (i = 0; i < (keyLen >> 2); i++) { p[i] = p[i] ^ eorConstKey; } //高4位与低4位交换 for (i = 0; i < keyLen; i++) { highByte = lastKey[i] >> 4; lowByte = lastKey[i] & 0xf; lastKey[i] = (lowByte << 4) | highByte; } //索引g_indexKey for (i = 0; i < keyLen; i++) { for (j = 0; j < 256; j++) { if (lastKey[i] == g_indexKey[j]) break; } if (j >= 256) return false; lastKey[i] = j; } //最后一个字节置换到第一个位置 temp = lastKey[keyLen - 1]; for (i = keyLen - 1; i >0; i--) { lastKey[i] = lastKey[i - 1]; } lastKey[i] = temp; return true; }sn = "C0ngRa7U1AtIoN2U"
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
最后于 2018-6-25 15:40
被oooAooo编辑
,原因:
赞赏
|
|
---|---|
|
,JNI_OnLoad是被Hook了导致没有走到那里的
|
他的文章
[原创]看雪CTF2019Q3第四题WP
5350
[2019看雪CTF晋级赛Q3第九题WP
11659
看原图