首页
社区
课程
招聘
[讨论]一个菜鸟与网络服务器认证软件的斗争过程
发表于: 2007-11-25 19:27 123328

[讨论]一个菜鸟与网络服务器认证软件的斗争过程

2007-11-25 19:27
123328
收藏
免费 0
支持
分享
最新回复 (287)
雪    币: 189
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
251
出来了一个

据说是破解版的   

但是,不是最新版

估计用不了

我还没试呢

我还是先试试你的方法

毕竟 这个方法只要有新版本

就可以破了用
2008-2-18 10:00
0
雪    币: 189
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
252
报告!

还是不行
2008-2-18 11:49
0
雪    币: 189
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
253
报告 还是不行
2008-2-18 12:05
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
254
不要着急, 我只会在晚上出现.  

我这里分析的结果是这个程序每隔15000(毫秒?)会向外部服务器发送HTTP请求, 服务器的域名有四个:
http://www.xiwangwg.com
http://www.game-tool.com
http://www.game-exp.com
http://www.game-club.com.hk

请求的URL有两种格式:
/Reg/Member/Check3.asp?A=xxx&L=xxx&B=xxx&G=xxx&V=xxx
/Reg/Member/Check3.asp?A=xxx&L=xxx&I=xxx&G=xxx&V=xxx

合起来完整的URL类似这样
http://www.xiwangwg.com/Reg/Member/Check3.asp?A=xxx&L=xxx&B=xxx&G=xxx&V=xxx

所以应该可以确认是认证是否是注册用户的请求包. 

每一轮请求最多重试三次, 三次不成功则等下一个15000后再试. 我让你把15000这个数改大目的是把这个发包的间隔加大. 这样还不行的话, 说明程序里还有地方另外判断时间.

你再试试看: 1. 能不能抓到这类包; 2. 把数值改大后发包的时间间隔是否也相应加大.

我自己会再看看这个函数设置了什么标志.

还有, 现在那个网站上又更新了版本, 你打算继续用0124还是0215? 我要选一个来处理, 要不然对不上号.
2008-2-18 22:47
0
雪    币: 189
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
255
实在是太感谢了

用最新的  要不然在游戏里出错了都不知道是

版本不符合出错还是  没改好出错

这个游戏有NP  抓包的软件一打开 游戏就自动关闭了 `

高手终于出现了 !!!
2008-2-19 00:33
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
apk
256
--------------------------------------------------------------------------------
我没有那么多电脑啊  555555````

我现在的思路就是把试用30分钟改为无限时间

但是我找不到那个30分钟了`````
2008-2-19 01:35
0
雪    币: 189
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
257
如果你也同意

那么就请顶一下这个帖子

为反台独尽一份力
2008-2-19 12:38
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
258
还是先讲解一下我的思路吧. 原来我担心先把思路讲出来可能会误导你们, 所以打算在确认方案可行后再详细说明, 不过现在看来有必要先介绍一下, 以方便有条件的同学跟进详细研究.

根据先前的各贴说明, 这个程序用到了网络认证, 那么肯定会有网络通讯模块, 也应该会用到与网络相关的API, 所以要先找出哪个程序用到了与网络相关的API

用Total Commander的FileInfo逐一检查(用有类似功能其他的工具也行), 发现只有DS.DLL里用了WinINet.DLL和WSock32.DLL, 网络通讯模块肯定是在这个DLL中.

用IDA打开DS.DLL(本文以0215版本为例), 等IDA分析完, 直接在Import里找从WinINet.DLL(这个API的封装比WSock32.DLL的高级)里的导入函数:
  .idata:10021344 ;
  .idata:10021344 ; Imports from WININET.dll
  .idata:10021344 ;
  .idata:10021344  extrn InternetCloseHandle:dword
  .idata:10021344                          ; CODE XREF: sub_1000BAC0+17C
  .idata:10021344                          ; sub_1000BAC0+240
  .idata:10021344                          ; sub_1000BAC0+243
  .idata:10021348  extrn InternetOpenUrlA:dword
  .idata:10021348                          ; CODE XREF: sub_1000BAC0+16F
  .idata:1002134C  extrn InternetCanonicalizeUrlA:dword
  .idata:1002134C                          ; CODE XREF: sub_1000BAC0+158
  .idata:10021350  extrn InternetGetConnectedState:dword
  .idata:10021350                          ; CODE XREF: sub_1000BAC0+4E
  .idata:10021354  extrn InternetOpenA:dword
  .idata:10021354                          ; CODE XREF: sub_1000BAC0+A0
  .idata:10021354                          ; sub_1000BAC0+B5
  .idata:10021358  extrn InternetReadFile:dword
  .idata:10021358                          ; CODE XREF: sub_1000BAC0+1C3
  .idata:10021358                          ; sub_1000BAC0+22F
