分析并模拟某程序服务端
本帖最后由 Rookietp 于 2013-5-18 09:29 编辑····标题:分析并模拟某程序服务端········作者:Rookietp········日期:2013-5-13·········只是一时兴起,没有其他目的,错误之处还请不吝赐教·····
该程序的验证是B/S架构,是基于浏览器的,服务端是ASP,模拟的服务端我是采用VC6.0编写。
///载入OD,运行程序,点击修改序列号,会弹出未注册。。
此时你回溯,会出错,下bpMessageBoxA 会拦截不到。
程序弹出信息框是采用创建线程,信息框弹出是调用MessageBoxTimeoutA
暂停与执行到用户代码的配合使用限定于主线程内。
定位关键可以通过字符串,按键事件,消息条件断点。
上半部分:00403480 64:A1 00000000MOV EAX,DWORD PTR FS: ; //验证段
00403486 6A FF PUSH -0x1
00403488 68 B83F4000 PUSH 00403FB8
0040348D 50 PUSH EAX
0040348E B8 10010100 MOV EAX,0x10110
00403493 64:8925 0000000>MOV DWORD PTR FS:,ESP
0040349A E8 11070000 CALL 00403BB0
0040349F 56 PUSH ESI
004034A0 8BF1 MOV ESI,ECX
004034A2 57 PUSH EDI
004034A3 8D4C24 0C LEA ECX,DWORD PTR SS:
004034A7 897424 08 MOV DWORD PTR SS:,ESI
004034AB E8 7E040000 CALL 0040392E
004034B0 C78424 20010100>MOV DWORD PTR SS:,0x0
004034BB E8 A0FEFFFF CALL 00403360; //产生随机数
004034C0 50 PUSH EAX
004034C1 8D4C24 10 LEA ECX,DWORD PTR SS:
004034C5 E8 52040000 CALL 0040391C
004034CA A1 54544000 MOV EAX,DWORD PTR DS:; //比较一个全局变量是否是已经验证通过了
004034CF 85C0 TEST EAX,EAX
004034D1 0F85 CA020000 JNZ 004037A1
004034D7 8D4424 34 LEA EAX,DWORD PTR SS:
004034DB 53 PUSH EBX
004034DC 50 PUSH EAX
004034DD E8 DEEFFFFF CALL 004024C0; //获取机器码
004034E2 83C4 04 ADD ESP,0x4
004034E5 50 PUSH EAX
004034E6 8D4C24 2C LEA ECX,DWORD PTR SS:
004034EA 68 EC514000 PUSH 004051EC;//http://disk.zgpmsj.com:146/disp1.asp?mac=
004034EF 51 PUSH ECX
004034F0 C68424 30010100>MOV BYTE PTR SS:,0x1
004034F8 E8 53060000 CALL 00403B50 ; //将固定字符串与机器码连接
004034FD 68 E4514000 PUSH 004051E4 ; &rnd=
00403502 8D5424 30 LEA EDX,DWORD PTR SS:
00403506 50 PUSH EAX
00403507 52 PUSH EDX
00403508 C68424 30010100>MOV BYTE PTR SS:,0x2
00403510 E8 35060000 CALL 00403B4A; //将固定字符串与随机数连接
00403515 8D4C24 10 LEA ECX,DWORD PTR SS:
00403519 8D5424 1C LEA EDX,DWORD PTR SS:
0040351D 51 PUSH ECX
0040351E 50 PUSH EAX
0040351F 52 PUSH EDX
00403520 C68424 30010100>MOV BYTE PTR SS:,0x3
00403528 E8 DB050000 CALL 00403B08; //生成最后的地址http://xxx/disp1.asp?mac=xxx&rnd=xxx
0040352D 8D4C24 2C LEA ECX,DWORD PTR SS:
00403531 C68424 24010100>MOV BYTE PTR SS:,0x7
00403539 E8 E4030000 CALL 00403922
0040353E 8D4C24 28 LEA ECX,DWORD PTR SS:
00403542 C68424 24010100>MOV BYTE PTR SS:,0x6
0040354A E8 D3030000 CALL 00403922
0040354F 8D4C24 38 LEA ECX,DWORD PTR SS:
00403553 C68424 24010100>MOV BYTE PTR SS:,0x5
0040355B E8 C2030000 CALL 00403922
00403560 6A 00 PUSH 0x0
00403562 6A 00 PUSH 0x0
00403564 6A 00 PUSH 0x0
00403566 6A 00 PUSH 0x0
00403568 68 DC514000 PUSH 004051DC
0040356D 90 NOP
0040356E E8 6DA1033E CALL wininet.InternetOpenA; //使用WININET API 进行打开操作
00403573 8BD8 MOV EBX,EAX
00403575 85DB TEST EBX,EBX
00403577 0F84 0B020000 JE 00403788; //是否打开成功
0040357D 8B4424 1C MOV EAX,DWORD PTR SS:
00403581 55 PUSH EBP
00403582 6A 00 PUSH 0x0
00403584 6A 00 PUSH 0x0
00403586 6A FF PUSH -0x1
00403588 6A 00 PUSH 0x0
0040358A 50 PUSH EAX
0040358B 53 PUSH EBX
0040358C 90 NOP
0040358D E8 62BE033E CALL wininet.InternetOpenUrlA; //使用WININET API 发送数据,GET
00403592 8BE8 MOV EBP,EAX
00403594 85ED TEST EBP,EBP
00403596 896C24 24 MOV DWORD PTR SS:,EBP
0040359A 0F84 E0010000 JE 00403780; //数据是否为空
004035A0 B9 19000000 MOV ECX,0x19
004035A5 33C0 XOR EAX,EAX
004035A7 8D7C24 58 LEA EDI,DWORD PTR SS:
004035AB 8D5424 58 LEA EDX,DWORD PTR SS:
004035AF F3:AB REP STOS DWORD PTR ES:
004035B1 8D4C24 38 LEA ECX,DWORD PTR SS:
004035B5 894424 38 MOV DWORD PTR SS:,EAX
004035B9 51 PUSH ECX
004035BA 6A 64 PUSH 0x64
004035BC 52 PUSH EDX
004035BD 55 PUSH EBP
004035BE 90 NOP
004035BF E8 C72F023E CALL wininet.InternetReadFile; //使用WININET 读取返回数据
004035C4 85C0 TEST EAX,EAX
004035C6 0F84 B4010000 JE 00403780; //数据是否为空
004035CC 8B35 64424000 MOV ESI,DWORD PTR DS:
004035D2 8D4424 58 LEA EAX,DWORD PTR SS:
004035D6 68 D0514000 PUSH 004051D0; 有效时间
004035DB 50 PUSH EAX
004035DC FFD6 CALL ESI; //调用strstr来查找返回数据是否有 “有效时间”
004035DE 83C4 08 ADD ESP,0x8
004035E1 85C0 TEST EAX,EAX
004035E3 0F84 7B010000 JE 00403764; //为0则跳如果服务端没有你的机器码信息,服务端直接返回“未注册”,服务端存在你的机器码信息,服务端返回“有效时间:-4913分钟///0578cea062dc054af986166292e68e12”
这个可以通过任何一款抓包工具来查看。
返回数据中,值得关注的是///后面这一串组合字串,通过测试,它会根据上半段所发送数据的随机数来动态生成.
http://xxx/disp1.asp?mac=xxx&rnd=xxx
再来看下半段:004035E9 8D4C24 58 LEA ECX,DWORD PTR SS:
004035ED 68 CC514000 PUSH 004051CC; ///
004035F2 51 PUSH ECX
004035F3 FFD6 CALL ESI; //寻找“///”
004035F5 8BE8 MOV EBP,EAX
004035F7 83C4 08 ADD ESP,0x8
004035FA 83C5 03 ADD EBP,0x3
004035FD B9 7C534000 MOV ECX,0040537C
00403602 55 PUSH EBP
00403603 E8 14030000 CALL 0040391C; //取出"///"后面的动态数据
00403608 68 7C534000 PUSH 0040537C
0040360D 8D4C24 20 LEA ECX,DWORD PTR SS:
00403611 E8 00030000 CALL 00403916
00403616 B9 18000000 MOV ECX,0x18
0040361B 33C0 XOR EAX,EAX
0040361D 8DBC24 BD000000 LEA EDI,DWORD PTR SS:
00403624 C68424 BC000000>MOV BYTE PTR SS:,0x0
0040362C F3:AB REP STOS DWORD PTR ES:
0040362E 66:AB STOS WORD PTR ES:
00403630 8D5424 34 LEA EDX,DWORD PTR SS:
00403634 C68424 28010100>MOV BYTE PTR SS:,0x8
0040363C 52 PUSH EDX
0040363D AA STOS BYTE PTR ES:
0040363E E8 7DEEFFFF CALL 004024C0; //再次进入取机器码
00403643 8B00 MOV EAX,DWORD PTR DS:
00403645 83C9 FF OR ECX,0xFFFFFFFF
00403648 8BF8 MOV EDI,EAX
0040364A 33C0 XOR EAX,EAX
0040364C 83C4 04 ADD ESP,0x4
0040364F 8D9424 BC000000 LEA EDX,DWORD PTR SS:
00403656 F2:AE REPNE SCAS BYTE PTR ES:
00403658 F7D1 NOT ECX
0040365A 2BF9 SUB EDI,ECX
0040365C 8BC1 MOV EAX,ECX
0040365E 8BF7 MOV ESI,EDI
00403660 8BFA MOV EDI,EDX
00403662 C1E9 02 SHR ECX,0x2
00403665 F3:A5 REP MOVS DWORD PTR ES:,DWORD PTR DS>
00403667 8BC8 MOV ECX,EAX
00403669 83E1 03 AND ECX,0x3
0040366C F3:A4 REP MOVS BYTE PTR ES:,BYTE PTR DS:[>
0040366E 8D4C24 34 LEA ECX,DWORD PTR SS:
00403672 E8 AB020000 CALL 00403922
00403677 8B7C24 14 MOV EDI,DWORD PTR SS:
0040367B 83C9 FF OR ECX,0xFFFFFFFF
0040367E 33C0 XOR EAX,EAX
00403680 8D9424 BC000000 LEA EDX,DWORD PTR SS:
00403687 F2:AE REPNE SCAS BYTE PTR ES:
00403689 F7D1 NOT ECX
0040368B 2BF9 SUB EDI,ECX
0040368D 8BF7 MOV ESI,EDI
0040368F 8BFA MOV EDI,EDX
00403691 8BD1 MOV EDX,ECX
00403693 83C9 FF OR ECX,0xFFFFFFFF
00403696 F2:AE REPNE SCAS BYTE PTR ES:
00403698 8BCA MOV ECX,EDX
0040369A 4F DEC EDI
0040369B C1E9 02 SHR ECX,0x2
0040369E F3:A5 REP MOVS DWORD PTR ES:,DWORD PTR DS>
004036A0 8BCA MOV ECX,EDX
004036A2 83E1 03 AND ECX,0x3
004036A5 F3:A4 REP MOVS BYTE PTR ES:,BYTE PTR DS:[>
004036A7 8D4C24 18 LEA ECX,DWORD PTR SS:
004036AB E8 F0DCFFFF CALL 004013A0
004036B0 8D8424 BC000000 LEA EAX,DWORD PTR SS:
004036B7 8D4C24 18 LEA ECX,DWORD PTR SS:
004036BB 50 PUSH EAX
004036BC C68424 2C010100>MOV BYTE PTR SS:,0x9
004036C4 E8 D7E8FFFF CALL 00401FA0; //将当前机器码加上随机数进行MD5运算
004036C9 50 PUSH EAX
004036CA 8D4C24 2C LEA ECX,DWORD PTR SS:
004036CE E8 55020000 CALL 00403928
004036D3 8B4C24 1C MOV ECX,DWORD PTR SS:
004036D7 8B5424 28 MOV EDX,DWORD PTR SS:
004036DB 51 PUSH ECX
004036DC 52 PUSH EDX
004036DD C68424 30010100>MOV BYTE PTR SS:,0xA
004036E5 E8 97E17F77 CALL msvcrt._mbscmp ; //比较当前机器码与服务端返回的机器码
004036EA 90 NOP
004036EB 83C4 08 ADD ESP,0x8
004036EE 85C0 TEST EAX,EAX
004036F0 75 39 JNZ SHORT 0040372B ; //如果相等 则成功
004036F2 8B4424 10 MOV EAX,DWORD PTR SS:
004036F6 C705 54544000 0>MOV DWORD PTR DS:,0x1
00403700 8B48 20 MOV ECX,DWORD PTR DS:
00403703 51 PUSH ECX
00403704 E8 E7F3FFFF CALL 00402AF0
至此,整个验证过程已经很清楚了。
程序发送 当前机器码+随机数 到服务端首先检查发送过来的机器码是否存在,不存在 服务端返回“未注册”,存在 服务端返回“有效时间:xxx分钟///机器码+随机数的MD5值”
下面来看VC6.0实现服务端的核心代码:CString RecvBuf;
CString Mac;
CString Rnd;
CString Str;
CString MD5;
CString ConStr="HTTP/1.1 200 OK\r\nDate: Sat, 11 May 2013 12:40:47 GMT\r\nServer: Microsoft-IIS/6.0\r\nContent-Length: 53\r\nContent-Type: text/html\r\nCache-control: private\r\n\r\n有效时间:-2663分钟///";
char *NoConstr="HTTP/1.1 200 OK\r\nDate: Sat, 11 May 2013 12:40:47 GMT\r\nServer: Microsoft-IIS/6.0\r\nContent-Length: 6\r\nContent-Type: text/html\r\nCache-control: private\r\n\r\n未注册";
CclientItem m_ClienItem=*(CclientItem*)pParam;
while(TRUE)
{
if (m_ClienItem.m_pMainWnd->SOCKET_Select(m_ClienItem.m_Socket))
{
CHAR szBuf={0};
int iRet=recv(m_ClienItem.m_Socket,(char*)szBuf,1024,0);
if (iRet>0)
{
RecvBuf=szBuf;
int MacStart=RecvBuf.Find("/disp1.asp?mac=");
MacStart = MacStart + strlen("/disp1.asp?mac=");
int MacEnd=RecvBuf.Find("&rnd=");
Mac=RecvBuf.Mid(MacStart,MacEnd-MacStart);//取出发送过来的数据中的机器码
MacEnd = MacEnd + strlen("&rnd=");
Rnd=RecvBuf.Mid(MacEnd,5);//取出随机数
Str= Mac + Rnd;//将机器码+随机数
MD5= MD5String(Str.GetBuffer(0));//进行MD5运算
ConStr = ConStr + MD5;//固定信息“有效时间:-2663分钟///” + MD5值
send(m_ClienItem.m_Socket,ConStr.GetBuffer(0),ConStr.GetLength(),NULL);///发送给客户端
}
else
{
break;
}
}
}
return 0;Patch机器码可以在各硬盘序列号连接好产生MD5值后:
附正版机器码:671fd8530c5d26154f385a7eb4c5ddb600402770|.8BB424 B40200>MOV ESI,DWORD PTR SS://此处EAX PATCH即可原程序+完整本地服务端VC6.0编译。XP测试通过:
BIN:
注意:源码中没有带转向处理,请手动添加HOSTS127.0.0.1 disk.zgpmsj.com 邦姐这次搞的很大。 没看懂是啥意思,过几天再来看,也许能学会 看了以后,想到我手头也有一款这样的软件.正好拿来试试学习下 {:301_993:}前排膜拜bang姐 前排膜拜 膜拜ING... 狄邦是Hook大师 怎么可能模拟一个服务器模拟不出来? 膜拜 棒棒 邦姐,原来大牛是位姐姐啊
页:
[1]
2