本帖最后由 zhukai055 于 2018-9-9 08:36 编辑
sub_401036:
这里 可以看到,程序通过创建 按钮指针回调监视,进入按钮事件。
sub_401223:
如果某种条件成立,进入获取编辑框文本,并传入sub_401103函数中
sub_401103:
1.其中使用了srand 和rand 简称 构造伪随机数 不可逆 只能爆破
2.srand()使用 dword_40406c^v2; v2= sum(str[ i]) ;
3.操作dword_40406c数据的指令
。
5.这里是pizza大佬的核心反调试 和 dword_40406c数据操作 过程了。
6.以前易语言中做外挂,NtQueryInformationProcess这个函数反调试 很常用。
7.NtQueryInformationProcess :查询线程属性函数,可以查询是否被调试。
8.因为程序使用的是指针回调,nop掉 函数,我怕会异常退出,没弄,当然也可以 直接读地址,我们先用静态分析。
9.
10.
[Asm] 纯文本查看 复制代码 dword_40406c = 1;
dword_40406c=dword_40406c^0x31333337;
dword_40406c=dword_40406c^shuzu[start];
start=6a;
程序的6a位置=6e;
也就是说:dword_40406c=6e^0x31333337;
dword_40406c=0x31333359;
11.我们动态,读地址一下。
12.易语言代码:
[C++] 纯文本查看 复制代码 调试输出 (hex (memory_class.读整数 (进程_名取ID (“give_a_try.exe”), dec (“40406c”))))
输出结果:“ 31333359”
13.结果一样
14.我们现在看一下for循环的内容
15.v6=rand()*str[ i];后面跟上的 v6的次方取余 也就是RSA算法。
16.看IDA中是 e=32768+1 ,我开始,用这个e 去解RSA ,一直失败。看了一下汇编代码。
17.发现,IDA少了 一次操作。
18.e=32768*2+1 n=0xFAC96621
19.解d,这里省略。d=3014950909;
20.RSA VS C++
[C++] 纯文本查看 复制代码 unsigned __int64 RSA_dec(unsigned __int64 a)
{
unsigned __int64 v21 = 1; // edx
for (int i = 0; i < 3014950909; i++)
{
v21 = v21*a % 0xFAC96621;
}
return v21;
}
unsigned __int64 RSA_enc(unsigned __int64 a)
{
unsigned __int64 v21=1; // edx
for (int i = 0; i < 65537; i++)
{
v21 = v21*a % 0xFAC96621;
}
return v21;
}
21.
22.我们解一下 4030B4的数据即可。因为d比较大,解密过程特别慢。
23.结果:[Asm] 纯文本查看 复制代码 unsigned __int64 B[] = { 1683306, 2791044, 2305108, 2970108,16728, 3588802, 2192320, 914940,2437320, 459867, 2875365, 3571292,3320616, 373422, 418836, 1584825,634980, 2859675, 358545, 1535390,724608, 929480, 1815345, 1152676,1134546, 1584660, 670815, 1820736,1900496, 106539, 877572, 679677,233985, 1028790, 169282, 992560,469568, 133570, 2957031, 460096,2915374, 3752875 };
24.爆破v2
25.v2 ∈(0x7f*1,0x7f*42)
26.我们把42位都解出来,然后sum解密后的值,看与前面我们的v2是否相等,如果相等,则结果正确。
27:vs c++代码
[C++] 纯文本查看 复制代码 for (int ia =0x7F*1; ia < 0x7F*42; ia++)
{
srand(825439065 ^ ia);
for (i = 0; i < 42; i++)
{
int ran = rand();
if (ran == 0)
{
flag[i] = 0;
}
else
{
flag[i] = B[i] / ran;
}
}
if (flag[0] == 'f' && flag[1] == 'l')
{
for (int ix = 0; ix < 42; ix++)
{
printf("%c", flag[ix]);
}
cout << endl;
system("pause");
}
}
system("pause")
28.结果:
29.最后祝pizza新加坡比赛顺利。
附原文件:
give_a_try.zip
(2.3 KB, 下载次数: 29)
|