|
本文转载于 大三狗,水平有限,感觉要止步第二轮了。 第一题逆向没什么难度,主要是考察对算法的还原,最重要的是耐心题目: 输入正确的UserName和RegCode,显示注册成功。 用OD通过对GetDlgItem下断,找到按钮相应事件004026F0处用IDA分析 一.分析4026F0函数 在上面我还发现了这样一行代码(传图麻烦,蓝色的文字就是IDA显示的伪代码) v20 = SendMessageW(*((HWND *)v4 + 8), 0xF0u, 0, 0) == 1;// /v20为1 说明你选的标准版 为0选的是进阶版 用来标识标准版还是进阶版,暂且不管 二.分析405510函数主要如下: 405510函数进去首先对用户名做一个判断。起名为checkuser if ( checkuser((int *)&str_name) ) 1.分析checkuser函数 用OD发现这个函数在压参数入栈时,压的是我们输入的用户名,所以认为他是对用户名是否输入合法做一个判断 if ( a1[4] != 39 ) // a1[4]是我们输入的用户名长度 return 0;首先是进行长度判断,长度不满足0x27,直接返回false if ( v7 ) { v9 = v7; // 每执行一次加一 执行39次 // 通过toupper函数 把小写字符c转化为大写字母 do { *((_BYTE *)v23 + v8) = toupper(*((char *)v6 + v8)); ++v8; } while ( v8 != v9 ); v1 = a1; } 其次通过toupper函数将输入用户名中的小写字母转换成大写字母 sub_402A70(&v16, &unk_5AC430, 1u); // &unk_5AC430是# sub_404D70((int)v24, (int)v1, *(LPVOID *)&v16, v17, v18, v19, v20, v21); v10 = (_DWORD *)v24[0]; if ( (unsigned int)(v24[1] - v24[0] - 192) >= 0x18 ) goto LABEL_30;// LABEL_30将会导致return 0 之后要求输入的用户名必须是XXXX#XXXX#XXXX#XXXX#XXXX#XXXX#XXXX#XXXX形式,X的范围必须在0~9,a~f或A~F之间对用户名合法性检查完毕,若正确,返回1 继续执行get5m((int)&str_name, &v26, &v27, &v28, (int *)&v29, &v30);// 根据用户名 获取五个64位整数 存在12EEA8~ 发现这个函数根据输入的用户名得到了五个变量m1,m2,m3,m4,m5,之后会用到2.get5m分析没什么说的,用OD耐心的一步一步调试,发现他是把用户名分为了八段Seg1~Seg8 m1.QuadPart = 0; m1.QuadPart += ((seg1[0] * seg2[0]) << 0x10); m1.QuadPart += (seg3[1] ^ seg1[1]); m1.QuadPart += (seg1[2] % (seg4[2] + 1)) + 1; m1.QuadPart += (seg1[3] / (seg5[3]+1)); m2.QuadPart = 0; m2.QuadPart += ((seg2[0] ^ seg6[0]) << 0x10); m2.QuadPart += (seg2[1] % (seg7[1] + 3)); m2.QuadPart += (seg2[2] / (seg8[2] + 1)) + 5; m2.QuadPart += seg1[3] + seg2[3]; m3.QuadPart = 0; m3.QuadPart += ((seg3[0] / (seg2[0] + 3)) << 0x10); m3.QuadPart = m3.QuadPart ^ (seg3[1] % seg4[1]); m3.QuadPart += 0xc + seg6[2] + seg3[2]; m3.QuadPart += seg8[3] + seg3[3]; m4.QuadPart = 0; m4.QuadPart = m4.QuadPart + (seg3[3] ^ seg1[1]); m4.QuadPart = m4.QuadPart*(seg2[3] + seg4[1]); m4.QuadPart = m4.QuadPart&(seg6[2] & seg5[2]); m4.QuadPart = (seg8[3] * m4.QuadPart + m2.QuadPart)*seg7[0] * m1.QuadPart; m4.QuadPart = m4.QuadPart - ((m4.QuadPart - m2.QuadPart) % (2 * m1.QuadPart)); m5.QuadPart = 0; m5.QuadPart += (seg4[0] ^ seg5[0]) << 0x10; m5.QuadPart = m5.QuadPart*(seg4[1] % (seg5[1] + 2)); m5.QuadPart += 7 + (seg4[2] % (seg5[2] + 5)); m5.QuadPart += seg5[3] * seg4[3]; 在计算m4的时候我以为要用到高32位和低32位,所以用到了结构体。后来发现不需要,定义M变量的时候直接用INT64定义就行了 3.对if(...)的分析 if ( sub_406080(v14) && ((v16 = HIDWORD(v31), v17 = (__m128i *)v31, a13) || (v33 = xmmword_5AC470, sub_403010(HIDWORD(v31) - v31, v31, (char *)&v33, v15, v31))) && v16 - (_DWORD)v17 == 32 && v17[1].m128i_i32[2] ==842019128 && !v17[1].m128i_i32[3] ) // 406080函数就是对我们输入的key进行转换 这个判断看起来很复杂,我们先看Sub_406080(伪代码有点长,就不贴了)406080函数是对我们输入的RegCode进行转换得到三个INT64变量结合OD发现首先对我们输入的RegCode,与一个包含65个数的表做对比,我们输入的字符必须在这个表里存在表为:ZO6Kq79L&[email protected]*kAB8rsFewxlm+/u5a^2YtTJUVEn0$HI34y#=所以我猜想这肯定跟BASE64有关 果然,之后406080函数把我们输入的RegCode 四个一组 转成三个 char ch1 = a ^ (a >> 3); char ch2 = b ^ (b >> 3); char ch3 = c ^ (c >> 3); char ch4 = d ^ (d >> 3); char ret1 = 4 * ch1 | (ch2 >> 4) & 3; char ret2 = 16 * ch2 | (ch3 >> 2) & 0xF; char ret3 = (ch3 << 6) | ch4 & 0x3F; 将得到的 ret1,ret2,ret3存放到一个地方,后来发现后面的判断需要用到其中的一部分(其实前32位RegCode会最后组合成三个INT64的数a6,a7,a8) 三.分析最终的402F20check函数sub_402F20( v26, v27, v28, v29, v30, __PAIR__(_mm_cvtsi128_si32(_mm_srli_si128(v18, 4)), _mm_cvtsi128_si32(v18)), __PAIR__(_mm_cvtsi128_si32(_mm_srli_si128(v18, 12)), _mm_cvtsi128_si32(_mm_srli_si128(v18, 8))), *((__int64 *)&v33 + 1)) // 关键的check函数 返回1 说明我们输入的key与通过name计算的key相同 通过OD发现他将Get5m中得到的五个INT64变量 m1,m2,m3,m4,m5与406080函数得到的三个INT64变量a6,a7,a8做了这样的运算 bool __cdecl sub_402F20(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, __int64 a7, __int64 a8) { return a3 + (a2 + a1 * a6) * a6 == a7 && (a2 - a4) * (a2 - a4) == 4 * (a4 * a6 - (a2 + a1 * a6) * a6) * a1 && a3 + (a2 + a1 * a5 - a4) * a5 == a8; } 将return后的语句化简得(其实第二句是一个一元二次方程) a6 = (m4 - m2) / (2 * m1); a7 = m3 + (m2 + m1 * a6) * a6; a8 = m3 + (m2 + m1 * m5 - m4) * m5; 这是我们编写***的关键。先通过输入的合法用户名,得到五个变量m1,m2,m3,m4,m5再根据五个变量得到a6,a7,a8,具体算法在源代码里根据a6,a7,a8得到我们对应的RegCode(后面12位是固定的,有三种) |
相关文章: