|
|

打开一个存档,地址80h处,文本04RP~74RP之间,有4个字节;一目了然。例如F8 FF 7F 4B
这就是古剑游戏时间的存档纪录数据,读档后由高到低调入内存为16进制4字节型数值;即4B7FFFF8
以下简称为内存数值,先来个简单的初始分析,没花我太多时间,这边改那边就实时看了,很容易找到
规律:内存数值每增加800000的一倍,时间变成2^N(N随着增加1)这些特殊值称为节点,我们还需比率
大于 内存数值 时的 比率(16进制:秒) 游戏时间(秒)
小等 3F 7F FF FF 看下文分析 .....0秒
大等 3F 80 00 00 00 80 00 00:1 01 .....1秒
大于 40 00 00 00 00 40 00 00:1 02
大于 40 80 00 00 00 20 00 00:1 04
大于 41 00 00 00 00 10 00 00:1 08
大于 41 80 00 00 00 08 00 00:1 16
大于 42 00 00 00 00 04 00 00:1 32
大于 42 80 00 00 00 02 00 00:1 64
大于 43 00 00 00 00 01 00 00:1 128
大于 43 80 00 00 00 00 80 00:1 256
大于 44 00 00 00 00 00 40 00:1 512
大于 44 80 00 00 00 00 20 00:1 1024 .......约17分钟
总结到这里。以下全是准确的预测(因为我验证了其中几个):
大于 45 00 00 00 00 00 10 00:1 2048
大于 45 80 00 00 00 00 08 00:1 4096
大于 46 00 00 00 00 00 04 00:1 8192
大于 46 80 00 00 00 00 02 00:1 16384
大于 47 00 00 00 00 00 01 00:1 32768
大于 47 80 00 00 00 00 00 80:1 65536
大于 48 00 00 00 00 00 00 40:1 131072 .....约36小时
大于 48 80 00 00 00 00 00 20:1 262144
大于 49 00 00 00 00 00 00 10:1 524288
大于 49 80 00 00 00 00 00 08:1 1048576
大于 4A 00 00 00 00 00 00 04:1 2097152
大于 4A 80 00 00 00 00 00 02:1 4194304
大于 4B 00 00 00 00 00 00 01:1 8388608
大于 4B 80 00 00 00 00 00 01:2 16777216 .....4660小时20分16秒 神奇初现:游戏界面时间秒针每次+2
大于 4C 00 00 00 00 00 00 01:4 33554432
大于 4C 80 00 00 00 00 00 01:8 67108864
大于 4D 00 00 00 00 00 00 01:16 134217728
大于 4D 80 00 00 00 00 00 01:32 268435456
大于 4E 00 00 00 00 00 00 01:64 536870912
大于 4E 80 00 00 00 00 00 01:128 1073741824 .....68年35天3小时12分钟,于是时间秒针每次+128
小等 4E FF FF FF 00 00 00 01:128 (2147483648-128)
大等 4F 00 00 00 ????????? .....是个秘密,现在不说,请往下看
下面通过数学分析找出其中的函数
设内存数值为X。以下出现的小写字母后缀,h 代表该数值为十六进制,d 代表该数值为十进制
令常数 L = 3F800000 h = 1065353216 d
令常数 C = 00800000 h = 8388608 d
加入2个中转值Y=X-L,K=[Y/C];则数值与时间比率V=C/(2^K)
K=[Y/C] ........[ ]是取整运算符号,以下同
V=C/(2^K)........ ^ 是乘方运算符号,以下同

变换节点数值Y 比率V(16进制:1秒) 时间T(秒)
00 00 00 00 C/(2^K) 2^00
00 80 00 00 C/(2^K) 2^01
01 00 00 00 C/(2^K) 2^02
01 80 00 00 C/(2^K) 2^03
02 00 00 00 C/(2^K) 2^04
02 80 00 00 C/(2^K) 2^05
03 00 00 00 C/(2^K) 2^06
03 80 00 00 C/(2^K) 2^07
04 00 00 00 C/(2^K) 2^08
04 80 00 00 C/(2^K) 2^09
05 00 00 00 C/(2^K) 2^0A
再次简化
大于 Y 时的 比率 对应的 时间
K*C C/(2^K) 2^K
K*C C/(2^K) 2^K
K*C C/(2^K) 2^K
K*C C/(2^K) 2^K
K*C C/(2^K) 2^K
K*C C/(2^K) 2^K
K*C C/(2^K) 2^K
K*C C/(2^K) 2^K
K*C C/(2^K) 2^K
K*C C/(2^K) 2^K
K*C C/(2^K) 2^K
很明显 时间等于节点值+变换数值减去对应节点除以比率
即 T = 2^K+[(Y-KC)/V] = 2^[Y/C]+[(Y-[Y/C]C)/(C/(2^K))]
= 2^[(X-L)/C]+[((X-L)-[(X-L)/C]C)/(C/(2^[(X-L)/C]))]
或 = 2^[(X-L)/C]+[((X-L)-[(X-L)/C]C)*(2^[(X-L)/C])/C] ....单位为秒,转成h/m/s格式小学生都会了。

