某公司otp生成的so层分析备忘
仍然是菜鸟备忘,上一篇在这里https://www.52pojie.cn/thread-1065238-1-1.html{:1_908:}一、IDA打开libmkey.so,定位Java_com_netease_mkey_core_OtpLib_getOtp函数,这是一个jni函数,先f5看一下
int __fastcall Java_com_netease_mkey_core_OtpLib_getOtpp(JNIEnv *jnienv, int a2, int a3, int a4, int a5, int a6, int a7)
{
int v7; // r4
JNIEnv *jinenv2; // r5
jbyte *v9; // r6
int v10; // r1
int v11; // r7
v7 = a3;
jinenv2 = jnienv;
v9 = (*jnienv)->GetByteArrayElements(jnienv, a7, 0);
v11 = get_otp(v7, v10, a5, a6, v9); // a3 a5 a6 a7
((*jinenv2)->ReleaseByteArrayElements)(jinenv2, a7, v9, 0);
return v11;
}
第一个参数a1改为*jnienv,第二个参数为jobject,a3为参数e,a4是寄存器r3没用上动态一下发现a5,a6参数合起来为参数Long.parseLong(str),位数太多一个寄存器放不下a7为byte数组str2先通过jni函数GetByteArrayElements转换类型,在ReleaseByteArrayElements还原为javabyte数组
二、关键代码在get_otp函数里
int __fastcall get_otp(int a1, int a2, unsigned int a3, unsigned int a4, int a5)
{
unsigned int strr; // ST08_4 a3 a4 存储序列号 a5存储str2转化为的数组
unsigned int strr2; // ST0C_4
struct tm *tm; // r4
int tm_y; // r0
unsigned int strr_nor; // r4
signed int v10; // r4
int result; // r0
unsigned __int8 v12; // r1
time_t timer; //
int v14; //
char s; //
char v16; //
char v17; //
char tm_m; //
char tm_d; //
char tm_h; //
char tm_mi; //
char tm_sec; //
char strr_nor2; //
char strr_nor3; //
char strr_h; //
char strr_nor_b1; //
char strr_nor_b2; //
char strr_nor_h; //
char v29; //
strr = a3;
strr2 = a4;
timer = a1 + 28800;
tm = gmtime(&timer); // gmtime根据时间戳产生tm时间结构体,因为从1900年开始算+28800
memset(&s, 0, 16u); // 把*s后面16字节设置为0
tm_y = tm->tm_year;
v16 = 20;
s = 0;
v17 = tm_y % 10;
tm_m = tm->tm_mon;
tm_d = tm->tm_mday;
tm_h = tm->tm_hour;
tm_mi = tm->tm_min;
tm_sec = 30 * (tm->tm_sec / 30);
strr_nor = (strr << 24) | (strr >> 24) | ((strr & 0xFF00) << 8) | ((strr & 0xFF0000) >> 8);
strr_h = HIBYTE(strr);
strr_nor2 = ((strr2 << 24) | (strr2 >> 24) | ((strr2 & 0xFF00) << 8) | ((strr2 & 0xFF0000) >> 8)) >> 16;
strr_nor3 = ((strr2 << 24) | (strr2 >> 24) | ((strr2 & 0xFF00) << 8) | ((strr2 & 0xFF0000) >> 8)) >> 24;
strr_nor_b1 = BYTE1(strr_nor);
strr_nor_b2 = BYTE2(strr_nor);
strr_nor_h = HIBYTE(strr_nor); //上面一系列操作把时间戳e与序列号str经过运算转换成为s数组的1-14位
my_md5(v14, a5, 128); // 把a5按128位my_md5加密结果放入v14
v10 = 10;
my_sha256(v14, &s, v29); // 把v14与s通过my_sha256加密结果放入v29
result = 0;
do
{
v12 = v29 % 0xAu;
result = 10 * result + v12; // 循环6次,每次取v29的11-16位与10取余数作为opt密码
}
while ( v10 != 16 );
return result;
}
很清晰,,首先,通过一系列操作把时间戳e与序列号str转换成为s数组的1-14位,s数组共16位调用my_md5加密a5也就是参数str2,结果放在v14中,简单看一下堆栈-00000240 v14 DCD 129 dup(?) v14是 my_md5加密结果129个dword
-0000003C s DCB ? s数组开始
-0000003B anonymous_0 DCB ?
-0000003A anonymous_1 DCB ?
-00000039 tm_m DCB ?
-00000038 tm_d DCB ?
-00000037 tm_h DCB ?
-00000036 tm_mi DCB ?
-00000035 tm_sec DCB ?
-00000034 strr_nor2 DCB ?
-00000033 strr_nor3 DCB ?
-00000032 strr_h DCB ?
-00000031 strr_nor_b1 DCB ?
-00000030 strr_nor_b2 DCB ?
-0000002F strr_nor_h DCB ?
-0000002E DCB ? ; undefined
-0000002D DCB ? ; undefined s数组结束
-0000002C var_2C DCB 16 dup(?) 这是v29, my_sha256加密结果
-0000001C var_1C DCD ?
三、简单看下my_md5,比较清晰,生成v14共有129位,不算最后一位共512个字节 my_md5(v14,a5, 128); // 把a5按128位my_md5哈希结果放入v14
1.ifa3=128 v5=10 a1=10
2.fori=0:3 通过a2字节生成a1字节a1生成
3.通过a1位与dword_4D14经过运算]生成a1循环到a1停止
4.初始化KT0-KT4
5.a1=a1
6.循环9次,通过a1作为下标运算KT0123生成a1 a1作为下标运算KT0123生成a14i] a1作为下标运算KT0123生成a1 a1作为下标运算KT0123生成a1
最终生成a1
7.a1=a1a1=a1a1=a1a1=a1
signed int __fastcall my_md5(int *a1, unsigned __int8 *a2, int a3)
{
int *a1a; // r5
int a3a; // r6
signed int v5; // r2
unsigned __int8 *s22; // r2
int *a1aaa; // r0
int v8; // r1
int v9; // r3
int v10; // r7
int *a1aa; // r3
int *dword_4D14a; // r2
int dword_4D14_0; // r6
unsigned int a1aaa3; // r1
int v15; // r6
int a1aa1; // r7
int v17; // r7
int *v18; // r2
int v19; // r6
unsigned int v20; // r1
int v21; // r6
int v22; // r7
int v23; // r7
int v24; // r6
int v25; // r6
int v26; // r6
unsigned int v27; // r1
int v28; // r7
int v29; // r0
int v30; // r7
int v31; // r0
int v32; // r7
int v33; // r0
int v34; // r7
unsigned int v35; // r0
int v36; // r7
int v37; // r0
int v38; // r7
int v39; // r0
int v40; // r7
int v41; // r0
int v42; // r2
int v43; // r1
int v44; // ST10_4
_DWORD *v45; // r2
int v46; // r1
int a44in; // r3
int *a1a68; // r2
unsigned int a1a39in; // r1
unsigned int a1a36in; // r1
signed int result; // r0
unsigned __int8 *s2; //
signed int v53; //
s2 = a2;
a1a = a1;
a3a = a3;
if ( do_init )
{
iVc3tO();
do_init = 0;
}
v5 = 10;
a1a = v5;
s22 = s2;
a1aaa = a1a;
v8 = 0;
while ( v8 < a3a >> 5 ) // for i=0:3 通过a2字节生成a1字节 a1生成
{
++v8;
v9 = (s22 << 16) | (*s22 << 24) | s22;
v10 = s22;
s22 += 4;
*a1aaa = (v10 << 8) | v9;
++a1aaa;
}
a1aa = a1a;
switch ( a3a )
{
case 128: // 通过a1位与dword_4D14)] << 16]生成a1
// 循环到生成a1停止
dword_4D14a = dword_4D14;
do
{
dword_4D14_0 = *dword_4D14a;
++dword_4D14a;
a1aaa3 = a1aa;
v15 = (dword_4D14[(a1aaa3 >> 8) + 10] << 16) ^ dword_4D14_0 ^ *a1aa ^ (dword_4D14 << 8) ^ dword_4D14[(a1aaa3 >> 24) + 10] ^ (dword_4D14[((a1aaa3 >> 16) & 0xFF) + 10] << 24);
a1aa1 = a1aa;
a1aa = v15;
a1aa = v15 ^ a1aa1;
v17 = v15 ^ a1aa1 ^ a1aa;
a1aa = a1aaa3 ^ v17;
a1aa = v17;
a1aa += 4;
}
while ( dword_4D14a != &dword_4D14 );
a1aa = a1a + 40;
break;
}
if ( KT_init ) // 初始化KT0-KT4,通过dword_4D14生成dword_5114、dword_5514、dword_5914、dword_5D14的下标生成KT0-KT4
{
v42 = 0;
do
{
v43 = dword_4D14;
v44 = dword_4D14;
KT0 = dword_5114;
KT1 = dword_5514;
KT2 = dword_5914;
KT3 = dword_5D14;
++v42;
}
while ( v42 != 256 );
KT_init = 0;
}
v45 = a1a + 63;
v45 = *a1aa;
v45 = a1aa;
v53 = 1;
v45 = a1aa;
v46 = a1aa;
a44in = (a1aa + 4); // a44in=a1aa
v45 = v46;
a1a68 = a1a + 68;
while ( 1 )
{
a1a36in = *(a44in - 32); // 00001400 sub r1 0x20 相当于a1,在此取出一个dword4位
if ( v53 >= a1a ) // a1=10,所以循环9次,通过a1作为下标运算KT0123生成a1
// a1作为下标运算KT0123生成a1
// a1作为下标运算KT0123生成a1
// a1作为下标运算KT0123生成a1
break;
*a1a68 = KT3 ^ KT0 ^ KT1[(a1a36in >> 16) & 0xFF] ^ KT2;
a1a68 = KT3[*(a44in - 28) & 0xFF] ^ KT0[*(a44in - 28) >> 24] ^ KT1[(*(a44in - 28) >> 16) & 0xFF] ^ KT2[*(a44in - 28) >> 8];
a1a68 = KT3[*(a44in - 24) & 0xFF] ^ KT0[*(a44in - 24) >> 24] ^ KT1[(*(a44in - 24) >> 16) & 0xFF] ^ KT2[*(a44in - 24) >> 8];
a1a39in = *(a44in - 20); // 相当于a1
a44in -= 16; // a44in每次下标-4 因为他前面类型转换为int了 出循环时变为a1
a1a68 = KT0 ^ KT1[(a1a39in >> 16) & 0xFF] ^ KT3 ^ KT2;
a1a68 += 4; // 出循环时变为a1
++v53;
}
*a1a68 = a1a36in; // a44in循环9次最后变成a1,所以a36in变为a1
// a1=a1
// a1=a1
// a1=a1
// a1=a1
//
result = 0;
a1a68 = *(a44in - 28);
a1a68 = *(a44in - 24);
a1a68 = *(a44in - 20);
return result;
}
四、my_sha256函数比较复杂,是把上一部生成的s数组与my_md5的结果v14经过一些计算,我看了半天,也没搞明白他跟sha256算法有什么关系,希望大佬来解释一下,密码学学的很渣 手动狗头
1.首先,分别取a1和a2前4个4字节运算生成v3v4v5v62.然后,通过a1的4567字节与v3456运算生成双字数组dword_6114,6514,6914,6d14的下标取出4个字节异或v78910循环到v35363738最后生成v54555339
3.如果a1>10 通过a1的40-43与v54555339生成v41424344 通过v41424344与a1的44-47重新生成v54555339 v40=a1+44 如果a1>12 通过a1的48-51与v54555339生成v45464748 通过v45464748与a1的52-55重新生成v54555339 v40=a1+52否则a1<=10,通过上文我们知道a1=10,所以直接跑这一句 v40=a1+36
4.通过v40的4-7与v54555339运算得到dword_4D14下标生成v495051与result返回值将v495051与result填充到v56的0-15位int __fastcall my_sha256(_DWORD *a1, unsigned int *a2, _BYTE *a3)
{
unsigned int v3; // ST0C_4 a1是my_md5结果v14,a2是s数组,a3是结果存储
unsigned int v4; // ST10_4
unsigned int v5; // r7
unsigned int v6; // r6
unsigned int v7; // ST14_4
unsigned int v8; // ST18_4
unsigned int v9; // ST1C_4
unsigned int v10; // r6
unsigned int v11; // ST0C_4
unsigned int v12; // ST10_4
unsigned int v13; // ST24_4
unsigned int v14; // r6
unsigned int v15; // ST14_4
unsigned int v16; // ST18_4
unsigned int v17; // ST1C_4
unsigned int v18; // r7
unsigned int v19; // ST0C_4
unsigned int v20; // ST10_4
unsigned int v21; // ST28_4
unsigned int v22; // r5
unsigned int v23; // ST1C_4
unsigned int v24; // ST24_4
unsigned int v25; // ST2C_4
unsigned int v26; // r6
unsigned int v27; // ST0C_4
unsigned int v28; // ST10_4
unsigned int v29; // ST34_4
unsigned int v30; // r6
unsigned int v31; // ST1C_4
unsigned int v32; // ST24_4
unsigned int v33; // ST08_4
unsigned int v34; // r6
unsigned int v35; // ST2C_4
unsigned int v36; // ST34_4
unsigned int v37; // ST00_4
unsigned int v38; // r7
unsigned int v39; // r5
_DWORD *v40; // r7
unsigned int v41; // ST34_4
unsigned int v42; // r1
unsigned int v43; // r4
unsigned int v44; // r3
unsigned int v45; // ST14_4
unsigned int v46; // ST18_4
unsigned int v47; // ST28_4
unsigned int v48; // r5
int v49; // r1
int v50; // r2
int v51; // r4
int result; // r0
unsigned int v53; //
unsigned int v54; //
unsigned int v55; //
_BYTE *v56; //
signed int v57; //
v56 = a3; // a2有16个字节4个字
// a1有521个字节 128个字
v3 = _byteswap_ulong(*a2) ^ *a1;
v4 = _byteswap_ulong(a2) ^ a1;
v5 = _byteswap_ulong(a2) ^ a1;
v6 = _byteswap_ulong(a2) ^ a1;
v7 = dword_6114 ^ a1 ^ dword_6514[(v3 >> 24) + 10] ^ dword_6914[((v4 >> 16) & 0xFF) + 10] ^ dword_6D14[(v5 >> 8) + 10];
v8 = dword_6114 ^ a1 ^ dword_6514[(v4 >> 24) + 10] ^ dword_6914[((v5 >> 16) & 0xFF) + 10] ^ dword_6D14[(v6 >> 8) + 10];
v9 = dword_6D14[(v3 >> 8) + 10] ^ dword_6114 ^ a1 ^ dword_6514[(v5 >> 24) + 10] ^ dword_6914[((v6 >> 16) & 0xFF) + 10];
v10 = dword_6D14[(v4 >> 8) + 10] ^ a1 ^ dword_6114 ^ dword_6514[(v6 >> 24) + 10] ^ dword_6914[((v3 >> 16) & 0xFF) + 10];
v11 = dword_6114 ^ a1 ^ dword_6514[(v7 >> 24) + 10] ^ dword_6914[((v8 >> 16) & 0xFF) + 10] ^ dword_6D14[(v9 >> 8) + 10];
v12 = dword_6114 ^ a1 ^ dword_6514[(v8 >> 24) + 10] ^ dword_6914[((v9 >> 16) & 0xFF) + 10] ^ dword_6D14[(v10 >> 8) + 10];
v13 = dword_6114 ^ a1 ^ dword_6514[(v9 >> 24) + 10] ^ dword_6914[((v10 >> 16) & 0xFF) + 10] ^ dword_6D14[(v7 >> 8) + 10];
v14 = a1 ^ dword_6114 ^ dword_6514[(v10 >> 24) + 10] ^ dword_6914[((v7 >> 16) & 0xFF) + 10] ^ dword_6D14[(v8 >> 8) + 10];
v15 = dword_6114 ^ a1 ^ dword_6514[(v11 >> 24) + 10] ^ dword_6914[((v12 >> 16) & 0xFF) + 10] ^ dword_6D14[(v13 >> 8) + 10];
v16 = dword_6114 ^ a1 ^ dword_6514[(v12 >> 24) + 10] ^ dword_6914[((v13 >> 16) & 0xFF) + 10] ^ dword_6D14[(v14 >> 8) + 10];
v17 = dword_6D14[(v11 >> 8) + 10] ^ dword_6114 ^ a1 ^ dword_6514[(v13 >> 24) + 10] ^ dword_6914[((v14 >> 16) & 0xFF) + 10];
v18 = a1 ^ dword_6114 ^ dword_6514[(v14 >> 24) + 10] ^ dword_6914[((v11 >> 16) & 0xFF) + 10] ^ dword_6D14[(v12 >> 8) + 10];
v19 = dword_6114 ^ a1 ^ dword_6514[(v15 >> 24) + 10] ^ dword_6914[((v16 >> 16) & 0xFF) + 10] ^ dword_6D14[(v17 >> 8) + 10];
v20 = dword_6114 ^ a1 ^ dword_6514[(v16 >> 24) + 10] ^ dword_6914[((v17 >> 16) & 0xFF) + 10] ^ dword_6D14[(v18 >> 8) + 10];
v21 = dword_6114 ^ a1 ^ dword_6514[(v17 >> 24) + 10] ^ dword_6914[((v18 >> 16) & 0xFF) + 10] ^ dword_6D14[(v15 >> 8) + 10];
v22 = a1 ^ dword_6114 ^ dword_6514[(v18 >> 24) + 10] ^ dword_6914[((v15 >> 16) & 0xFF) + 10] ^ dword_6D14[(v16 >> 8) + 10];
v23 = dword_6114 ^ a1 ^ dword_6514[(v19 >> 24) + 10] ^ dword_6914[((v20 >> 16) & 0xFF) + 10] ^ dword_6D14[(v21 >> 8) + 10];
v24 = dword_6114 ^ a1 ^ dword_6514[(v20 >> 24) + 10] ^ dword_6914[((v21 >> 16) & 0xFF) + 10] ^ dword_6D14[(v22 >> 8) + 10];
v25 = dword_6D14[(v19 >> 8) + 10] ^ dword_6114 ^ a1 ^ dword_6514[(v21 >> 24) + 10] ^ dword_6914[((v22 >> 16) & 0xFF) + 10];
v26 = a1 ^ dword_6114 ^ dword_6514[(v22 >> 24) + 10] ^ dword_6914[((v19 >> 16) & 0xFF) + 10] ^ dword_6D14[(v20 >> 8) + 10];
v27 = dword_6114 ^ a1 ^ dword_6514[(v23 >> 24) + 10] ^ dword_6914[((v24 >> 16) & 0xFF) + 10] ^ dword_6D14[(v25 >> 8) + 10];
v28 = dword_6114 ^ a1 ^ dword_6514[(v24 >> 24) + 10] ^ dword_6914[((v25 >> 16) & 0xFF) + 10] ^ dword_6D14[(v26 >> 8) + 10];
v29 = dword_6114 ^ a1 ^ dword_6514[(v25 >> 24) + 10] ^ dword_6914[((v26 >> 16) & 0xFF) + 10] ^ dword_6D14[(v23 >> 8) + 10];
v30 = a1 ^ dword_6114 ^ dword_6514[(v26 >> 24) + 10] ^ dword_6914[((v23 >> 16) & 0xFF) + 10] ^ dword_6D14[(v24 >> 8) + 10];
v31 = dword_6114 ^ a1 ^ dword_6514[(v27 >> 24) + 10] ^ dword_6914[((v28 >> 16) & 0xFF) + 10] ^ dword_6D14[(v29 >> 8) + 10];
v32 = dword_6114 ^ a1 ^ dword_6514[(v28 >> 24) + 10] ^ dword_6914[((v29 >> 16) & 0xFF) + 10] ^ dword_6D14[(v30 >> 8) + 10];
v33 = dword_6D14[(v27 >> 8) + 10] ^ dword_6114 ^ a1 ^ dword_6514[(v29 >> 24) + 10] ^ dword_6914[((v30 >> 16) & 0xFF) + 10];
v34 = dword_6514[(v30 >> 24) + 10] ^ a1 ^ dword_6114 ^ dword_6914[((v27 >> 16) & 0xFF) + 10] ^ dword_6D14[(v28 >> 8) + 10];
v35 = dword_6114 ^ a1 ^ dword_6514[(v31 >> 24) + 10] ^ dword_6914[((v32 >> 16) & 0xFF) + 10] ^ dword_6D14[(v33 >> 8) + 10];
v36 = dword_6114 ^ a1 ^ dword_6514[(v32 >> 24) + 10] ^ dword_6914[((v33 >> 16) & 0xFF) + 10] ^ dword_6D14[(v34 >> 8) + 10];
v37 = dword_6114 ^ a1 ^ dword_6514[(v33 >> 24) + 10] ^ dword_6914[((v34 >> 16) & 0xFF) + 10] ^ dword_6D14[(v31 >> 8) + 10];
v38 = a1 ^ dword_6114 ^ dword_6514[(v34 >> 24) + 10] ^ dword_6914[((v31 >> 16) & 0xFF) + 10] ^ dword_6D14[(v32 >> 8) + 10];
v54 = dword_6114 ^ a1 ^ dword_6514[(v35 >> 24) + 10] ^ dword_6914[((v36 >> 16) & 0xFF) + 10] ^ dword_6D14[(v37 >> 8) + 10];
v55 = dword_6114 ^ a1 ^ dword_6514[(v36 >> 24) + 10] ^ dword_6914[((v37 >> 16) & 0xFF) + 10] ^ dword_6D14[(v38 >> 8) + 10];
v53 = dword_6D14[(v35 >> 8) + 10] ^ dword_6114 ^ a1 ^ dword_6514[(v37 >> 24) + 10] ^ dword_6914[((v38 >> 16) & 0xFF) + 10];
v39 = a1 ^ dword_6114 ^ dword_6514[(v38 >> 24) + 10] ^ dword_6914[((v35 >> 16) & 0xFF) + 10] ^ dword_6D14[(v36 >> 8) + 10];
v57 = a1;
if ( v57 > 10 )
{
v41 = dword_6114 ^ a1 ^ dword_6514[(v54 >> 24) + 10] ^ dword_6914[((v55 >> 16) & 0xFF) + 10] ^ dword_6D14[(v53 >> 8) + 10];
v42 = dword_6D14[(v39 >> 8) + 10] ^ dword_6114 ^ a1 ^ dword_6514[(v55 >> 24) + 10] ^ dword_6914[((v53 >> 16) & 0xFF) + 10];
v43 = dword_6114 ^ a1 ^ dword_6514[(v53 >> 24) + 10] ^ dword_6914[((v39 >> 16) & 0xFF) + 10] ^ dword_6D14[(v54 >> 8) + 10];
v44 = a1 ^ dword_6114 ^ dword_6514[(v39 >> 24) + 10] ^ dword_6914[((v54 >> 16) & 0xFF) + 10] ^ dword_6D14[(v55 >> 8) + 10];
v54 = dword_6114 ^ a1 ^ dword_6514[(v41 >> 24) + 10] ^ dword_6914[((v42 >> 16) & 0xFF) + 10] ^ dword_6D14[(v43 >> 8) + 10];
v55 = dword_6114 ^ a1 ^ dword_6514[(v42 >> 24) + 10] ^ dword_6914[((v43 >> 16) & 0xFF) + 10] ^ dword_6D14[(v44 >> 8) + 10];
v53 = dword_6114 ^ a1 ^ dword_6514[(v43 >> 24) + 10] ^ dword_6914[((v44 >> 16) & 0xFF) + 10] ^ dword_6D14[(v41 >> 8) + 10];
v39 = dword_6914[((v41 >> 16) & 0xFF) + 10] ^ a1 ^ dword_6114 ^ dword_6514[(v44 >> 24) + 10] ^ dword_6D14[(v42 >> 8) + 10];
v40 = a1 + 44;
if ( v57 > 12 )
{
v45 = dword_6114 ^ a1 ^ dword_6514[(v54 >> 24) + 10] ^ dword_6914[((v55 >> 16) & 0xFF) + 10] ^ dword_6D14[(v53 >> 8) + 10];
v46 = dword_6114 ^ a1 ^ dword_6514[(v55 >> 24) + 10] ^ dword_6914[((v53 >> 16) & 0xFF) + 10] ^ dword_6D14[(v39 >> 8) + 10];
v47 = dword_6114 ^ a1 ^ dword_6514[(v53 >> 24) + 10] ^ dword_6914[((v39 >> 16) & 0xFF) + 10] ^ dword_6D14[(v54 >> 8) + 10];
v40 = a1 + 52;
v48 = dword_6D14[(v55 >> 8) + 10] ^ a1 ^ dword_6114 ^ dword_6514[(v39 >> 24) + 10] ^ dword_6914[((v54 >> 16) & 0xFF) + 10];
v54 = dword_6114 ^ a1 ^ dword_6514[(v45 >> 24) + 10] ^ dword_6914[((v46 >> 16) & 0xFF) + 10] ^ dword_6D14[(v47 >> 8) + 10];
v55 = dword_6114 ^ a1 ^ dword_6514[(v46 >> 24) + 10] ^ dword_6914[((v47 >> 16) & 0xFF) + 10] ^ dword_6D14[(v48 >> 8) + 10];
v53 = dword_6D14[(v45 >> 8) + 10] ^ dword_6114 ^ a1 ^ dword_6514[(v47 >> 24) + 10] ^ dword_6914[((v48 >> 16) & 0xFF) + 10];
v39 = dword_6D14[(v46 >> 8) + 10] ^ dword_6114 ^ a1 ^ dword_6514[(v48 >> 24) + 10] ^ dword_6914[((v45 >> 16) & 0xFF) + 10];
}
}
else
{
v40 = a1 + 36;
}
v49 = dword_4D14 ^ v40 ^ (dword_4D14[(v54 >> 24) + 10] << 24) ^ (dword_4D14[((v55 >> 16) & 0xFF) + 10] << 16) ^ (dword_4D14[(v53 >> 8) + 10] << 8);
v50 = v40 ^ dword_4D14 ^ (dword_4D14[(v55 >> 24) + 10] << 24) ^ (dword_4D14[((v53 >> 16) & 0xFF) + 10] << 16) ^ (dword_4D14[(v39 >> 8) + 10] << 8);
v51 = dword_4D14 ^ v40 ^ (dword_4D14[(v53 >> 24) + 10] << 24) ^ (dword_4D14[((v39 >> 16) & 0xFF) + 10] << 16) ^ (dword_4D14[(v54 >> 8) + 10] << 8);
result = (dword_4D14[(v39 >> 24) + 10] << 24) ^ v40 ^ dword_4D14 ^ (dword_4D14[((v54 >> 16) & 0xFF) + 10] << 16) ^ (dword_4D14[(v55 >> 8) + 10] << 8);
*v56 = HIBYTE(v49);
v56 = BYTE2(v49);
v56 = BYTE1(v49);
v56 = v49;
v56 = HIBYTE(v50);
v56 = BYTE2(v50);
v56 = BYTE1(v50);
v56 = HIBYTE(v51);
v56 = BYTE2(v51);
v56 = BYTE1(v51);
v56 = HIBYTE(result);
v56 = BYTE2(result);
v56 = v50;
v56 = v51;
v56 = BYTE1(result);
v56 = result;
return result;
}
五、最后,my_sha256加密后放入v29中,最后用数组v29的11-16位模10生成动态密码result的1-6位,完结,感谢大家的在支持{:1_924:}
锁匙扣 发表于 2019-12-8 07:48
我看不懂阿,还是继续学习吧。目前虽然是看不懂,但相信跟着学,肯定会进步的
兄弟 先看上一篇啊{:301_997:} 伤情丶 发表于 2019-12-4 10:22
这种硬刚的方式 实属佩服......
菜鸟现在只能一句一句看 最近抽时间一定要学习一下unicorn{:1_896:} 强大佬强{:1_893:} mark一下 本帖最后由 L剑仙 于 2022-3-24 17:49 编辑
感谢各位大佬支持
感谢分享,学习中。 大佬太强了,马克 学习一下 看下。。。。。。。。 学习学习。。。。 感谢分享,:lol:lol学习一下 感谢分享!