手机游戏攻防(一) 变量加密法

  1. 1. 一.什么是八门神器
  2. 2. 二.原理
  3. 3. 三.应对方案

这篇文章的前提是单机游戏,网络游戏有自己的加密方法,与单机游戏不尽相同!

游戏辛辛苦苦的做完了,但是使用八门神器可以轻松的修改你的重要数据(金币,道具数量),哈哈哈,那么恭喜您,您挣不到一分钱!说的有点危言耸听了,毕竟知道八门神器这个工具的不是非常多,而且使用条件比较苛刻,但是我们不能掉以轻心,他完全可以修改完成了,将存档放在网上,这样我们就十分被动了!

一.什么是八门神器

不明白八门神器为何物的请自行Google!这里我引用百度百科(点击这里:http://baike.baidu.com/view/3258873.htm)中的一段话:

八门神器是安卓、iOS、塞班平台上通用的游戏修改工具,可以修改内存中的数值和参数,达到修改游戏HP、MP、金钱、等级等的作用。八门神器类似于PC平台的金山游侠等游戏修改器,是手机游戏中的金手指。但八门神器在安卓平台下需要Root权限才能正常工作,在iOS平台下需要iPhone越狱才能正常工作,并且支持中、英双语言,并且自带帮助说明。

建议大家还是亲自去使用下这个工具,效果请看下图:

二.原理

知己知彼百战百胜,我们要先了解八门神器的原理:

在游戏运行时,内存和处理器都会对于游戏进行非常复杂的数据交换和变更,这是因为游戏有很多的数据,例如金钱、HP值、等级、攻击力、防御力等数据,而这些数据,就在内存和处理器的各个地址当中,玩家只需要在八门神器中搜索相关的数据值,八门神器就会将搜索出记录此数据的各个地址显示,玩家进行多次的数据变更后再次搜索,到最后就会确定此地址到底是哪一个,然后将此地址的数值进行修改,回到游戏中,相关的数据也会变化!
总结下,就是八门神器会搜索出对应数值的内存地址,然后改变内存地址对应的值!

三.应对方案

这样我们貌似可以从两个方面去入手解决这个问题:

  1. 让它搜不着!
  2. 让它改变不了!

我们今天先来看看第一种方法. 用过这个工具的人都明白,一般情况下,一次搜索就能准确定位内存地址的情况非常少见(除非这个数字非常大,非常奇葩),都是先搜索,获得大量(几十万)的数据,然后回到游戏中,改变这个值,再回到八门神器,会自动筛选出之前搜索到的结果有哪些改变了…直到只剩下几个结果,这个时候我们挨个去改变值会变得十分的Easy!

1.改变内存地址

想想这个过程,好像只有第一次搜索是全局搜索,后面的每次搜索都是在之前搜索的结果上进行筛选!这样如果我们游戏中每次改变这个变量的时都去改变这个变量的内存地址,这样它就搜索不到了!代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class DynamicInt
{
public:
DynamicInt(){m_pValue=NULL;}

~DynamicInt()
{
if (m_pValue)
{
delete m_pValue;
}
}

int getValue(){return *m_pValue;}

void setValue(int nValue)
{
if (m_pValue)
{
delete m_pValue;
}
m_pValue=new int();
*m_pValue=nValue;
}
private:
int * m_pValue;
};

经过尝试,这个方法并不管用,还能被破解,不知我的做法错误呢还是八门神器的原理不是这样!请懂行人指出!

注: 经过分析, 可能是因为你 delete 后立刻 new 会获取到同一块内存地址的原因~ 这样的话, 我们也好说, 我们先换下顺序可能就可以了, 不过我没有进行过测试!

2.加密数据

换个思路,我们为何不在数据上做手脚,对数据进行加密(如:表面上显示的是50,内部存的却是50^0xff),这样他搜索表面上的数字当然搜索不到!代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#ifndef _H_DYNAMICVALUE_H_
#define _H_DYNAMICVALUE_H_

template<class T>
class CEncryptValue
{
public:
CEncryptValue()
: m_Value(0)
{
}
~CEncryptValue()
{
}

T getValue()
{
return m_Value ^ m_EncryptKey;
}

void setValue(T value)
{
m_Value = value;
m_EncryptKey = rand();
m_Value ^= m_EncryptKey;
}

void offset(T value)
{
setValue(getValue() + value);
}

public:
T m_Value;
int m_EncryptKey;
};

typedef CEncryptValue<int> CDynamicValueInt;
typedef CEncryptValue<float> CDynamicValueFloat;
typedef CEncryptValue<bool> CDynamicValueBool;

#endif

使用时:

1
2
3
4
5
6
7
8
9
10
CDynamicValueInt m_DynamicMoney;

//设置金钱数
m_DynamicMoney.setValue(1000);

//得到金钱
m_DynamicMoney.getValue()

//改变金钱
m_DynamicMoney.offset(-100);

这个方法经过测试,十分管用!也是我目前采取的方案!大家可以直接拿来使用!

写在后面的话:

有些人可能会骂八门神器的作者无耻之类,我非常不认同,大家都是靠手艺吃饭的,么有什么无耻不无耻的,如果你的游戏被破解了,只能说明你比较傻!还有对使用八门神器破解游戏的玩家表示同情,因为你一旦破解了,整个游戏就没有意义了!