• 1470阅读
  • 2回复

[休闲灌水]科普下敲出大符文的方法....神棍级别! [复制链接]

上一主题 下一主题
离线新安洲
 
发帖
1163
金钱
5942
91币
0
信誉
0
资产
0 IST
在线时间
217 小时
注册时间
2011-03-09
最后登录
2012-09-25
只看楼主 倒序阅读 使用道具 楼主  发表于: 2012-04-03 11:34:30
敲石头的技术帖(再发)
结论:敲石头的结果在敲石头的游戏被创建的时候就已经确定了,其他因素不影响在该游戏敲石头的结果,例如你换别的BB来敲,结果也一样。 就像一个游戏被创建之后,游戏的地图就确定了,不管你进来几个人、杀什么BOSS都一样

原文是我发表在TTBN的,其实1.11b的代码和1.10的代码基本一样的。如果你没有汇编知识或者编程知识,那就还是不要看了

发这篇文章的目的,是证明 其他所谓的秘诀都是扯淡~

原文地址:
http://www.ttage.com/bbs/viewthread.php?tid=134863


这个不知道会不会被咔嚓掉,如果BB觉得不爽,就把它咔嚓掉吧。。。呵呵

我原来写的一篇文章,供有志者参考,不过需要较强的汇编语言知识。。。。。
文中需要反汇编工具IDA Pro。。。

老早就听说在Diablo2中使用了伪随机数来产生游戏行为的。今天在TTBN上听说有人能够在Rune Run中找到规律,能够敲出尽可能高的符文。有许多人骂他是神汉~~汗。。。。
有关Rune Run最后的敲石头,就是完成A4的第二个任务,将有一个符文的奖励,在地狱难度下面完成这个任务,可以获得15#~25#中的某个符文。网上大多研究表明,这个到底会得到那个符文,完全是随机的。。。
居然有人在此情形下,给出经验,说有把握能够敲到高级符文,怪不得变成人民公敌了。。

然后从理论的角度,由于D2里面是伪随机并不是真正的随机,因此完全有可能找到其规律,从而实现敲石头的时候,只出25#。

因此,我上网找了一下相关的资料,得到如下信息:
敲石头掉落的符文产生方法,是硬编码在d2game.dll中的。这个和别的物品掉落不一样,别的物品基本上都是由一个公共函数产生,几率由配置文件(MPG文件)决定。

下面说的都是在Diablo2 1.11(其实D2 1.10的代码基本一样),也就是TTBN的文件上进行分析的。

1、首先要找到d2game.dll中,与敲石头任务奖励相关的代码。这个很容易,在d2game.dll里面搜索r25,就看到了,引用这个数字的地方,就是相关的代码;
2、在相关的代码片断,其任务奖励过程是:首先产生完美宝石,然后产生无瑕疵的宝石,最后产生符文。
其中,完美宝石和无瑕疵的宝石产生极其类似,都是产生一个0~6的随机数,然后对应到相应的宝石即可。
3、符文的产生较为复杂。首先判断游戏难度,决定掉落的符文范围是多少?在普通难度,掉落的是1#~11#,而在噩梦难度,掉落的是12#~22#,地狱难度掉落的是15#~25#。
然后调用一个随机数函数,用于产生最终掉落符文的序号。最后根据这个序号产生对应的符文。
(见图) 
而最为感兴趣的自然就是其中的随机数函数RuneRandom了。。其代码如下:
.text:6FC21040 RuneRandom      proc near              ; CODE XREF: sub_6FC336B0+187p
.text:6FC21040                                        ; sub_6FC41C20+CCp ...
.text:6FC21040                push    esi
.text:6FC21041                mov    esi, eax        ; ESI=EAX=B
.text:6FC21043                test    esi, esi
.text:6FC21045                jg      short loc_6FC2104B
.text:6FC21047                xor    eax, eax
.text:6FC21049                pop    esi
.text:6FC2104A                retn
.text:6FC2104B ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:6FC2104B
.text:6FC2104B loc_6FC2104B:                          ; CODE XREF: RuneRandom+5j
.text:6FC2104B                mov    eax, [ecx]
.text:6FC2104D                push    ebx
.text:6FC2104E                push    edi
.text:6FC2104F                mov    edx, 6AC690C5h  ; 初始化随机数种子
.text:6FC21054                lea    edi, [esi-1]    ; lea edi,[A]
.text:6FC21057                mul    edx
.text:6FC21059                xor    ebx, ebx
.text:6FC2105B                test    edi, esi
.text:6FC2105D                jz      short loc_6FC21075
.text:6FC2105F                mov    edi, [ecx+4]
.text:6FC21062                add    eax, edi
.text:6FC21064                adc    edx, ebx
.text:6FC21066                mov    [ecx+4], edx
.text:6FC21069                mov    [ecx], eax
.text:6FC2106B                xor    edx, edx
.text:6FC2106D                div    esi              ; ESI = A = 10
.text:6FC2106F                pop    edi
.text:6FC21070                pop    ebx
.text:6FC21071                pop    esi
.text:6FC21072                mov    eax, edx
.text:6FC21074                retn
.text:6FC21075 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:6FC21075
.text:6FC21075 loc_6FC21075:                          ; CODE XREF: RuneRandom+1Dj
.text:6FC21075                mov    esi, eax        ; EDI=ESI
.text:6FC21077                mov    eax, [ecx+4]
.text:6FC2107A                add    esi, eax
.text:6FC2107C                mov    eax, edi
.text:6FC2107E                adc    edx, ebx
.text:6FC21080                pop    edi
.text:6FC21081                pop    ebx
.text:6FC21082                mov    [ecx], esi
.text:6FC21084                and    eax, esi
.text:6FC21086                mov    [ecx+4], edx
.text:6FC21089                pop    esi
.text:6FC2108A                retn
.text:6FC2108A RuneRandom      endp