真运气, 居然有这么高级的API调用, 而且都在同一个函数.....
别客气, 直接跳到sub_1000BAC0

对这个函数没必要详细分析, 有兴趣自己慢慢看, 总之, 这是一个完整的连接/请求/接收/关闭的HTTPIO过程, 所以我先把它命名成HTTPIO.

既然sub_1000BAC0只是个HTTPIO, 那确切的URL和内容处理肯定都在调用者那边, 因此我们关心的是谁调用它.
  .text:1000BAC0  HTTPIO proc near   ; CODE XREF: StartAddress+6D
  .text:1000BAC0                     ; .text:1000C35C
  .text:1000BAC0                     ; sub_1000CCA0+E9
  .text:1000BAC0                     ; sub_1000CCA0+456
有四个函数, 其中sub_1000CCA0调用两次, 那就先看看它吧
  .text:1000CD7A  push    edx
  .text:1000CD7B  push    ecx
  .text:1000CD7C  push    ecx
  .text:1000CD7D  mov     ecx, esp
  .text:1000CD7F  mov     [esp+0D3Ch+var_D1C], esp
  .text:1000CD83  push    eax             ; Src
  .text:1000CD84  call    sub_1001A2CE
  .text:1000CD89  call    HTTPIO
  .text:1000CD8E  add     esp, 0Ch
  .text:1000CD91  xor     edx, edx
  .text:1000CD93  cmp     al, 1
  .text:1000CD95  setz    dl
  .text:1000CD98  mov     eax, edx
  .text:1000CD9A  pop     edi
  .text:1000CD9B  pop     esi
  .text:1000CD9C  pop     ebp
  .text:1000CD9D  pop     ebx
  .text:1000CD9E  add     esp, 0D20h
  .text:1000CDA4  retn
看起来不象有什么价值的东西, 再看另一处
  .text:1000D0E3  push    0BB8h
  .text:1000D0E8  push    ecx
  .text:1000D0E9  push    ecx
  .text:1000D0EA  mov     ecx, esp
  .text:1000D0EC  mov     [esp+0D3Ch+var_D14], esp
  .text:1000D0F0  push    edx             ; Src
  .text:1000D0F1  call    sub_1001A2CE
  .text:1000D0F6  call    HTTPIO
  .text:1000D0FB  add     esp, 0Ch
  .text:1000D0FE  cmp     al, 1
  .text:1000D100  jnz     loc_1000D3DF
  .text:1000D106  lea     eax, [esp+0D30h+Str]
  .text:1000D10D  push    offset SubStr   ; "DB ERROR"
  .text:1000D112  push    eax             ; Str
  .text:1000D113  call    _strstr
等等, DB ERROR? 有点门路, 上下左右随便看一下(这个看和下面的翻都是指用PgUp/PgDn上下浏览附近的代码)
  .text:1000CFE8  mov     edi, offset aI  ; "&I="
  .text:1000D048  mov     edi, offset aG  ; "&G="
  .text:1000D090  mov     edi, offset aV  ; "&V="
Hmmmm.... 我好象已经闻到了什么, 继续翻
  .text:1000CDE8  mov     ecx, [esp+0D30h+arg_C]
  .text:1000CDEF  mov     edx, [esp+0D30h+var_D18]
  .text:1000CDF3  push    ecx
  .text:1000CDF4  push    ebx
  .text:1000CDF5  lea     eax, [esp+0D38h+var_D10]
  .text:1000CDF9  push    edx
  .text:1000CDFA  push    eax
  .text:1000CDFB  call    sub_1000C7B0
  .text:1000CE00  mov     eax, [esp+0D40h+arg_C]
  .text:1000CE07  add     esp, 10h
  .text:1000CE0A  cmp     eax, 3
  .text:1000CE0D  lea     edx, [esp+0D30h+var_D10]
  .text:1000CE11  mov     edi, offset a?a ; "?A="
