|
本帖最后由 银河漫步 于 2011-9-30 23:11 编辑
4 i- A6 c9 _: e# s: l4 I4 j: z) ?8 S+ t5 t2 n
基地址的查找与特征数据
# M4 E3 ]' r) A- S# E; L9 S: @1 {(指针部分的使用说明在二楼,对基地址没兴趣的可跳过)0 n4 D. P4 A# E' V c; S1 ~
5 F' N4 W( C- N0 y7 k# U {5 Q# n ~
所谓基地址其实就是指针,其用法和指针的用法几乎相同,但是只所以区别开来还是因为模拟器这种东西,每次模拟游戏时游戏里的数据都是相对于某一个地址的偏移地址,所以与其每次都取写这个指针,不如把这个地址记录下来作为这个模拟器的基地址,则可以在做相同模拟器的游戏的时候方便很多
4 {6 f8 l% N! f1 P5 u2 L 指针怎么查找?CM其实目前没有反汇编的功能,所以关于指针的查找还是建议使用CheatEngine或者OllyDBG,我个人推荐前者$ b2 n' \8 a# h. _( h
CheatEngine简称CE,这软件功能十分强大,但是直到6.0版本,对于修改器界面的设计始终功能比较简单,无法做出比较随心所欲的修改器,而纯粹以编程的方式去处理修改器界面则门槛相对较高,所以也有了CheatMaker这一类的中间软件层的存在,所以就笔者我而言,是属于用CE寻址,然后用CM实现界面设计的这一类人(另一说,CE 6.1的版本已经可以推出了比较好的修改器设计功能,但是到目前为止笔者尚未研究出头绪…)+ Q; S6 S8 w8 _/ x. B
9 @0 u- ~- H. k6 m4 x& q
以SFC模拟器:Snex9X为例子,模拟器版本Ver 1.52,游戏三国志III,如下图查找金钱+ D3 o T7 t& z6 O) O3 [$ y0 `( i
9 C! c+ @" J* N, t
) m5 y4 n- h/ N' ~7 `7 s+ y4 y4 L0 z7 g
得到了唯一地址:013BF460
$ g% Q3 i, i' m0 `8 T3 R4 f/ h
! ?7 B7 Y2 \2 P+ V3 K( g. ~' I5 R. r/ ?% I# L3 Q( R; |
3 m! H% e" {, c
然后对这个数据跟踪,得到一个可能的地址指针值,注意这个地址指针值的013BCBA0是对应ESI的值,而EBX的值是28C0,这个是指的平原金钱的偏移地址0 {$ ?% R# V' N$ Y, A, `% @
值得注意的是[ebx+esi]的模式esi通常将不是固定值,这种时候,指针的好处就特别明显了,因为每次用模拟器模拟同一个游戏,对应的数据的搜索的绝对地址往往都在变动5 i4 A, k {7 A0 W' x" V
但是相对esi的ebx的偏移地址则是固定的
; ?6 B7 r, i8 B9 X" `! N; w
8 ~, B( [6 W/ c" O, ^0 U' k& g% j3 J% J1 ^( i( \ v/ ^9 A
1 z; u1 C1 N8 r6 c% L, c L
直接搜索相关这个地址的内容可以得到以下结果/ r6 }) Y6 U2 h
, V) A& P& ]6 w- ^( v- @- d
- M1 A5 q- A& H7 P6 p% M I+ o1 L0 a" P5 q! L$ O: e6 _1 O: V) P
如果得到的结果很多需要做一些进一步的测试和跟踪, 其实这里搜索到的这些都可以作为这个版本模拟器的基地址,比如任意选择一个0076448C: f5 u$ k6 c9 n! s; O
/ l( K' y9 J* s& y ^. Y8 i1 p7 L N! J/ L
7 |: K( C/ m9 _" w: `7 C% h+ o我们可以看到,指针指向的地址的数据已经和原地址数据一致了 ,这里的28C0是之前的ebx的值,就是刚才平原城金钱的相对偏移地址6 r2 S: x% z. {7 T0 f8 Y! U' q( l
那么我们把这个指针添加到CM的支持程序管理
; c+ d0 [! l$ O1 H' ]8 S- O% C; I+ c! Y$ S5 l' T+ ^
7 q5 T* w* M% i8 L3 @: F
6 w' B% u6 W+ \! a: H4 `; X
8 \/ q5 l7 u/ r
这里的最大偏移量是指的相对于这个基地址所指向的地址,最大允许的偏移量是多少,SFC游戏几乎不会超过20000,但其实这里填0表示不限制,也没有关系( `) ?# Z+ C$ D0 Q }
添加完毕后,我在CM里搜索平原城的金钱地址得到如下图片
) p$ U0 c, ^+ l; R' s W4 Q2 b
/ t% s: u( \( j& U1 I# A% ]& ^1 M* U- u9 B" W# G% h9 M4 N7 W' D
2 s/ D' r5 e+ }/ T
这个时候,对应的CM地址等于了原来的ebx的值,即这个金钱地址的相对偏移地址,我们的基地址添加成功了
5 o( |. q- D/ L/ W; l; y: t
( ~8 l- @5 c& v: m; E但是这么添加基地址,仅仅只是支持了Snes9X Ver 1.52版,如果用户换了一个版本的模拟器,则将出现不支持的情况,这是因为一个程序的升级通常会让基地址发生变化,所以在模拟器里要能够支持一个系列全版本的模拟器,就需要使用动态定位基地址的方法,于是采用了“基址特征数据”这个概念* q" Z2 ?+ i* F2 J
& [) x% C9 n) V i) j. [回到我们之前的搜索出很多基地址的那个步骤,这里选择基地址其实是有诀窍的,我们启动另一个版本的Snes9X模拟器,模拟同样的游戏,同样搜索平原金钱的地址指针
3 t6 T, E1 E% N. }* |; |1 k5 R) e我们保留之前的模拟器进程和调试器进程,同时启动不同版本的模拟器进程双开另一个调试进程来进行跟踪调试以方便对比
/ b; N6 Q {, t6 W& P
9 h7 y- `" T+ G) @7 B* E
2 A. M( V4 q0 y2 v2 Z1 K0 x0 l
3 f/ T0 Q( I3 q6 D7 h采用同样的方法得到了 也可以得到基地址列表; f0 W' R* z/ I* _5 K4 V5 m4 r
那么现在需要从这些基地址里面找到可以通用的特征码,这个比较考验经验,查看特数据的方式可以右键点击任意基地址,点击“反汇编该内存区域”
$ q2 M: d4 O6 F/ \然后找到两个不同版本的模拟器之间的通用的一个基地址特征数据,如果找不到甚至要开始进行2级或者多级指针查找
& U, r& K( a3 F/ e4 m所谓的基址特征数据就是指的通过一段内存数据的搜索可以定位到一个固定地址,然后通过这个固定地址增加一个偏移值就可以定位到基地址) g! `) W5 e' T8 B1 j
比如这里SFC模拟器SNes9X我们就用2级指针来进行基地址搜索以及确定基址特征码,首先以0076448C作为一级指针来追踪二级指针3 Y( }/ Z s) C
(如果这里对于多级指针的查找和添加方法看不明白的,请在网上搜索CheatEngine八步教学的教程自学一下)
& m! X4 X5 E/ q3 o/ @
$ H1 I, `3 R# @0 s: W; j
P" b4 d6 P1 g3 E9 [
3 C1 u0 q# I! D重新读取一下游戏就可以找到以下代码
3 @4 e6 H) D8 } Z9 q9 j2 R( p! E7 j. v7 K) {' @. e4 t, B
E9 x; z% w O) N
8 q6 ~' O, B" W使用深度扫描可以找到对应007311C8的指针( |' c' ?- d( ]$ t% Q6 M
% t0 X) g- @, w( U& J' T8 c3 {+ P
" T l: a1 N6 k' y
6 l: ]" g, B# u1 ~2 {
这个时候对于基地址的添加就多了一种方式,使用2级指针进行寻址,这时候【附加数据】需要填上1,才能正常寻址# I1 \( t# E& c3 ]' F: a
. v+ x4 p6 C- y9 Z1 C* m1 Y+ y7 C) X. X' a
3 G: m5 P9 p* I) @' r
改完后我们可以尝试搜索平原的金钱,可以看到添加2级指针的基地址的结果和之前的效果相同: t+ y3 k& ?: k+ ^: ]
& o! Y: w* V' q8 S" ^
- E, @3 o9 P$ E/ e: D {" }+ z8 E/ T; L$ H3 J
但是换一个版本的模拟器时同样无法使用2 C3 ^: o# c$ R9 a$ P
所以我们对于其他版本的模拟器以同样的方法和选地址方式进行这个2级指针的寻址,得到对比结果如下2 G" B: [" Z8 |+ z- ~2 k0 `
/ X3 F1 i4 t6 o7 S' ]) z5 n9 h
9 c3 O- A8 E# E8 E t' h! W9 l( D- s8 U/ Y9 m$ R
可以看到两个版本的模拟器,对应的2级指针地址很接近但并不相同,那么我需要一种可以自动定位到各个版本的基地址的方法,这种自动定位的方法就是“特征码寻址”: |3 L" o# Q! A, N
我们分别对上图的红框内的2级指针地址查看反汇编的代码,如下图( s( ]1 y8 D r0 E! h
9 q# g8 }4 o$ ?% P- _+ C# w8 r
: q; q5 k. O5 Y6 j; s5 s: d! V
* d3 c3 I4 M$ l5 ]# Y
然后又可以得到一个对比图,下图中选中的部分就是相关到2级指针的地址的代码
, Z5 ^8 _& d9 f4 C* K: S5 N4 u$ o6 f# K1 @
+ ~' U: _1 u* J2 i! ?- Q, z
; {1 o! I- H5 |+ c6 s5 Z3 d% }
通过观察可以看到,虽然2级指针的地址和代码不同的模拟器版本有一些区别,但是在这段代码前两者确有一段共同的代码:2B C7 48 C1 E0 05 50
, M& ^9 V+ y; Z5 m/ v! N我们不妨对这段代码进行搜索,如下图,注意反汇编里看到的字节搜索的时候要反过来,2B C7 48 C1,搜索就要搜索C148C72B
% D: f x7 j* d# S8 ], [- K0 |& t. O% i/ U
% C9 x7 H( p9 X3 m* \" l0 x! H$ o8 h6 W
非常幸运的,这段代码在模拟器的程序里具有唯一性,那么我们就可以通过这段代码定位到之前的2级指针的地址
+ t) |+ o9 ^4 i! ^: V) [$ T6 C: k/ p4 N这段代码的地址是00409664,2级指针的地址是00409674,两个地址之前相差10(H),那么我通过定位到00409664,然后增加10(H)的偏移就可以得到2级指针的基地址00409674/ a9 R" B1 z) V) C/ Y5 n0 D4 q
我们在看一下另一个版本的模拟器,这段代码定位的地址是00409FD4,而2级指针的地址是00409FE4,差值也是10(H)
# q+ }; T$ j- H# G那么这两个版本的模拟器的共性我们就找到了(这种共性肯定不止一处,这里只是介绍方法)2 t* Z1 c. `! E# [' f
最后我们就是要把共性统一成模拟器的基地址
% t" Z6 S1 y: P9 B$ v M6 Z8 ]- \: q* t. Z# n6 I4 o
7 o$ k) `4 l, q5 \9 W Q6 M. O
+ a2 P* y! D1 p/ X' B8 P6 z
这里的基址特征数据就是用刚才我们所说的不同版本模拟器的共性进行定位到基地址,而这里的附加数据“5”表示找到的基地址的指向的地址的偏移,我们再把前面添加2级指针的基地址的图来对比一下+ d, r7 h1 V" i
2 s3 N; V7 ?7 @( A/ B' A" _
3 i6 t! u9 w1 ^+ { h/ F6 p
$ [$ k; B) H6 ?按照基址特征数据的方式,我们尝试一下对其他版本的模拟器搜索金钱地址的结果,之前我搜索的是Snes9X 1.52版,现在我来搜索1.53版
4 W4 Z4 f C* r$ `$ a
9 g3 s7 i# l9 E" M1 C, Z# E
h' b; C( `; N9 C) p
3 a: C7 E, _3 Y" g5 B, N' M x+ [ P; L
我们可以看到,现在两个版本的模拟器通过特征地址的方式统一了搜索的结果,但是这样其实我们还只是作出了通用1.52和1.53两个版本的模拟器
5 |5 a) |. f! R* ^2 ?: K9 f) g! X# v# H如果想作出更大的兼容性,则还需要拿更多的版本的Snes9X来做这种共性的测试,最终找到一个共性地址0 }. n+ o! t0 D' f" l, D7 y
值得说明的是,这里的基址特征数据可以用?做替代,比如2BC748C1E00550作为特征地址码的话可以写成2B??48C1????50,这样其实可以模糊出更多的版本共性出來 `7 S$ k3 U4 \/ I
本文可以看作一篇实例教学,关于附加数据和添加说明写法的详细说明( i- G& U/ G' }$ U0 ^) c" |9 c) q3 j
还可以参考http://www.cheatmaker.org/Help/supportDoc/supportDoc.html
# i4 a2 K$ L& f4 e$ Z这里最下面的位置写了各个基地址和附加数据的写法和作用
) J6 P- L8 F. Q9 s+ E8 F
O$ w( ]; ^& P: m9 D2 C |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|