Rookietp 发表于 2013-5-13 11:20

分析并模拟某程序服务端

本帖最后由 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

Chief 发表于 2013-5-13 11:58

邦姐这次搞的很大。

maxrio 发表于 2013-5-13 14:07

没看懂是啥意思,过几天再来看,也许能学会

我是菜鸟 发表于 2013-5-13 16:17

看了以后,想到我手头也有一款这样的软件.正好拿来试试学习下

a070458 发表于 2013-5-13 16:57

{:301_993:}前排膜拜bang姐

夏日 发表于 2013-5-13 18:02

前排膜拜

SxAni丶 发表于 2013-5-13 19:15

膜拜ING...

1354669803 发表于 2013-5-14 12:00

狄邦是Hook大师 怎么可能模拟一个服务器模拟不出来?

吾爱丶小末 发表于 2013-5-14 22:25

膜拜 棒棒

yangenwei 发表于 2013-5-27 18:44

邦姐,原来大牛是位姐姐啊
页: [1] 2
查看完整版本: 分析并模拟某程序服务端