源头好象在这, 到sub_1000C7B0里看一下
  .text:1000C7D7  mov     edi, offset aHt ; "ht"
  .text:1000C807  mov     edi, offset aTpW ; "tp://w"
  .text:1000C82F  mov     edi, offset aWw_g ; "ww.g"
  .text:1000C854  mov     edi, offset aAme ; "ame-"
  .text:1000C87C  mov     edi, offset aClub_co ; "club.co"
  .text:1000C8A4  mov     edi, offset aM_hk ; "m.hk/"
呵呵, 现在知道 http://www.game-club.com.hk 是怎么来的了吧, 原来被化整为零了, 运行时才组装起来的啊.

对sub_1000C7B0也不再详细说明了, 大家不要对里面的一堆repne scasb/movsb吓倒, 其实那只是个inline展开后的strcat, 整个函数就是根据某个参数(大概是用户的分类吧)的值来决定去哪个Site做认证.
sub_1000C7B0返回的认证的URL最终是会是这个样子:
  http://www.xiwangwg.com/Reg/Member/Check3.asp
调用返回到1000CE00后再根据同一个参数决定是加上
  ?A=xxx&L=xxx&B=xxx&G=xxx&V=xxx
还是
  ?A=xxx&L=xxx&I=xxx&G=xxx&V=xxx
合起来就是
  http://www.xiwangwg.com/Reg/Member/Check3.asp?A=xxx&L=xxx&B=xxx&G=xxx&V=xxx

OK, 回到调用HTTPIO的地方, 刚才我们已经看到了, 
  .text:1000D0F6  call    HTTPIO
  .text:1000D0FB  add     esp, 0Ch
  .text:1000D0FE  cmp     al, 1
  .text:1000D100  jnz     loc_1000D3DF
也就是说, 如果HTTPIO出错, 则跳到loc_1000D3DF
  .text:1000D3DF  mov     eax, [esp+0D30h+var_D18]
  .text:1000D3E3  inc     eax
  .text:1000D3E4  cmp     eax, 3
  .text:1000D3E7  mov     [esp+0D30h+var_D18], eax
  .text:1000D3EB  jle     loc_1000CDE8
再去看看loc_1000CDE8
  .text:1000CDE0  mov     [esp+0D30h+var_D18], 1
  .text:1000CDE8 loc_1000CDE8:                           ; CODE XREF: sub_1000CCA0+74B
  .text:1000CDE8  mov     ecx, [esp+0D30h+arg_C]
我不知道你明不明白, 但我肯定看得出来, 这其实就是
  for(i = 1, i <= 3; i ++)  /// i = esp+0D30h+var_D18
很显然, 这个请求会重试三次, 如果都不成功
  .text:1000D3F1  mov     edx, ds:dword_100363EC
  .text:1000D3F7  mov     eax, [esp+0D30h+var_D1C]
  .text:1000D3FB  add     edx, 15000
  .text:1000D401  mov     ds:dword_10146D40, edx
  .text:1000D407  pop     edi
  .text:1000D408  pop     esi
  .text:1000D409  pop     ebp
  .text:1000D40A  pop     ebx
  .text:1000D40B  add     esp, 0D20h
  .text:1000D411  retn
显然直接就返回了.

等等, 这是什么?
  dword_10146D40 = dword_100363EC + 15000 ?!
dword_10146D40和dword_100363EC好象在哪见过? 赶快到处翻
  .text:1000CDA5  mov     eax, ds:dword_100363EC       
  .text:1000CDAA  mov     ecx, ds:dword_10146D40       
  .text:1000CDB0  cmp     eax, ecx                     
  .text:1000CDB2  jb      loc_1000D412                 
  .text:1000CDB8  cmp     ds:dword_1013FCBC, 0C8h      
  .text:1000CDC2  jge     loc_1000D412                 
  .text:1000CDC8  mov     ebp, [esp+0D30h+arg_14]      
  .text:1000CDCF  mov     ebx, [esp+0D30h+arg_8]       
  .text:1000CDD6  mov     ds:dword_10146D40, 0FFFFFFFFh