可以看出,它使用的是一种典型的伪随机数产生算法,可以参考
http://www.luocong.com/articles/show_article.asp?Article_ID=24
简单的说,就是用如下公式产生:
Rand_Number = (Rand_Seed * X + Y) mod Z
其中Rand_Seed固定是6AC690C5h, 而Z固定是11
因此,决定最终随机数的只有X和Y。
不幸的是,X和Y并不能简单的推算出来。。。
它的XY大概的产生过程是:
1、貌似系统初始的时候,有一个XY,这个称为游戏种子,貌似是真随机的;
2、以后,每次使用随机数算法,将X更新为X*Rand_Seed + Y的高半部分;而Y更新为  X*Rand_Seed + Y的低半部分。相关算法如下:
      mov    eax, rand_h ; [ebp+0D0h]
      mov    ecx, 6AC690C5h
      mul    ecx
      mov    edi, eax
      mov    eax, rand_l ; [ebp+0D4h]
      xor    ecx, ecx
      add    edi, eax
      adc    edx, ecx
      mov    rand_l, edx ; [ebp+0D4h]
      mov    rand_h, edi ; [ebp+0D0h]

姑且将上述代码称为函数rand_step。
D2在最开始的时候首先生成随机数种子,然后使用这个种子不断的调用rand_step,每次调用,将更新这个随机数种子为一个新的值,然后D2再使用这个随机数去产生游戏行为,其中包括地图生成以及敲石头的结果(初始的种子经过数次rand_step之后,就是敲石头的结果了)。。。。
所以结论就是,在地图和敲石头结果之间存在联系,但目前联系还不清楚。有人说,下面的地图形状比较容易出高级RUNE,可能是有道理的( 我在单机上通过IDA Pro测试过一部分得到25#的地图,有许多地图和给出的地图形状基本一样)。

金钱条评分
乔巴 金钱 +2 代新人谢谢 2007-08-26
离线baominlee
发帖
4821
金钱
3873
91币
0
信誉
0
资产
0 IST
在线时间
2213 小时
注册时间
2009-10-18
最后登录
2013-10-12
只看该作者 沙发  发表于: 2012-04-03 21:50:03
不错,不过相当于没说
离线新安洲
发帖
1163
金钱
5942
91币
0
信誉
0
资产
0 IST
在线时间
217 小时
注册时间
2011-03-09
最后登录
2012-09-25
只看该作者 板凳  发表于: 2012-04-14 15:39:00
附上容易敲出25#的例图
快速回复
限100 字节
 
上一个 下一个