12月6号金山公司员工失误造成IDA pro6.8的正式个人版完全泄露,里面包含正版的安装包,安装密码以及7月份的授权(这个要比hackteam放出来的那个时间短,hackteam授权时间是2016.4.8),不过授权时间并不影响使用,只是停止升级而已,不过按照IDA公司的一贯做法,该员工应该是被放到黑名单了。
0x01局域网检测
该Windows版本的IDA启动后,它会在端口23945上广播一个UDP包,并等待响应,看相同子网中是否有其他使用相同许可证密钥的IDA实例在运行。然后,IDA会将得到的响应数量与使用该许可证的用户数量进行比较,如果发现网络中存在过多的IDA实例,IDA会拒绝启动。
因此我把这处简单的限制给去除掉了,当然在吾爱破解上面早已经出现了该绿色版本的,下载地址。去除局域网验证方法很多,吾爱上hellotong88和看雪上都有基本的破解思路。针对6.8其实思路也差不多。
0x02 思路过程
按照最基本的破解思路,查找关键字符串,找到提示信息
很轻松就能找到提示信息,看看是哪个函数调用的
上图的sub_5533c0应该是最终的调用结果函数,因此还得往上继续逆,找到调用sub_5533c0的函数(由于图片太大,这里贴代码)
C++
| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 | int __usercall sub_553410@<eax>(SOCKET *a1@<ecx>, int a2@<esi>){int v2; // edi@1SOCKET v3; // ST08_4@1int result; // eax@1int v5; // ebx@4_DWORD *v6; // ecx@4int v7; // eax@4int v8; // esi@4int v9; // esi@9char *v10; // eax@9unsigned int v11; // ecx@9char *v12; // eax@16unsigned int v13; // ecx@16SOCKET v14; // ST00_4@20int v15; // [sp-4h] [bp-4Ch]@2int fromlen; // [sp+8h] [bp-40h]@1struct sockaddr from; // [sp+Ch] [bp-3Ch]@1char buf; // [sp+1Ch] [bp-2Ch]@1int v19; // [sp+20h] [bp-28h]@6char v20[16]; // [sp+24h] [bp-24h]@10char v21[16]; // [sp+34h] [bp-14h]@17 v2 = a1;v3 = *a1;fromlen = 16;result = recvfrom(v3, &buf, 40, 0, &from, &fromlen);if ( result != -1 ){v15 = a2;do{if ( result == 40 ){v5 = *(v2 + 316);qmutex_lock(*(v2 + 316), v15);v7 = *(v2 + 312);v8 = 0;if ( v7 > 0 ){v6 = (v2 + 24);do{if ( v19 == *v6 )break;++v8;v6 += 18;}while ( v8 < v7 );}v15 = v5;qmutex_unlock(v6);if ( v8 != *(v2 + 312) ){v9 = v2 + 72 * v8 + 24;v10 = (v9 + 8);v11 = 16;while ( *&v10[&v20[-v9 - 8]] == *v10 ){v11 -= 4;v10 += 4;if ( v11 < 4 )goto LABEL_20;}if ( v19 ){*(v9 + 4) = 0;sendto(*v2, v9, 40, 0, &from, 16);}else if ( time64(0) - *(v9 + 48) <= 3 ){v12 = (v9 + 24);v13 = 16;while ( *&v12[&v21[-v9 - 24]] == *v12 ){v13 -= 4;v12 += 4;if ( v13 < 4 ){++*(v9 + 40);sub_5533C0(v2, v9);break;}}}}}LABEL_20:v14 = *v2;fromlen = 16;result = recvfrom(v14, &buf, 40, 0, &from, &fromlen);}while ( result != -1 );}return result;} |
上述代码中,能看到调用了sendto()和recvfrom()这两个跟UDP通信很关键的函数,sendto()是把UDP数据报发给指定地址;recvfrom()是从指定地址接收UDP数据报。我们结合UDP的通讯过程来看上述代码能更快理解(图片来自网络)
对照上图和代码,能够看出IDA的局域网检测大概就是,作为接收端,调用bind()函数绑定IP,接收来自任意IP、任意网卡的发给指定端口的数据。作为发送端,调用bind()函数绑定IP,使用网卡号最低的网卡进行发送数据,也就是UDP数据广播,通过多次循环判断是否存在相同的IDA实例。按道理,这里是校验的关键了,可以改相应的条件判断,实现patch。事实上也是可以的,不过为了使得补丁损伤最少,还能够有更小的改动,再往上回溯两三层
可以看到如果sub_552120()函数return 0的话,接下来所有的函数都不会执行了,进入 sub_552120()看看return 0的条件
上图很明显,要使sub_552120 return 0,则 WSAStartup(2u, &v1)函数必须调用失败。
WSAStartup原型:int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );
wVersionRequested是Windows Sockets API提供的调用方可使用的最高版本号。
lpWSAData 是指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节。
只要这两个参数任何一个出现错误则调用失败。
更详细的说明,参见这篇博客。
0x03 patch过程
查看 WSAStartup(2u, &v1)函数传参,再做相应修改,可以看到这里只需要更改一个字节。
最后,Edit->Patch program->Change byte即可。











还没有评论,来说两句吧...