看明白什么意思了吗?
如果 dword_100363EC < dword_10146D40, 则去到loc_1000D412
  .text:1000D412  pop     edi
  .text:1000D413  pop     esi
  .text:1000D414  pop     ebp
  .text:1000D415  xor     eax, eax
  .text:1000D417  pop     ebx
  .text:1000D418  add     esp, 0D20h
  .text:1000D41E  retn
显然是返回0

也就是说, 1000CDA5到1000D41E这段代码相当于:
  if( dword_100363EC < dword_10146D40 )
    return 0;
  for( i=0; i <= 3; i ++)
     HTTPIO的相关处理
  dword_10146D40 = dword_100363EC + 15000
  return [esp+0D30h+var_D1C]

dword_100363EC是什么内容呢? 我可以先告诉大家, 这个值就是系统的TickCount(至于具体分析我下回再讲), 那么dword_10146D40的意义就很明显了.
到此为止, 我们应该确认已经找到了网络认证部分以及认证的方式和频度.

  .text:1000D106  lea     eax, [esp+0D30h+Str]
  .text:1000D10D  push    offset SubStr   ; "DB ERROR"
  .text:1000D112  push    eax             ; Str
  .text:1000D113  call    _strstr
从这里开始就是对认证的结果进行处理的部分, 大家先自行分析一下, 我明天有事不上来, 后天再跟大家继续交流.

TIPS:
  .text:1000CDB8  cmp     ds:dword_1013FCBC, 0C8h      
  .text:1000CDC2  jge     loc_1000D412                 
从这里可以看到, 如果dword_1013FCBC >= 200 也会跑到loc_1000D412, 如果不想研究认证结果的处理, 不妨研究一下dword_1013FCBC到底起了什么作用.

谢谢您的捧场.
2008-2-19 23:08
0
雪    币: 200
活跃值: (245)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
259
大家新年快乐
高手其实一直在这里游荡......
去看了下网站,是个成熟的外挂研发小组做的.
看了下ARAB的研究报告,关注域名加密方式,可以看出是个老手,加上楼主首贴所说的VC不加壳,说明外挂编写者竟不屑于加壳,看来至少存在几十个甚至上百个暗桩......可能还不止......
我服了编挂挂的土人了......
其实他们也是这里的常客.......
2008-2-19 23:31
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
260
恭喜LZ了,问题解决。
ps:  LZ毅力好强
2008-2-20 16:47
0
雪    币: 189
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
261
请问你所说的效果是什么?
2008-2-20 20:55
0
雪    币: 189
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
262
我照你250楼的改了

不行啊

到了30分钟还是不动了

也不打了
2008-2-20 22:01
0
雪    币: 200
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
263
呵呵快一个月了还没搞定啊。空了帮你看下
2008-2-21 17:02
0
雪    币: 189
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
264
谢谢  十分感谢
2008-2-21 19:16
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
265
忘记了你对汇编还不太熟悉.

250楼的修改方案的思路是: 如果它的计时器是根据这个发认证包的频率来计算的话, 把发认证包的频率加大, 则计时器更新的时间自然也加大, 从而达到延长使用时间的效果. 另外, 这个修改是针对0124版本的.
既然你已经试过没有效果, 说明时间限制另有一个计时器, 我们得另试其他办法.
2008-2-21 20:56
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
266
我们前面已经知道了, 认证包是类似这样的一个URL
  http://www.xiwangwg.com/Reg/Member/Check3.asp?A=xxx&L=xxx&B=xxx&G=xxx&V=xxx
那么服务器的返回是怎么样的呢? 实时不能抓包, 但并不等于不能直接访问, 我们在IE的URL输入试试
  http://www.xiwangwg.com/Reg/Member/Check3.asp?A=game&L=vip&B=1121&G=sasa&V=1113
OK, IE返回了这样的内容:
  ==2006/01/01 12:00:01,5,1,583
就是说, 无效的账号认证的结果是这个样子的, 接下来, 我们从前面找到的认证处理部分开始跟下去
  .text:1000D106  lea     eax, [esp+0D30h+Str]
  .text:1000D10D  push    offset SubStr   ; "DB ERROR"
  .text:1000D112  push    eax             ; Str
  .text:1000D113  call    _strstr
