目录介绍:
- 1、怎样制作游戏辅助
- 2、怎么制作游戏修改器?
- 3、如何制作各种游戏补丁…
- 4、看看黑客怎么玩游戏
- 5、黑客是怎么玩游戏的
怎样制作游戏辅助
做游戏辅助程序的原理及方法原 理 就 是 调 用 外 部 ( 游 戏 ) EXE 文 件 对 话 原 理 1 可 以 采 用 参 数 2 采 用 进 程 通 信 用 参 数 传 递 主 机 信 息 和 一 些 信 息 用 进 程 通 信 实 现 验 证 是 否 是 我 项 目 中 的 游 戏 。 要看是什么 游戏的辅助程序, 单机版游戏的辅助程序无非就是读内 存中 的数据进行修改, 网 络 游 戏 的 是 拦 截 数 据 包 进 行 修 改 . 摘 录 : 辅助程序现在分为好多种, 比如模拟键盘的, 鼠标的, 修改数据包的, 还有修改本地内存的, 但好像没有 修 改 服 务 器 内 存 的 哦 。 修改游戏无非是修改一下本地内存的数据, 或者截获 API 函数等等。 这里我把所能想到的方法都作一个介绍, 希望大家能做出很好的辅助程序来使游戏厂商更好的完善自己的技术。 我见到一篇文章是讲魔力宝 贝 的 理 论 分 析 , 写 得 . . . . . . . 进 程 间 通 信 , 你 开 发 的 什 么 辅 助 程 序 啊 。 那 你 还 要 启 动 主 程 序 , 真 正 的 辅 助 程 序 是 模 拟 的 客 户 端 , 不 用 启 动 主 程 序 。 要 做 的 工 作 太 多 了 。 先 要 截 获 登 入 网 络 封 包 , 用 动 态 调 试 软 件 截 获 网 络 接 受 封 包 也 就 是 rectveto 函 数 , 然 后 找 到 加 密 的 地 方 , 全 是 汇 编 , 然 后 翻 译 为 你 写 辅 助 程 序 的 语 言 。 然 后 把 截 获 的 封 包 来 解 密 , 想 出 登 入 的 通 信 协 议 。 然 后 做 一 个 程 序 发 送 该 加 密 信 息 , 得 到 服 务 器 返 回 的 数 据 。 在进行解密分析任务属性。 这样一来一样破解出登入的信息至少要 1 天。 这是高手中的高手。 一 般 破 解 出 大 部 分 通 信 协 议 要 一 段 时 间 , 决 不 是 什 么 进 程 间 通 信 。 这 样 你 可 以 任 意 修 改 网 络 的 数 据 封 包 发 送 模 拟 信 息 。 要 完 成 所 有 的 通 信 协 议 怎 么 也 要 有 一 个 月 。 所 以 辅 助 程 序 没 有 专 门 的 公 司 一 般 只 有 一 点 点 功 能 。 向 什 么 , 瞬 间 移 动 , 就 不 是 发 送 了 一 个 平 常 的 数 据 把 坐 标 发 过 去 就 可 以 了 。 但是有些做得好的网络游戏, 它的主机会判断你在这么短的时间里面, 不可能移动着么远的距离。 所以有些 辅 助 程 序 只 能 穿 墙 , 等 等 那 就 是 移 动 了 一 点 点 距 离 。 服务器的解决办法, 把墙加厚, 厚到你不可能在短时间通过, 哈哈辅助程序失效。 我 可 以 提 供 我 写 的 截 获 网 络 封 包 程 序 , 解 密 工 作 要 大 家 自 己 做 了 。 应 为 我 的 汇 编 也 不 怎 么 的 , 只 能 拿 到 汇 编 论 坛 , 请 大 哥 翻 译 。 动 态 调 试 工 具 softi ce, trw2000 trw2000 国 产 软 件 , 简 单 好 用 。 支 持 98 softi ce 功 能 强 大 。 支 持 98 , 2000 。 大家要的话在这里留言, 好多的人话我把我原来的程序改写一下, 提供给大家。 QQ 登入这些信息都可以截 获 , 但 是 乱 码 ! 你 要 自 己 破 解 了 加 密 算 法 才 行 。 我 说 两 句 , 1 、 网 络 游 戏 , 客 户 端 和 服 务 器 端 的 几 种 通 讯 方 式 a 、 直 接 通 过 Wi nSock 编 程 接 口 进 行 , 大 多 数 的 网 络 游 戏 采 用 这 个 方 式 。 b 、 通 过 HTTP 协 议 进 行 通 讯 , 有 些 网 络 游 戏 利 用 I E 的 组 件 进 行 通 讯 。 很 少 C、 一种设想: 可以同过 SOAP 协议进行通讯, 还没有见过这样的大型网络游戏, 可能很快就会有。 2 、 服 务 器 端 程 序 的 构 造 方 式 通常是一个接受客户端数据提交和响应客户端数据请求的数据库服务程序。 很多的网络游戏用 SQLServer 作为数据库, 服务程序其实很简单, 就是接受数据提交和响应数据请求。 有些服务器端程序给予客户-服务模型, 只有客户请求数据他才向客户传输数据, 这样这个服务器端演变成了一个普通的数据库应用的服务器端。 客户之间数据同步也都是基于请求-响应模型。 服务器端通常不主动地向客户端发送数据。 这种模型有一个漏洞, 就是客户端可以加快请求的频率以获得更多的服务器相应, 这是某些辅助程序的基本原理。 有些服务器端可以主动地向客户端发送数据, 从而避免了这类辅助程序的干扰。 这类服务器端构造比较复杂, 它需要纪录链接的客户信息等等。 为了加快响应时间, 平衡负载, 某些服务器端使用了 Com+技术, 每次客户请求数据或者更新数据的时候需要提供一个连接标志, 或者当前客户的状态。 还有的服务器端为了加快响应速度, 他根本不纪录客户端的状态, 他也不去数据库请求数据进行验证, 客户端必须自己记住当前的状态。 为了防止恶意辅助程序, 通常他会检查新数据和客户端提交的状态之间的关系。 3 、 辅 助 程 序 的 基 本 方 式 a、 提高客户端的时间节律, 这里面有很多的方式, 一种, 提高时钟硬件的节律, 和 I ntel 系列的 CPU 的配合的主板在时间控制方式上和早期的 8086 没有任何差异, 可以直接修改, 在 Wi n2000 下面需要取得 Ri ng0 的权限, 可以通过Servi ce 程序获得。 还有一种截获时间频率的 API 比如 SetTi mer 之类的 API , 替换成自己的函数, 但是这样根据不同的游戏控制节律的方式决定。 这一类方式对于服务器端控制节律的网络 游 戏 是 没 有 效 果 的 。 b、 修改客户端的内存, 从而直接修改你需要修改的属性, 这种方式一般没有用, 如果服务器端加强验证是 很 难 奏 效 的 。 不 过 做 得 巧 妙 也 是 很 有 效 果 的 。 C、 控制客户端和服务器端的通讯, 这有很多的办法, 常见的截获Wi nsock 的 API 和使用网络过滤驱动程序, 这也有很多的办法, 可以用增加 Wi nSock 的过滤层, 使用小端口网络驱动程序, 还有一个办法就是使用代理服务器截获。 修改网络封包的方法, 和直接修改内存数据的效果差不多, 但是要灵活很多, 可以采用的策略更多, 取决于服务器端的如何验证数据有效的策略, 服务器端的有效性验证不可能十全十美,总有漏洞可以钻, 这需要不断的实验和猜测, 如果你认识开发组的人, 那么要简单很多了 。 D、 完全的自己的客户端, 效果和控制通讯一样, 但是系统资源的耗费要少很多, 毕竟一个大的图形客户端占用 的资源很庞大, 这适合于挂机玩游戏的玩家, 可以 同 时挂上好多 的角 色一起干。 E、 黑客的方式, 入侵服务器, 直接修改数据库, 这个方法最有效了, 绕开了一切服务器的检查, 不过要小心 GM 的检查, 不要一次弄上很多, 一天升 2-3 级就可以了 , 否则, 肯定引起怀疑。 如果对方的 SQLServer 服务器不在防火墙后面, 那么就更容易一些, 有大量的方法可以采用。 直接攻击服务器程序也可以, 或者供给服务器上面的其他服务, 唯一的目标, 就是植入木马, 经典的就是缓存溢出攻击, 如果对方的服务器程序写得不好, 一个极品封包就可以使他出错。 植入了你的木马, 你再写一个好用一点的客户端辅助程序就可以了。 小心坐牢。 如果你清楚电信机房的内幕, 可以攻击任何和她比较近的服务器, 比如在同一个网段的其他服务器, 然后迂回的攻击。 不会所有的服务器都是铁桶一个, 一个有点漏洞, 其他的都有可能遭殃。 4、 封包破译, 有很多的网络监控软件可以使用, 可以直接看到客户端和服务器端的通信情况, 解密需要依靠自己的智慧了。 速度快一点, 用两台电脑, 一个作代理服务器, 截获, 并且纪录通讯的情况, 最简单的你移动一下角色, 看看发送了什么数据, 解密都不用作, 直接再发就可以了, 不过如果他整个封包加密,而不是一个数据一个数据的加密, 就很难看出来。 通常加密机制不复杂, 因为服务器承受不了解、 加密的压力 , 太 复 杂 的 加 密 他 不 会 用 的 。 分 析 数 据 包 , 主 要 依 靠 猜 测 。 基 本 方 法 就 是 对 比 。 1 、 完整的隔离出一个数据封包, 去掉其他的关于代理的, 或者其他的外加的信息, 这需要你熟悉网络协议。 2 、 对 比 封 包 , 观 察 不 同 封 包 的 内 容 , 关 键 是 甄 别 出 不 同 封 包 之 间 相 同 的 结 构 。 3、 不同封包的差分对比。 上一个封包的状态和下一个封包之间的微小差异, 客户端仅仅变动很小, 观察两个 封 包 直 接 的 差 异 。 4、 不同用户的, 相同操作的封包对比。
怎么制作游戏修改器?
游戏修改器制作-黑客入门
工具:SoftICE、金山游侠2002、VC++7.0、PE查看器、SPY++
测试平台:Window2000 Professional SP2
首先我介绍一下将会用到的工具:
1、 SoftICE(不用多说了吧,我想你应该会用)
2、 金山游侠2002(这个你也应该会用)
3、 VC++7.0(不要求你一定会用,但至少应该会一种编程工具)
4、 PE查看器(你可以随意找一个,没有也没关系,我会教你用SoftICE查看)
5、 SPY++(VC里的一个查看程序信息的工具,你可以和别的,比如Delphi和C++Builder的WinSight32)
然后就是你应该会的知识:
1、 汇编基础
2、 一些编程基础,至少应该看懂我介绍的几个API函数
3、 PE文件结构的基础,不会也没关系,我会解释给你
以上几点你都具备了的话我们就可以开始了。
我来介绍一下我要教给你的东西。想必大家都玩过PC游吧,那么也一定用过一些专用的游戏修改器吧,比如暗黑,红警,大富翁这些经典的游戏都有它们专用的修改器,注意,我说的不是FPE之类的通用修改工具。
你试没试过用金山游侠修改红警二的金钱?如果有的话你应该知道每玩一次就要改一次,因为这个游戏是动态分配内存的,每次重新开始都会改变。所以你会选择到网上去下载一个专用的修改器,那么你有没有想过自己做一上呢?想过?那你为什么不做?什么不会?那就好办了,看了这篇教程你就会了:D费话少说,我来讲一下原理。
有一些经常修改游的朋友一定会知道,不论游戏中“物品”的内存地址是否是动态的,物品与物品之间相隔的距离都是不变的,我拿“楚留香新传”为例,我先用金山游侠查找内力值的内存地址,找到的结果是:79F695C,再查找物品“金创药”的地址是:328D1DC,现在我用79F695C减去328D1DC,得到:4769780,这个数就是内力值与金创药的偏移值,没看懂?接着看呀,我还没说完呢,现在重新再运行游戏,查找内力值的地址,得到:798695C再查找金创药得到的地址是:321D1DC,两个值的内存地址都改变了,但是用你内力值的地址减去金创药的地址得到的结果是什么?没错,还是4769780,也就是说,无论这两个值的内存地址变成多少,它们之间的距离是永远不变的,不光是这个游戏,一般的游戏都是,至少我没见过不是的:D
上面讲的东西总结出一个结论,那就是我们只要得到这两个地址中的任何一个,就可以得到另外一个,只要你知道它们之间的偏移量是多少。
我们第一步要做的就是得到这个地址,但是内存中的地址是动态改变的,得到也没有用,这里我就教你把它变成静态的,叫它永远都不变!我继续拿“楚留香新传”为例,如果你有这个游的话就跟我一起做,没有的也没关系,只要看懂这几个步骤就行了。开工!
首先进入游戏,查找内值的地址,得到的是:798695C(不知道为什么这上游并不是每次重起都改变内存地址),按Ctrl+D打开SoftICE,下命令:BPM 798695C W(写这个地址时则中断),回到游戏中,打开人物属性面板,游戏中断了,在SofitICE中你会看到这条指令:
0047EB17 MOV EAX [EDX+000003F4] 下命令:D EDX+3F4将看到内力值
0047EB1D PUSH EAX
………………………………
………………………………
从上面可看出0047EB17处的指令是将内力值的指针送到EAX寄存器中,这是一个典型的寻址方式,设想一下,我们是到了EDX中的基址,那么无论什么时候只要用EDX+3F4就可以轻松的得到内力值的地址,因为000003F4是一个常量,它是不会改变的,改变的只是EDX中的地址,所以只要有办法得到EDX中的值就什么都好办了,你明白了没有?如果还是不懂,那么请再看一遍。现在要做的就是如何得到这个值,下面我教给你如何做:
我的办法就是设计一段代码,把EDX中的值存放到一个地址中,然后运行这段代码,再返回游戏的原有指令继续执行,什么?补丁技术?SMC?随你怎么说啦,只要运行正常就一切OK啦:D
实际操作:
首先在程序中找一段空白处来存放我们设计的代码,很简单,只要懂得一些PE文件结构的朋友都会知道,一般在EXE文件的数据段(.data段)的结尾都会有一段缓冲区,我们可以在这段区域中写任何东西,当然你也可以用“90大法”找一段空白区,但我还是推荐你用我教给你的方法。上同我提到,如果你没有PE文件查看工具我可以教你用SoftICE查看,而且很简单,只要一个命令:MAP32 “模块名”,看一下我是怎么做的你就知道了。
Ctrl+D呼收出SoftICE,然后下命令:MAP32 CrhChs,这时你应该看到EXE各个段的信息,我们要注意的只是.data段,既然要找的是数据段的结尾,那么我们就从下一个段开始向上找,如下:
.data 004FB000
.rsrc 00507000
.data的下一个段是.rsrc段,它是从00507000开始的,也就是说以00507000为基础向上一个字节就是数据段的结尾,我所择从00506950处开始写代码,说了这么半天那么我们的代码到底是什么样子呢?修改后的指令又是什么样的呢?别急,请看下面:
修改0047EB17后代码:
0047EB17 JMP 00506950 //跳到我们的代码中去执行
0047EB1C NOP //由于这条指令原来的长度是6字节,而修改后的长度是5个字节,所以用一个空指令补上
0047EB1D PUSH EAX
//我们的代码:
00506950 MOV DWORD PTR EAX,[EDX+00003F4] //恢复我们破坏的指令
00506956 MOV DWORD PTR [00506961],EDX //把EDX保存以00506961中去
0050695C JMP 0047EB1D //返回原来的指令去执行
把上面的代码用SoftICE的A命令写入,OK!
现在我们试一下运行的效果,你现在用金山游侠搜索一下内力址的地址,什么又变了?那就地啦,它要是不变我们还用费这么大劲儿吗?记下这个地址返回到游戏中去,Ctrl+D呼出SoftICE,下命令 D *[00506961]+000003F4,在数据窗口看到什么了?呵呵,没错,看到了你刚才记住的那个地址,里面的数值正是内力的值,试着改一下,回到游戏中,呵呵,内力值变了吧:D
讲到这里,我们的工作已经完成了%90,但别高兴的太早,后面的%10要远比前的%90花的时间长,因为我们要用编程实现这一切,因为你不能每次都像刚才那样做一次吧!
现在我来说一下编程的步骤:
首先用FindWindow函数得到窗口句柄,然后用GetWindowThreadID函数从窗口句柄得到这个进程的ID,接着用OpenProcess得到进程的读写权限,最后用WriteProcessMemory和ReadProcessMemory读写内存,然后。。。。呵呵,你的修改器就做成啦:D
下面是我抄写以前写的修改器源程序片断,第一部分是动态写入刚才的代码,第二部分是读取并修改内力值,由于我没有时间整理和测试,所以不能保证没有错误,如果大家发现有遗漏的话,可以在QQ上给我留言或写信给我,代码如下:
有几点请大家注意:
1、 写机器码时要一个字节一个字节的写
2、 注意要先写入自己的代码,然后再修改游中的指令(下面的代码没有这样做,因为不影响,但是你应该注意这个问题)
#define MY_CODE5 0x00
#define MY_CODE6 0x90
//00506950
#define MY2_CODE1 0x8B
#define MY2_CODE2 0x82 //这部分是要写入的机器码的常量定义
#define MY2_CODE3 0xF4
#define MY2_CODE4 0x03
#define MY2_CODE5 0x00
#define MY2_CODE6 0x00
#define MY3_CODE1 0x89
#define MY3_CODE2 0x15
#define MY3_CODE3 0x61
#define MY3_CODE4 0x69
#define MY3_CODE5 0x50
#define MY3_CODE6 0x00
#define MY4_CODE1 0xE9
#define MY4_CODE2 0xBC
#define MY4_CODE3 0x81
#define MY4_CODE4 0xF7
#define MY4_CODE5 0xFF
//-----------------------------------------------------------------------------//
DWORD A1 =MY_CODE1;
DWORD A2 =MY_CODE2;
DWORD A3 =MY_CODE3;
DWORD A4 =MY_CODE4;
DWORD A5 =MY_CODE5;
DWORD A6 =MY_CODE6;
DWORD B1 =MY2_CODE1;
DWORD B2 =MY2_CODE2;
DWORD B3 =MY2_CODE3; //这部分是变量的定义
DWORD B4 =MY2_CODE4;
DWORD B5 =MY2_CODE5;
DWORD B6 =MY2_CODE6;
DWORD C1 =MY3_CODE1;
DWORD C2 =MY3_CODE2;
DWORD C3 =MY3_CODE3;
DWORD C4 =MY3_CODE4;
DWORD C5 =MY3_CODE5;
DWORD C6 =MY3_CODE6;
DWORD D1 =MY4_CODE1;
DWORD D2 =MY4_CODE2;
DWORD D3 =MY4_CODE3;
DWORD D4 =MY4_CODE4;
DWORD D5 =MY4_CODE5;
//--------------------------------------------------------------------------//
HWND hWnd =::FindWindow("CRHClass",NULL); //得到窗口句柄
if(hWnd ==FALSE)
MessageBox("游戏没有运行!");
else
{
GetWindowThreadProcessId(hWnd,hProcId); // 从窗口句柄得到进程ID
HANDLE nOK =OpenProcess(PROCESS_ALL_ACCESS|PROCESS_TERMINATE|PROCESS_VM_OPERATION|PROCESS_VM_READ|
PROCESS_VM_WRITE,FALSE,hProcId); //打开进程并得到读与权限
if(nOK ==NULL)
MessageBox("打开进程时出错");
else
{
//0047EB17
WriteProcessMemory(nOK,(LPVOID)0x0047EB17,A1,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x0047EB18,A2,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x0047EB19,A3,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x0047EB1A,A4,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x0047EB1B,A5,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x0047EB1C,A6,1,NULL);
//00506950
WriteProcessMemory(nOK,(LPVOID)0x00506950,B1,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x00506951,B2,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x00506952,B3,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x00506953,B4,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x00506954,B5,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x00506955,B6,1,NULL);
//第二句
WriteProcessMemory(nOK,(LPVOID)0x00506956,C1,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x00506957,C2,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x00506958,C3,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x00506959,C4,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x0050695A,C5,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x0050695B,C6,1,NULL);
//最后一句
WriteProcessMemory(nOK,(LPVOID)0x0050695C,D1,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x0050695D,D2,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x0050695E,D3,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x0050695F,D4,1,NULL);
WriteProcessMemory(nOK,(LPVOID)0x00506960,D5,1,NULL);
CloseHandle(nOK); //关闭进程句柄
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//读取并修改内力值
DWORD hProcId;
HWND hWnd =::FindWindow("CRHClass",NULL);
if(hWnd ==FALSE)
MessageBox("No");
else
{
GetWindowThreadProcessId(hWnd,hProcId);
HANDLE nOK =OpenProcess(PROCESS_ALL_ACCESS|PROCESS_TERMINATE|PROCESS_VM_OPERATION|PROCESS_VM_READ|
PROCESS_VM_WRITE,FALSE,hProcId);
if(nOK ==NULL)
MessageBox("ProcNo!");
else
{
DWORD buf1;
DWORD write;
BOOL OK=ReadProcessMemory(nOK,(LPCVOID)0x00506961,(LPVOID)buf1,4,NULL); //读取我们保存EDX中的基础
if(OK ==TRUE)
{
write =buf1+0x000003F4; //得到内力值的地址
DWORD Writeed =0x00; //要修改的数值
BOOL B =WriteProcessMemory(nOK,(LPVOID)write,Writeed,1,NULL);
if(B==FALSE)
MessageBox("WriteNo");
}
}
CloseHandle(nOK);
}
啊,写的我手都麻啦,今天就到这里了,才疏学浅难免会有遗漏,请大家指教,如果我不会或不喜欢用VC的话,你可以在QQ上与我交流,我可以教你如何用Delphi、C++Builder、Win32Asm或VC实同上面的功能。
(如转载本篇文章请不要改动内容及作者!)
作者:CrackYY
Email:CoolYY@msn.com
OICQ:20651482
2001年,从云风那儿得知了IDA这种好东东,看到他在解恺撒的游戏资源,觉得好玩,也开始自己解一些东东,当时一口气解了一些游戏的资源,当然,都不是很复杂的,主要是台湾和日本的
后来在主页上放过一段时间,记得感兴趣的朋友还挺多的,一直没时间说,现在大概聊一下做法吧:)
工具当然是IDA+SoftIce,要自己写解压程序的话,还要有习惯的编辑器,我当然是用VC
其实,资源破解,并不是很复杂,方法大致有3种
1,硬性破解
通过观察目标文件和反汇编代码,分析出资源压缩或者加密的格式,写程序读取改文件,并转换成一种自己可以识别的格式就OK了
这是自己动手解资源时最容易想到的做法
具体来说,也就是通过一些特定函数,譬如 fopen、createFile这样的文件相关函数,确定游戏的解资源函数,然后就拼命的分析汇编代码就OK了
我前期大部分资源都是这样破解的,最好先用UEDIT分析一下实际的文件,有些格式太简单了,通过文件大小,用看的就可以了
这种方法,我解过的最复杂的就是神奇传说系列,当时就感觉和GIF比较像,但又不太一样,因为对压缩算法没研究,所以就没深究了,不过后来从网上看到文章说,那是一个很通用的压缩算法,一些解压工具就可以可以解开的,◎#¥%……真是不爽(不过还好,我只花了几个小时就解开那个游戏而已
2,Dump
等图片载入后,直接从内存中导出
这种做法也很容易想到的,主要难点在于内存中资源的格式问题,可能对3D游戏来说,这种解法比较容易一些,毕竟纹理渲染这些,是显卡完成的,不是软件实现的
我了解到的有些人解魔兽的资源就是这样解开的,hook OpenGL的一些函数
我这样解过一些游戏的文本(汉化用的文字),赛车游戏的,为了获取所有游戏文本,特地将那款游戏通关的说
3,直接调用游戏的解码函数解码
和第2种做法类似,但是主动调用函数,基本上可以一次将所有资源全部解开,不需要游戏通关
当然,不是让你调用游戏的解包模块,毕竟很多游戏都不是dll形式的
只能侵入到游戏进程内部,找一个合适的时机(一般是载入其他文件的时候,中断跳转一下,先把我们的事做完),调用内部函数,解开所有的资源
我解过一款游戏就是用这种方法,说起来,那款游戏的资源压缩率和rar差不多
0. 需求文档
LZW压缩算法是一种新颖的压缩方法,由Lemple-Ziv-Welch 三人共同创造,用他们的名字命名。它采用了一种先进的串表压缩,将每个第一次出现的串放在一个串表中,用一个数字来表示串,压缩文件只存贮数字,则不存贮串,从而使文件的压缩效率得到较大的提高。奇妙的是,不管是在压缩还是在解压缩的过程中都能正确的建立这个串表,压缩或解压缩完成后,这个串表又被丢弃。
1. 基本原理
首先建立一个字符串表,把每一个第一次出现的字符串放入串表中,并用一个数字来表示,这个数字与此字符串在串表中的位置有关,并将这个数字存入压缩文件中,如果这个字符串再次出现时,即可用表示它的数字来代替,并将这个数字存入文件中。压缩完成后将串表丢弃。如"print" 字符串,如果在压缩时用266表示,只要再次出现,均用266表示,并将"print"字符串存入串表中,在解码时遇到数字266,即可从串表中查出266所代表的字符串"print",在解压缩时,串表可以根据压缩数据重新生成。
2. 实现方法
A. 初始化串表
在压缩信息时,首先要建立一个字符串表,用以记录每个第一次出现的字符串。一个字符串表最少由两个字符数组构成,一个称为当前数组,一个称为前缀数组,因为在文件中每个基本字符串的长度通常为2(但它表示的实际字符串长度可达几百甚至上千),一个基本字符串由当前字符和它前面的字符(也称前缀)构成。前缀数组中存入字符串中的首字符,当前数组存放字符串中的尾字符,其存入位置相同,因此只要确定一个下标,就可确定它所存贮的基本字符串,所以在数据压缩时,用下标代替基本字符串。一般串表大小为4096个字节(即2 的12次方),这意味着一个串表中最多能存贮4096个基本字符串,在初始化时根据文件中字符数目多少,将串表中起始位置的字节均赋以数字,通常当前数组中的内容为该元素的序号(即下标),如第一个元素为0,第二个元素为1,第15个元素为14 ,直到下标为字符数目加2的元素为止。如果字符数为256,则要初始化到第258个字节,该字节中的数值为257。其中数字256表示清除码,数字257 为文件结束码。后面的字节存放文件中每一个第一次出现的串。同样也要音乐会 前缀数组初始化,其中各元素的值为任意数,但一般均将其各位置1,即将开始位置的各元素初始化为0XFF,初始化的元素数目与当前数组相同,其后的元素则要存入每一个第一次出现的字符串了。如果加大串表的长度可进一步提高压缩效率,但会降低解码速度。
B. 压缩方法
了解压缩方法时,先要了解几个名词,一是字符流,二是代码流,三是当前码,四是当前前缀。字符流是源文件文件中未经压缩的文件数据;代码流是压缩后写入文件的压缩文件数据;当前码是从字符流中刚刚读入的字符;当前前缀是刚读入字符前面的字符。
文件在压缩时,不论文件字符位数是多少,均要将颜色值按字节的单位放入代码流中,每个字节均表示一种颜色。虽然在源文件文件中用一个字节表示16色、4色、2色时会出现4位或更多位的浪费(因为用一个字节中的4位就可以表示16色),但用LZW 压缩法时可回收字节中的空闲位。在压缩时,先从字符流中读取第一个字符作为当前前缀,再取第二个字符作为当前码,当前前缀与当前码构成第一个基本字符串(如当前前缀为A,当前码为B则此字符串即为AB),查串表,此时肯定不会找到同样字符串,则将此字符串写入串表,当前前缀写入前缀数组,当前码写入当前数组,并将当前前缀送入代码流,当前码放入当前前缀,接着读取下一个字符,该字符即为当前码了,此时又形成了一个新的基本字符串 (若当前码为C,则此基本字符串为BC),查串表,若有此串,则丢弃当前前缀中的值,用该串在串表中的位置代码(即下标)作为当前前缀,再读取下一个字符作为当前码,形成新的基本字符串,直到整个文件压缩完成。由此可看出,在压缩时,前缀数组中的值就是代码流中的字符,大于字符数目的代码肯定表示一个字符串,而小于或等于字符数目的代码即为字符本身。
C. 清除码
事实上压缩一个文件时,常常要对串表进行多次初始化,往往文件中出现的第一次出现的基本字符串个数会超过4096个,在压缩过程中只要字符串的长度超过了4096,就要将当前前缀和当前码输入代码流,并向代码流中加入一个清除码,初始化串表,继续按上述方法进行压缩。
D. 结束码
当所有压缩完成后,就向代码流中输出一个文件结束码,其值为字符数加1,在256色文件中,结束码为257。
E. 字节空间回收
在文件输出的代码流中的数据,除了以数据包的形式存放之外,所有的代码均按单位存贮,样就有效的节省了存贮空间。这如同4位彩色(16色)的文件,按字节存放时,只能利用其中的4位,另外的4位就浪费了,可按位存贮时,每个字节就可以存放两个颜色代码了。事实上在 文件中,使用了一种可变数的存贮方法,由压缩过程可看出,串表前缀数组中各元素的值颁是有规律的,以256色的文件中,第258-511元素中值的范围是0-510 ,正好可用9位的二进制数表示,第512-1023元素中值的范围是0-1022,正好可用10位的二进制数表示,第1024-2047 元素中值的范围是0-2046,正好用11位的二进制数表示,第2048-4095元素中值的范围是0-4094,正好用12位的二进制数表示。用可变位数存贮代码时,基础位数为文件字符位数加1,随着代码数的增加,位数也在加大,直到位数超过为12(此时字符串表中的字符串个数正好为2 的12次方,即4096个)。 其基本方法是:每向代码流加入一个字符,就要判别此字符所在串在串表中的位置(即下标)是否超过2的当前位数次方,一旦超过,位数加1。如在4位文件中,对于刚开始的代码按5位存贮,第一个字节的低5位放第一个代码,高三位为第二个代码的低3位,第二个字节的低2位放第二个代码的高两位,依次类推。对于8位(256色)的文件,其基础位数就为9,一个代码最小要放在两个字节。
F. 压缩范围
以下为文件编码实例,如果留心您会发现这是一种奇妙的编码方法,同时为什么在压缩完成后不再需要串表,而且还在解码时根据代码流信息能重新创建串表。
字 符 串: 1,2,1,1,1,1,2,3,4,1,2,3,4,5,9,…
当 前 码: 2,1,1,1,1,2,3,4,1,2,3,4,5,9,…
当前前缀: 1,2,1,1,260,1,258,3,4,1,258,262,4,5,…
当前数组: 2,1,1, 1, 3,4,1, 4,5,9,…
数组下标: 258,259,260,261,262,263,264,265,266,267,…
代 码 流: 1,2,1,260,258,3,4,262,4,5,…
3. 测试文档
说明:
当选择时请选择1-3的数据,如果选了其他的数据就出错了。
4. 使用文档
在进入程序后,通过选择是压缩、解压缩还是退出程序。
压缩文件:
1)提示:“Input file name?” 输入:D:\cc\test.txt
2)提示:“Compressed file name?” 输入:test.lzw
3)显示:“Compressing………” 及 “*”表示文件压缩的进度。
说明:如果输入的文件不存在,将会重复提示,直到输入正确文件位置和文件名。生成的test.lzw将会存放在程序所在的根目录下。
如:程序放在D:\cc\下,则生成文件也在D:\cc\.
解压缩:
1)提示:“Input file name?” 输入:test.lzw
2)提示:“Compressed file name?” 输入:test.txt
3)显示:“Expand………” 及 “*”表示文件解压缩的进度。
说明:如果输入的文件不存在,将会重复提示,直到输入正确文件位置和文件名。生成的test.lzw将会存放在程序所在的根目录下。
ANI(APPlicedon Startins Hour Glass)文件是 MS-Windows的动画光标文件,其文件扩展名为“.ani”。它一般由四部分构成:文字说明区、信息区、时间控制区和数据区,即 ACONLIST块。anih块、rate块和 LIST块。
以下就是作为例子的文件内容(数据E)及ANI文件标准结构图(图):
1. 从(0000-006D)是 Wnd0WS 95& NT ANI文件的文字说明区部分
如你想对你开发的ANI文件提供一点文字说明,并加入你的版权信息,且同时它们又要被ANI文件播放软件承认时,这是你唯一的选择。要是你觉得这样做很麻烦,或者没什么好写时,那你完全可以去掉本块中的全部内容,并将块的大小置为0。切记,“块识别码
‘ ACONLIST’”和标识“块的大小”这两部分,共计 12字节,绝对不能被更改、移动及删除,否则后果自负。
可能为了让文字说明信息系统化,在ACONLIST块内部包容了若干子块,本例中用到的两个分别是:INFOINAM块(提供本文件的解释说明)和IART块(用于插入版本信息)。说实在,诸位可以运用在 AVI文件中插入自定义块的方法,加入自己的自定义块,其结果只是ANI播放软件把它当作一个“JUNK”罢了。
0000-0003:多媒体文件识别码:RIFF
0004-0007;文件大小( 2052h字节)-8字节
0008- 000F: ACONLIST块识别码,它是文字说明区开始的标志
0010-0013:ACONLIST块的大小(5Ah字节)
0014-001B:INFOINAM块识别码,标志文件说明信息子块的开始
001C- 001F: INFOINAM块的大小( 20h字节)
0020-003F :文件说明信息子块的内容“Application startingHour Glass”
0040-0043:IART块识别码,标志版权说明信息于决的开始
0044-0047:IART块的大小(26h字节)
0048- 006D:版权说明信息于块的内容“Microsoft Corporation,Copyright 1995”
2.从(006E-0099)?
如何制作各种游戏补丁…
游戏修改器制作-黑客入门
工具:SoftICE、金山游侠2002、VC++7.0、PE查看器、SPY++
测试平台:Window2000
Professional
SP2
首先我介绍一下将会用到的工具:
1、
SoftICE(不用多说了吧,我想你应该会用)
2、
金山游侠2002(这个你也应该会用)
3、
VC++7.0(不要求你一定会用,但至少应该会一种编程工具)
4、
PE查看器(你可以随意找一个,没有也没关系,用SoftICE查看)
5、
SPY++(VC里的一个查看程序信息的工具,你可以和别的,比如Delphi和C++Builder的WinSight32)
然后就是你应该会的知识:
1、
汇编基础
2、
一些编程基础
3、
PE文件结构的基础
看看黑客怎么玩游戏
黑客们玩不玩游戏我不知道,不过他们显然更喜欢捣鼓代码(这里的黑客是指真正的Hacker,研究代码的效率和问题等等方面的,而不是那些用别人现成的工具到处做破坏的初级cracker)
黑客是怎么玩游戏的
不玩,他们的游戏就是按组织的命令到处执行干涉国际或国内的黑客行动,当然也分高级和低级,比如低级的ddos攻击。
网友评论
最新评论
,先从字符流中读取第一个字符作为当前前缀,再取第二个字符作为当前码,当前前缀与当前码构成第一个基本字符串(如当前前缀为A,当前码为B则此字符串即为AB),查串表,此时肯定不会找到同样字符串,则将此字符串写入串表,当前前缀写入前缀数组,当前码写入当前数组,并将当前前
件的文字说明区部分 如你想对你开发的ANI文件提供一点文字说明,并加入你的版权信息,且同时它们又要被ANI文件播放软件承认时,这是你唯一的选择。要是你觉得这样做很麻烦,或者没什么好写时,那你完全可以去掉本块中的全部内容,并将块的大小置为0。切记,“块识别码 ‘
一个下标,就可确定它所存贮的基本字符串,所以在数据压缩时,用下标代替基本字符串。一般串表大小为4096个字节(即2 的12次方),这意味着一个串表中最多能存贮4096个基本字符串,在初始化时根据文件中字符数目多少,将串表中起始位置的字节均赋以数字,通常当前数组中的