实例操作:假设写入内存数值为49A076C0,让我们来计算这代表什么游戏时间:
X=49A076C0,Y=X-L=A2076C0,K=[Y/C]=14;则比率V=C/(2^K)=8,代入公式得:
T = 2^K+[(Y-KC)/V] = 2^14+[(A2076C0-14*800000)/8] =140ED8 (这里出现的所有数值我都用16进制)
T=140ED8 h =1314520 秒(十进制)。嘿,巧了,蛮有爱的时间。古剑会显示成365小时08分40秒。
这是知道内存数值求时间的算法,那么想改成指定游戏时间怎么计算数值呢?
虽然取整操作不存在逆运算,但原理已搞清,就更简单了。
先计算游戏时间T以2为底的对数并取整,设为 K =[log(2)(T)] ;则余值 E=T-2^K;比率 V=C/(2^K),那么
内存数值就等于 变换节点数值+余值×比率+L

X = Y+L = CK+EV+L = C*[log(2)(T)]+(T-2^K)C/(2^K)+L
= C*[log(2)(T)]+TC/(2^[log(2)(T)])-C+L
或 = C*[log(2)(T)]+TC/(2^[log(2)(T)])+3F000000

实例操作:假设你想改成游戏时间为1989小时06分04秒,即T=7160764=6D43BC h,计算需要写入什么数值
则K=[log(2)(T)]=22d=16 h(T先用10进制,因16进制下普通计算器难以计算log值,计算结果22转成十六进制,即K=16)
E = T-2^K = 6D43BC-2^16 = 2D43BC
V = C/(2^K) = 2 代入公式得:
X = Y+L = CK+EV+L =800000*16+2D43BC*2+3F800000 = 4ADA8778
直接在内存里写入该数值即可使游戏时间变成1989:06:04 若是在存档中修改需要反过来哦 即 78 87 DA 4A
是不是更简单了,虽说如此,这也是建立在上个函数深入分析的基础上。
你用十进制也好,十六进制也好,都可以使用上述公式。但大家试验时最好用16进制,计算器会自动取整
但切忌二种进制不经转换直接运算!
下面我们来分析比率V:
比率V=C/(2^K)=800000/2^([Y/800000]-1)
因为当X≥4B800000;Y≥C000000;[Y/800000]≥18;2^([Y/800000]-1)≥2^18=1000000,V≤1/2

所以从这里开始分母大于分子,V开始小于1;又由于[Y/800000]是个整数,[Y/800000]每增加1
分母就增加2的1次方,V开始变成1:2、1:4....1:128了。由于内存地址数值每次只能±1,那么时间
就只能加减1/V了,即每2、4.....128秒显示一次的由来。由于32位操作系统所能表示的最大整型常量
是2^32÷2-1,即-2147483648~2147483647,故时间最大是2147483647秒(即2^31-1秒
= 596523:12:00)于是44E FF FF FF 是时间终点 596523:12:00,也即68年35天3小时12分钟
调成 4E FF FF FF,耐心等待1分多钟,就是激动人心的时刻:
再大溢出了,画面定格在-596523:-357 内存定格在4F 00 00 2B,骂谁呢,斯爱弗你过来?
下面再来分析X小于3F7FFFFF时T的取值情况:
0≤X≤3F7FFFFF
-3F800000≤Y≤-1
[-3F800000/800000]≤K≤[-1/800000]
-7F≤K≤-1
设K的绝对值为J,则1≤J=|K|≤7F
V=C/(2^K)=C*2^J
1000000≤V≤+∞
T = 2^K+[(Y-KC)/V] ≤ 0.5 + [(Y-KC)/V]
因为0≤T、[(Y-KC)/V] 都为整,欲证明 T = 0 只需证明 T≤0.5 即(Y-KC)/V<1
即Y-KC<V , 即Y<V + KC,即Y<V - J*C=C*2^J - J*C=(2^J-J)C
1≤J;1≤(2^J-J);C≤(2^J-J)C
Y≤-1<C≤(2^J-J)C
证明完毕[em23]
好吧,完成了分析帝的任务了,以后你的完美修改器感谢名单要有我哦(MS我爆料了)[em09]
下面附带每2秒刷新一次的时间,读档后立即进入菜单界面,等待12秒后有惊奇哦
我承认这张图偷懒PS了一部分,但你不会否认我能做到除67外的所有值吧⊙﹏⊙b
12秒后时间跳跃.rar
(22.08 KB, 下载次数: 27)

附:内存修改方法:第一步当然是找地址了,因为不固定,那么我们可以给它先,设定一个
每128秒刷新一次的内存值,例如:4EFFFFF0 还有,在存档偏移地址越靠前的在内存里
也是哦,在这里扫描00000000~0FFFFFFF就行了,很简单,只有一个结果,看图说话吧:

|
|