处理的流程我就不详细说了, 现在知道的是, 程序使用了一种0x90(144)字节的数据结构, 共0xC8(200)个, 前面提到的dword_1013FCBC是已经使用了其中的多少个(所以超过200个就不再发请求).
每次认证服务器返回的数据会存放在这个结构中(可以是以前发过的数据, 数据结构中有一个字节是用来做标识的), 处理的流程只负责将服务器返回的数据填到这个数据结构中, 而对这些数据的处理是在DLL之外进行的.  
所以, 从网络通讯模块入手的路被堵死了. 
等周末我再看看有没有其他路子可行吧.
2008-2-21 22:48
0
雪    币: 189
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
267
辛苦您了

高手高手

热心的高手啊
2008-2-22 21:35
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
268
个高手!厉害啊/////////
2008-2-23 08:10
0
雪    币: 189
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
269
这个即使不请求的时间大于30分钟

这个程序也会在30分钟时部分功能停止

请求 我不清楚频度是多少

按开始时一次   运行时也请求吗?
2008-2-23 10:51
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
270
有点不懂。。
2008-2-23 21:35
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
271
再试这样修改:
在(0215版的)DS.DLL里找 C1 E0 03 3B C8 , 只有一处(在0xD1DB), 把 03 修改成 13, 看看能否延长使用时间.
2008-2-24 21:31
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
272
我再解释一下我的思路吧.
基本的想法跟你是一样的, 就是说要解除这30分钟的限制, 只不过你是从定时器入手, 我是从网络认证入手.

一开始, 我发现它会定时向认证服务器发认证请求, 于是猜想是否当认证请求失败的次数累计到一定程度时程序会退出, 这样的话, 请求失败的总次数就是限制值, 那么如果我改了它发包的频率, 在总数不变的情况下, 频率间隔越大, 达到总数的时间就越长, 无形中也就延长了使用的时间. 我已经找到发包的频率值并让你修改进行测试, 这就是250楼提到的地方. 你的测试结果表明, 这个猜想是错的.

接下来, 我想能否简单的通过修改认证返回的结果把非注册用户当成注册用户, 但分析认证处理部分后发现, 它只负责将服务器返回的数据填到某个数据结构中, 而对这些数据的处理是在DLL之外进行的, 这样即使能骗过程序说当前用户是注册用户, 但后来程序要使用那些数据时还是会出错, 因此我在266楼说, 此路不通.

至于271楼的修改办法, 灵感来源于对认证处理部分的分析. 266楼里提到认证服务器返回的包是这个样子的
  ==2006/01/01 12:00:01,5,1,583
其中第一个逗号后面的数字(5)要先乘上1000后才跟当前的TickCount进行运算比较, 然后再存到数据结构中, 因此我猜想这个数的单位一定是秒, 那么把这个数字加大后会有什么效果呢? 那要你测试过才能知道.

在266楼最后说: "从网络通讯模块入手的路被堵死了", 其实并非完全堵死, 只不过当前的条件下确是被堵死了.

如果我们有条件, 能够抓到程序向认证服务器发送的具体认证请求和服务器实际返回的认证数据, 通过分析, 应该还是可以找出一点线索的. 所以, 接下来的问题就是: 我们能否抓到这些认证用的数据包?

其实答案应该是肯定的, 既然我们已经知道它的认证部分使用的是HTTP协议, 那么Sniffer一下就可以解决问题; 可惜你的条件不允许使用Sniffer.
那么变通一下, 既然知道它是通过InternetOpenUrlA发请求, InternetReadFile取数据, 那么用个Hook把这两个函数接管一下或许行得通(希望NP不会监视这么偏门的API).
如果还是行不通, 那干脆直接在HTTPIO上挂个Hook. 反正目的就是为了抓包.

总之, 在当前的条件下, 除非271楼的办法成功, 或者你能抓到程序与认证服务器间的通讯包, 否则的话我只能帮你帮到这个程度了.
2008-2-24 21:49
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
273
我也在玩这个游戏,,,
2008-2-26 17:22
0
雪    币: 189
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
274
抱歉

这几天失恋了

情绪很低落 ``

对不起大家的热情```

谢谢大家

我会尽快测试
2008-3-2 00:55
0
雪    币: 29
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
275
你用 qq的截图功能  可以截图 然后另存为。。。。保存, 保存的图片可以发上来

我也在关注这个软件, 帮顶,有结果 告知一下
2011-10-3 09:15
0
游客
登录 | 注册 方可回帖
返回
//