csdn开发高手09 文件类型:PDF/Adobe Acrobat 文件大小:字节
更多搜索:
Windows开发 Java
.Net 数据库 算法
普及开发知识 提高开发技术 交流开发经验 享受开发乐趣
著名游戏修改软件整人专家作者李果兆《游戏修改历史》
外挂开发元老的现身之作《外挂开发大揭密》
多位专业游戏研发者联合推出《反外挂战略体系浅析》
中国大陆反外挂第一人林阜民专访《游戏反外挂的法律维权和未来发展》
联合打造
实战应用 纯粹技术
本期优惠价
www.csdn.net/magazine 1投稿信箱:tougao@csdn.net
生于下半月
—— 致读者的一封公开信(代发刊词)
《CSDN开发高手》消息发布后,引起了很大的反响,众多读者和网友纷纷来信或发表评论,
对新杂志的定位,名称及两本杂志的发展方向提出了很多中肯的意见和改进建议.论坛上长长
的帖子,言简意赅而语意深长的网友发言,都让我们深受感动,也更感自身责任重大.
首先感谢大家对我们始终一致的关注,支持与厚爱.《程序员》经过三年的发展,已经得
到了广大读者的认可,大家也对我们提出了更多更高的希望,但是限于篇幅和定位,一本杂志
很难满足广大读者的需求,我们经过精心的准备,从9月份开始,对《程序员》杂志进行扩容
和提速.
对今后的杂志发展,我们有如下规划:
一,两本杂志内容定位各有侧重,形成互补
《程序员》将继续保持其综合性,产业性和技术性的特点,重视产业,人文,管理和技术四大
内容.在原基础上,《程序员》将做一些重大内容调整,加强文章的深度,提高实用性和指导性.
人物&报道:从技术视角,关注中国软件的发展与创新,报道产业中最具活力,最新的人
物和事件
这部分内容是我们杂志的传统强项.我们将继续强化这个版块,捕捉产业界发展的最新动
态,及时响应重大事件,追踪技术名人,进行系统化的纵深报导.另外,我们会逐渐强化评论
功能,提高交互性,鼓励广大读者参与其中.
管理:加强实践方法的探讨与应用,强调企业和项目实战案例的剖析与挖掘
随着软件产业的逐渐成熟,管理和软件工程越来越重要.为了顺应这一潮流,伴随我们的
读者一起成长,我们将逐渐加大在管理和软件工程方面的力度,突出中国特色,注重调查研究,
加强实践方法的探讨与应用,重视国内企业和项目实战案例的挖掘与剖析,与读者一起探索一
条实实在在的软件企业管理与软件工程之路.
技术:关注技术趋势,企业开发,深度应用.
程序以技术为本,《程序员》杂志深深认识到这一点.我们的技术板块一向走高端路线,偏
重技术前瞻,关注新技术,探讨技术趋势.未来我们将继续坚持这条路线,但是会更加注意结
合实际,关注实践,帮助读者掌握第一手的趋势性技术资讯,开拓技术视野,融入全球性技术
文化.
《CSDN开发高手》将是一本注重实战的纯技术杂志,她的宗旨是:普及开发知识,提高开发
技术,交流开发经验,享受开发乐趣.她以帮助读者更迅速,更有效地提高开发水平,提升个
人价值为已任.
杂志内容将分为特别专题,技术专区,特色专栏以及学习&文化四大部分.致力于实用技
术与技术实践.
特别专题:每期杂志将推出一个特别专题,围绕一个热点开发技术,分层次,多角度地深
入探讨.
技术专区:针对目前最重要的几个技术方向,汇集国内外知名技术专家和CSDN技术高手们
的智慧和经验,伴随程序员的学习成长.
2 csdn 开发高手 2003.09
特色专栏:作为《CSDN开发高手》特别奉献给读者的栏目,"特色专栏"倾注了编辑部和大
量"外援","顾问"的心血.我们力图以新鲜,精彩,交互性强的新形式,新风格,做出实用,
好看的栏目.
我们也深知要做好这样的栏目,难度很大,因此我们特别期待有更多的专家能参与,把您
的经验,研究所得与读者一起分享.
源码赏析:有经验的程序员都知道,提高编程技术的最好办法,就是通过阅读大量的经典
源码,就象好的作家必须阅读前辈的著作,吸取写作的营养一样.
经典名著《莱昂氏UNIX源码分析》造就了整整一代黑客高手,成为编程历史中的传奇.今
天各种高水平的开源软件随处可见,但是又有多少人去仔细读过这些代码 去体会高手的心血
之作呢
我们相信,源码学习不在多而在精,与其贪多,不如细细品味,反复赏析,实力就会在不
知不觉中增长!
软件克隆:优秀的软件,都至少拥有一项超越一般软件的功能,只有不断追求卓越的软件,
才能获得最终的成功.你一定会在使用软件过程中被某项特色功能所震撼,或者为某个特性而
着迷.程序员之不同于普通用户,就在于我们不仅仅停留在感叹上,而是会考虑How和Why,在
解析和实现中体味成功的快乐."软件克隆"专栏就是要为大家揭密软件精彩的内部奥秘,通过
实际动手提高你的实践能力.
大话Design:编程能力有三要素:算法,技术与设计.国内程序员普遍重视技术,疏于算法,
而荒于设计.软件的实现,通常有多条道路可选,高手设计之道,在于简洁,在于深刻."大话
Design"通过轻松活泼的对话,以纪实风格向大家展示真实的设计过程,生动而富有启发性.
二,两本杂志的上市时间
调整后,两本杂志上市时间分别为每月的月初和月中.
《程序员》将固定为每月1日发行;
《CSDN开发高手》固定为每月15日发行.
三,技术专刊合集出版
除上述两本综合性杂志外,很多读者希望看到专业技术领域的专刊(如Java, .NET),为此,
编辑部特别引进了国外6本著名技术期刊,即《Visual Studio Magazine》,《Java Pro》,《a .net PRO》,
《Delphi INFORMANT MAGAZINE》,《XML & WEB SERVICES》等.
这些一流的国际技术刊物,在其专业技术领域内,都有着很好的影响和口碑.它们内容精
彩,技术新颖,极受国内外读者的青睐.
我们将在10月一共推出多本汇集国外期刊2002-2003精彩文章的技术专刊中文合集,同时,
我们也非常期待国内技术专家在这些专业方向给我们撰文投稿.
一份杂志的创刊,发展与提升,就如同一个新生命的诞生和成长一样,离不开所有喜欢她,
帮助她的朋友,我们期待着大家的支持,帮助与参与!
本刊编辑部
2003.9.1
www.csdn.net/magazine 3投稿信箱:tougao@csdn.net
目 录
CONTENTS
技术专区
生于下半月 ——致读者的一封公开信
本期游戏外挂专题将从技术,社会,法律等各个方面,把关于外挂的最真实情况展示给读者,让读者自己去做这个简单而复杂的受
力分析,最后结果如何,相信每个人心中都会有自己的***.
漫谈游戏修改历史 llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll 9
本文作者为台湾知名游戏修改软件作者李国兆先生.他以幽默的笔调将近十年来PC机上游戏修改历史与发展变迁为你娓娓道来.从
最初DOS下的PCTOOLS到FPE,GB4……再到如今Windows下FPE2000;从当初单机游戏到如今网络游戏.修改工具的发展史也就是
一部PC游戏的进化史.
网络协议分析 llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll 14
现在国内最热的互联网应用莫过于网络游戏,其发展已大大超过单机以及局域网游戏,但也因此成为众多破解高手的目标.制作外
挂的第一步就是进行网络协议的分析.看看本文是如何对一个知名棋牌类网络游戏的通讯协议进行分析的.
外挂开发大揭密lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll 16
本文详细向大家介绍各种类型外挂的工作原理,并详细介绍其中主流的几种外挂的开发方式,读者可以通过这篇文章彻底解除对外
挂原理的神秘感.
反外挂战略体系浅析llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll 24
有矛就有盾,如何反外挂是摆在现在所有网络游戏公司面前的一个重要议题.面对种种外挂,单一的防护手段是无济于事的,必须
建立一套综合有效的战略体系.这也正是本文所要阐述的观点.
网星高层外挂专访lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll 26
网星史克威尔艾尼克斯网络科技有限公司(简称网星)是一家国内知名的网络游戏营运商,旗下有著名的网络游戏:魔力宝贝.今年
五月,网星举办了以"绿色网游新世界"为主题的系列反外挂活动,随即掀起了国内反外挂高潮.《CSDN开发高手》也对网星负责人林
阜民进行了一次采访.
发刊词
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll6程序员说事
特别专题
游戏外挂之前世今生
算法与基础
关于学习C++和编程的50个观点(2003修订版)lll 28
"Kingofark关于C++和编程的50个观点"是网上流传很广的
一篇趣文.不久前,作者秉承与时俱进的思想,修订了这篇文章.
它是更有趣了,还是更喋喋不休了 感兴趣的读者不妨看看.
关于Ks50PV修订版的对话lllllllllllllllllllllllllllllll 32
看了"Kingofark关于C++和编程的50个观点"的最新修订
版,再来看看这篇对话.通常对话的主角都是大师,高手,大老
板,而kingofark不过是一名普通的网友.如果你相信像你一样的
普通网友也能成为对话的主角,不妨看看这篇有趣的文章.
运用设计模式设计MIME编码类
——兼谈Template Method和Strategy模式的区别lllllll 35
"设计模式好,就是不知道用在哪里",这是很多程序员共同
的烦恼.这篇文章的作者是个有心人,不仅在一个日常项目中运
用了模式,而且还对Template Method模式和Strategy模式进行了
比较,看看他的感悟能否给你以启发.
Windows开发
Delphi.NET前瞻llllllllllllllllllllllllllllllllllllllllllllllll 39
"聪明的程序员用Delphi",当年这句口号把一大批聪明的程序
员变成了Delphi Fa ,而Delphi又成功的把一大批程序员变成了
今天的"高手"..NET时代来临之后,Delphi又将向何处去 今天
聪明的程序员应该怎么走Delphi之路 请看这篇精彩文章.
4 csdn 开发高手 2003.09
目 录
CONTENTS
面向扩展的应用程序系统插件篇llllllllllllllllllllllll 46
通常,杂志里是不愿意放太多代码的,本篇却是一个例外.
该文的确是一篇难得的好文.如果你对Photoshop,Acrobat之类
软件无穷无尽的扩展能力感到羡慕 那就耐下性子好好阅读这
篇文章吧.
Java Learning Path——带你走上Java开发之路lllll 52
想想自己多年以前学习Java时所走的弯路,就知道这篇文
章的意义.难得作者能够将他宝贵的学习经验写出来和我们大家
分享.作者从学习Java的工具,书籍,学习过程,学习方法以及
学习资源等五个方面给我们作了全面的介绍.即便你是个Java老
手,这篇文章也许能让你发现你遗漏的知识点哦.
采用扩展机制增强Java平台llllllllllllllllllllllllllll 58
如何让我们自己所写的类就像Java平台提供的核心类一样,
在此平台上部署的所有应用程序都可以像使用Java核心类那样直
接使用它们,从而增强Java平台的功能.作者通过分析Java类
运行机制,告诉了我们扩展方法.通过实例让我们明白,JDK的
确是一个开放的,不断发展的应用开发包.
通过标签库实现Java Web编程中的Se ion管理lllll 61
一个简单的se ion管理,方法当然有多种,看看作者怎样用
标签库(Taglib)来实现吧.对于j 编程,不用java bea 和标
签库,这样的j 程序可以说是毫无意义,因为Taglib和java bean
才是j 编程的精华……
从VB到VB.net——VB6程序员如何转向.NETllllllll 66
只有VB程序员才真正知道从VB6转向VB.NET的痛苦!这
篇文章介绍了VB.NET作为完全面向对象编程语言的一些新特
性,比较了VB6和VB.NET之间的区别,试图从新功能和一些
相关概念上扫清我们转向道路上的障碍……..
在C#Builder中使用ADO.NETlllllllllllllllllllllllllllll 73
用于Microsoft .NET Framework的 Borland C#Builder为企
业数据库提供了创建企业级ADO.NET数据库的应用程序.尽管
Borland Data Provider for ADO.NET为大量的主要企业级数据库
提供了高性能本地支持,使开发更加快速,方便,且更具灵活性,
然而BDP并不包含在C#Builde个人版中.看看作者怎样用"plain
(纯代码)ADO.NET"的方式来进行MSDE数据库的操作吧.
详解Attlibutes lllllllllllllllllllllllllllllllllllllllllllll 76
Attributes(属性)作为一种说明性信息,在各类应用中十分常
见.作者讲述了如何生成开发自定义属性并将它附加到各种应用
程序项中,以及如何在运行时环境中检索属性信息.
数据库设计经验谈系列之:数据对象的命名 llllllll 81
这是一组数据库设计经验谈系列的第一篇文章.一切从命名
开始,作者在分析了目前数据库设计中数据对象命名混乱的原
因,以及可能对项目实施维护造成的影响之后,向读者介绍了一
些自己在数据库设计过程中的一些良好的命名规范和习惯.
Oracle8i与MS SQL SERVER之比较 lllllllllllllllllllll 83
对于开发者,几乎没有一个不喜欢在同类产品中进行比较
的,不管是开发工具还是数据库系统.诚然,有些比较的确毫无
意义,然而DBMS可能不一样,原因就在于这些DBMS本身就有
很大的不同,不管是概念上还是体系结构上.看看作者对目前最
流行的两大数据库产品的比较吧.
技术专区
特色专栏
高手的风范——淡妆浓抹总相宜
一本好的程序开发的书籍,其中示例代码的质量也应该是作
者精雕细琢而成.《Windows核心编程》就是这样的一本好书.
其第一个示例代码"Hello,error",看似简单,但在Jeffref的精
心设计下,展示了一个完整的经典源码.
保龄球计分程序设计实践——《敏捷软件开发》精彩节选
相对于编程语言而言,设计是一门艺术.要想成为这门艺术
的高手,只有多思多想多实践.《CSDN开发高手》认为,只有实
践,才是提高设计能力的不二法门.本文就是从《敏捷软件开发》
一书中精选出的一个片断,亲自演示了一个采用XP进行编程的
具体实践,包括了结队编程,测试驱动的开发方法,重构等内容.
用c#实现弹出广告谋杀器——Popup Killer
对于上网时无穷无尽的弹出广告,你是不是想手起刀落,让
整个世界清静呢 文中详细讲述了如何运用C#实现Popup Killer.
一次惊心动魄的调试——都是"单线程"惹的祸
对于系统测试出现的"意外",想必很多程序员都不会陌生.
本文以生动的笔触描述了一次惊心动魄的调试过程,也为我们运
用多线程技术提供了很好的案例.
兵器谱
举重若轻的ASP.NET开发工具——Web Matrix
作为一个开发ASP.NET的开发工具,Web matrix与Visual
Studio.Net相比,有着体积小,免费,易用等优点.本文介绍了
该工具的一些优秀特性.
www.csdn.net/magazine 5投稿信箱:tougao@csdn.net
目 录
CONTENTS
计算机科学数学理论浅谈 llllllllllllllllllllllllllllllllllllllllll 107
计算机科学中的数学理论很庞杂.本文从数值计算,离散数学,数论,
计算理论四个方面对此进行了详细的描述.
面向对象设计思辩一则 llllllllllllllllllllllllllllllllllllllllll 111
面向对象设计中总是存在着各种各样的观点.对于C++Gotchas中
单根继承的问题,文章进行了大胆的思辩.
数据压缩技术简史 lllllllllllllllllllllllllllllllllllllllllllllllll 112
简单地说,如果没有数据压缩技术,我们就没法用WinRAR为Email
中的附件瘦身;如果没有数据压缩技术,从Internet上下载一部电影也许要
花半年的时间……电脑里的数据压缩不外有两大功用,第一,可以节省空
间.第二,可以减少对带宽的占用.可是,这一切究竟是如何实现的呢
数据压缩技术是如何从无到有发展起来的呢 且听本文作者细细道来.
声音与评论 lllllllllllllllllllllllllllllllllllllllllllllllllllllllllll 117
这个世界充满了各种各样有特色的声音,而且,在软件开发领域,竟然
更有那么多的精言妙语值得大家仔细体味.语言会随风而逝,评论会时过境
迁,但这个留言板却会随着时日永远留存下来,带给你一份别样的感受.
程序人生 lllllllllllllllllllllllllllllllllllllllllllllllllllllllllll 118
中学时,你用Basic来书写"HELLO WORLD";大学一年级时,你
用Pascal;大学高年级,你学会了Li …….那你知道,做了专业开发者,
当了编程大师,他们在写什么 看形形***的人生,看各式各样的职业,
你想知道黑客,新经理,高级经理,首席执行官都做些什么吗 请看这卷
"程序人生"的标准***.
Typedef一次搞掂
Dr. CSDN,是一个生动有趣的人.他从克莱登大学获得博士,算不
上资深程序员,入职也就是两三年的光景.才学虽不敏,但喜欢动脑筋,
有点子小聪明.读者如果有什么编程方面的问题,可以一古脑全扔给他,
他最喜欢替别人分忧了.尤其是小小的疑难杂症,一般都考不住他,当然
这也是他最得意之处了.猜猜,本期他的见面礼是什么
.NET网络资源库
这篇文章可是ccboy贡献给读者的锦囊库.他精选了网络上.NET的
最好资源.另外,编者本人曾一一访问过文中的站点,证实它们确实值得
大力推荐.网下的读者朋友们,如果你有好的收藏库,也请尽快告诉我们,
让大家一起来分享吧.
认证园地
应试绝招,帮你轻松过软考
金秋十月,软件水平和资格考试姗姗到来.急躁不安的考生们,如何
应考 如何答卷 如何保证成功率 且让本文作者现身说"法",帮你轻
松搞惦.
Amone信箱
固定栏目
(总第71期)下半月
主管单位
主办单位
协办单位
出版单位
总 编
社长\常务副总编
副 社 长
执行副总编
编 委 会
编 辑 部
责任编辑
华东记者站
华南记者站
美术编辑
电 话
投稿信箱
发行总监
电 话
信 箱
广告总监
电 话
信 箱
华南联络站
电 话
信 箱
读者服务部(邮购)
读者信箱
地 址
电 话
传 真
邮 购
国际刊号
国内刊号
邮发代号
印 刷
广告经营许可证号
网 址
出版日期
零 售 价
::::::::::::::::::::::::::::::::::::::
中国社会科学院
中国社会科学院文献信息中心
北京百联美达美数码科技有限公司
www.csdn.net
《程序员》杂志社
黄长著
张悦校
蒋 涛
熊池舟
黄长著 张悦校 陈洋彬 蒋 涛
熊池舟 唐 琦 曾登高
孟迎霞(主任)
汤 韬 闫 辉 韩 磊 郭红俊 宋志翔
熊 节(xiongjie@csdn.net)
张 里(zhangli@csdn.net)
关峻峰 孔祥利 吴志民
010-84540265
editor@csdn.net
俞 波
010-84540235
sales@csdn.net
唐 琦
010-84540265/36
adv@csdn.net market@csdn.net
刘 羽
020-61213341/42/43/44/45/46转918
hnoffice@csdn.net
reader@csdn.net
北京市朝阳区北三环东路8号
静安中心26层(100028)
010-84540262
010-84540263
读者服务部
ISSN 1672-3252
CN11-5038/G2
北京乾沣印刷有限公司
京东工商广字0188号
http://www.csdn.net/magazine
每月1日
人民币10.00元
csd gt; 107
6 csdn 开发高手 2003.09
1WEB是一张网,当你试图用它捕获信息时会发现网
眼太大了.幸好有RSS,我得以借助新闻聚合编织一张
小些的网——不过,要覆盖"天下"之大,恐怕就力不从
心了.在读者抱怨本栏目内容贫乏之前,我想推荐功能
强大的RSS新闻聚合工具——NewzCrawler.该工具的
1.5新版刚刚推出,不过,官方网站(http://www.
newzcrawler.com)只提供1.4共享版的下载.
好吧,我的网里出现的第一条鱼是随SQL Server
Yukon Beta1发行的.NET Framework 1.2 SDK开发
包.虽然微软没有大张旗鼓地宣传,好事者已经将它分
离出来供人下载.如果你热衷于追踪新技术,也许会想
一试,但绝对不要在正式运行的服务器上***,由此导
致的问题不会有人负责(在2.0整数版本发布之前,或
许我还要无数次重复这个忠告),已经有人吃过苦头了.
另外一条跟微软数据库产品有关的消息是MDAC
(Microsoft Data Acce Component)2.8发布,这东西
以前是包括在Windows Server 2003里面的,现在可以
作为单独组件下载***.
2002年引起轩然大波的.NET/Java平台生产力和运
行性能评估报告已经有了更新版本(http://www.
theserverside.com/home/thread.j thread_id
=20655&article_count=39).Middleware Company再
次甘冒天下之大不韪发布不利于Java平台的评估报告.
报告中宣称最好的J2EE Web Service实现速度也只能
达到.NET Web Service的29%.Java的拥趸和.NET
的反对者岂肯善罢甘休 看来一场论战已是在所难免,
不过显然Sun公司的注意力并不在此——在JavaOne
2003研讨会上,该公司副总裁和CTO均阐述了J2SE1.
5(Tiger)/J2EE发展计划.据称新版本Java平台将集中
于改善稳定性和易用性,对于开发人员而言可能"泛型,
autoboxing,元数据工具"等新特性更具吸引力.遗憾
的是我们得继续等待一年以上时间才能尝试这些令人心
动的特性..NET/Java平台之争不是一天两天了,这事
儿没法从技术上去判断.市场,只有市场才是最终裁决
者.真正的开发者不会一再询问"到底.NET和Java哪
个好"之类的问题.只要精通其中一种已足够让你得到
一份高薪工作.
Middleware的评估报告(部分)
本期大嘴 CSDN网站内容总监 韩磊
www.csdn.net/magazine 7投稿信箱:tougao@csdn.net
4在Port80 Software关于WEB服务器占有率的调查
中,微软IIS占到53.7%的份额.这个数字令人吃惊,不
过该调查是基于用户填表的,未经由权威机构认证,可
信度到底如何很难说.比较可靠的消息是Office2003发
布日期和价格已经确定;此前的测试版本流传甚广(显
然有人违反了测试用户授权条款),据说一些新的功能值
得一用.不过微软也有不开心的时候,最近的MSBlast
系列病毒应该很令MS烦心.先是"冲击波",后是打着
"冲击波杀手"招摇撞骗的变种病毒;Windows,你的名
字是弱者.不知道准备大举进军安全软件市场的MS,是
否会有些郁闷 另一个郁闷的是Novell,由于营收持续
下降,该公司不得不裁员10%.Netscape停止Mozilla开
发,转行在线教育——现在轮到我们郁闷了.正是:滚
滚长江东逝水,浪花淘尽英雄.在以火箭速度向前冲(有
时是向后退)的IT业,"明天"永远是未知数.
Nokia购买Sega游戏部门;AMD购买VIA 前Cyrix
Media-GX部门;Oracle宣布延长对PeopleSoft的收购
时限;被IBM成功收购的Rational宣称将执行改进产品
的宏伟战略(事实上该战略是两年前IBM投入4千万巨
资豪赌Ecli e开源项目的自然延续,Ecli e旨在集成
多个开发工具).在并购的叫嚷声甚嚣尘上之时,AOL却
要求母公司AOL时代华纳把名字中的"AOL"去掉——
看起来颇有些反讽的意味.天下大势,分久必合,是否
又会合久必分呢 IBM收购Rational,Borland收购
Together,Oracle欲图收购PeopleSoft,这还不只是简单
的合并.对于程序员,也许更该看到并购背后的东西.
"建模"已经成为开发界讨论的热点.如李维先生所言,
集成化开发应该会独领风骚.
好了,让我们关心一下纯技术的新闻吧.SourceForge
.net8月的Project of the Month是Boa Co tructor,一
个Python开发IDE工具,据作者称初衷是做一个Delphi
for Python.Python越来越受欢迎,开源社区中的人们
趋之若鹜,似乎将成为编程语言的另一王者.
SourceForge是著名的开源社区,近七万个开源项目在它
提供的平台上维护.在SourceForge上面,你甚至可以
找到与Janeva功能类似的Corba/.NET集成中间件.与
SourceForge的无私相比,SCO简直就是贪得无厌的山
洞怪人.在争夺Linux所有权的拉锯战中,SCO似乎有
恃无恐.该公司CEO Darl McBride在接受采访时,宣
称SCO诉IBM案若不在2005年之前开始审理,将对IBM
来自BlogCN的用户地区分布图
SourceForge.net:最大的开源社区
不利.自从SCO跳出来宣布"拥有"Linux后,股价已
经从1美元/股涨到10美元/股.Borland Delphi 8很
快会推出,神秘的Borland C++ Builder X渐渐开始
显露庐山真面目.它们的共同特点就是跨平台.前者可
用来开发Win32 Native应用和.NET应用,后者更是跨
越Win32,Linux和Solaris.
然而,现在最热门的,既不是病毒,也不是并购,甚
至不是厂商策划的,发布的,跳票的新版本产品,而是Blog
和RSS.我没有给出RSS的全称,因为它有好几种解释.
前几年的"频道","推"概念借尸还魂,真正开始为Internet
读者提供有效的内容定制服务.不用怀疑他会不会持久,
连MSDN都有了自己的各栏目RSS,还有什么好犹豫的
呢 如你所愿,很快CSDN.NET也会推出RSS客户端定
制.与此相关的新闻肯定会令方兴东博士兴奋——Blog一
词被收入牛津字典.从BlogCN的用户地区分布图上可以
看出这东西的火爆程度.由Blog引申出来的新词Moblog
在美加大停电期间大显神威,许多blogger通过手机把停
电现场情况抓拍下来发到自己的blog上.
本期"大嘴说事"到此结束,谢谢关注.如果读者
有更多热点新闻或流行话题,欢迎联系大嘴栏目:
bigmouth@csdn.net
8 csdn 开发高手 2003.09
特别专题
游戏外挂
游戏外挂
前世今生之
前世今生前世今生
小时候,拿着掌上黑白游戏机,与其说是我在玩游戏,不如说是游戏在玩我.大一
些了,面对ROM卡带游戏,我很快就习惯去询问种种秘笈.后来,部分卡带游戏有了密
码续玩功能,给了玩家以通关的捷径,而就在那时,《GAME集中营》上一篇名为《怎样
破译游戏节目中的密码》的文章,不仅在玩家中引起巨大反响,也直接促使国内第一个
专门研究游戏破译的工作室成立.那是什么时候 一九九五年.
接下来的几年,就是PC单机游戏逐步征服大陆玩家的日子,而修改游戏也成为玩
家的一种习惯,GB4和FPE成就了这样一道上抛线.
其实,一切都是发自人的本能,这么多年我们做着什么 只有一件事情:打破规
则,寻求刺激.找秘笈如此,破译密码如此,使用FPE也是如此,即便你只想快一点完
成游戏.
接下来,在我大学生涯的后期,郁闷许久的中国玩家终于等到了为之疯狂的电玩
新宠,网络游戏.网络游戏让真人成为游戏的对象,但已经习惯去打破规则的玩家们
并不会因此有所改变,那是由本能进化而来的习惯,也正是那道上抛线的动力.
然而,意外的是,这一次玩家们对规则的破坏,却给这道曲线带来了新的外力,外
力或许会让曲线变得更加优美,却也让本不平静的社会又多了一个麻烦,而这,就是
今天的主题:外挂问题.
本期外挂专题将从技术,社会,法律多个侧面,把关于外挂最真实的情况展示给
读者,让你自己去做这个简单而又复杂的受力分析,至于最后结果如何,我想每个人
心中都会有自己的***.
本刊特邀技术编辑 王轶男
www.csdn.net/magazine 9投稿信箱:tougao@csdn.net
特别专题
游戏外挂
所谓修改游戏,就是借由一些工具程序去修改游戏
存盘文件或内存,达成无敌或者打不死的最高境界.原
本游戏工作小组都会设定一些剧情及参数,让玩家一步
一步参与,不过我个人是比较喜欢当超人的,现实环境
中无法实现的事,由游戏来达成不是也挺好的吗
既然要修改游戏存盘文件或内存,就必须先了解PC
储存资料的基本方式(相信写过程序的人都知道) :
u内存上的地址观念:在IBM PC上的设计是低位对
应低地址的,所以比如十六进制的"12AB",就会
被存成"AB 12"这样.大部分内存和磁盘文件都
是这样去储存资料,不过有些工具会自行帮你转
换这些排列方式.
u游戏中使用的数据结构:一般来说屏幕上如果看
见10,内存中存放的方式是十六进制位的0A,不
过如果是BCD码就会存成十六进制的10或是0100.
此外还有其它数种编码方式.
u游戏中连续数值的排列:如果你在RPG游戏中看
到500/500这样的数字,那么在内存中它一般就
是500,500连续排在一起的.
DOS时代
在以前的DOS时代,依据修改的方式我们可以把游
戏修改分成下面四类:
u直接修改游戏存盘
u使用常驻修改程序(TSR)
u使用某游戏专用修改程序
u使用游戏内建的欺骗码(CHEAT CODE)
前面两类是通过搜寻要修改的目标数值,进而判断
出游戏储存这些目标数值的位置,然后对其加以改变就
行了,所以前两类工具的重点放在"搜寻"功能上.后
面两类工具的重点在于游戏程序设计师或者有闲心的人
漫 谈
u撰文/FPE之父 李果兆
针对特定游戏帮我们设计出方便的修改方法,这种设计
可能是基于预先分析出的修改地址自动完成修改,也可
能是直接向游戏实现嵌入修改服务,各种游戏都有不同
的专用修改程序或欺骗码.
一,直接修改游戏存盘
这是笔者看过的最早的游戏修改方式,当时游戏一
片要卖60元哦,不过当时游戏只是由简单的线条组成,
声光效果当然没有办法可以和现在比.但在那时候就已
经有杂志刊登 xxx 游戏要用PCTOOLS找ooo字符串
改成zzz这类的修改方法了,甚至有人去追踪游戏程序代
码,目的只是让游戏主角无敌而已.不过,现在除了要
对游戏进行破解外,已经没有人做这种事了,因为如今
游戏的规模通常很大,追踪起来会很累.如今进行程序
追踪使用的工具大都是SoftIce.
修改游戏存盘除了要研究存盘各位置的含义外,还
必须小心检查码.许多游戏程序设计师为了防止玩家乱
改游戏存盘,会把待存储的数据先经过一番逻辑运算之
后再存盘,这样就从很大程度提升了修改存盘的难度.
二,常驻型游戏修改程序(TSR)
话说当年在笔者还边看杂志边修改游戏存盘的时候,
一位笔者的死党带来了一份惊天地,泣鬼神的礼物....
陈伟谷先生所撰写的"电动克星5.19版",它的随呼随
到以及多功能修改真是令只会使用PCTOOLS的笔者眼
睛一亮,差点中风瘫痪.这就是笔者见过的第一个常驻
型游戏修改程序.不过,当时"电动克星"只支持单色
屏幕,而且只有高级扫瞄功能.但在那时"电动克星"已
经能够连续扫瞄01 02 03这样的字符串了,而且还能进
行如01 $1A 02 $1B这样的十进制,十六进制混合输
入,这比后来的一些游戏修改程序还要先进,笔者的FPE
(游戏修改至尊)就受到了它相当大的影响.
游 戏 修 改 历 史
10 csdn 开发高手 2003.09
特别专题
游戏外挂
这类游戏修改工具常驻于内存中,借由拦截键盘中
断(INT 9)抢得系统控制权,在需要的时候随传随到.常
驻修改工具可以记住所有符合当前修改条件的地址,我
们只要不断告诉常驻修改程序我们在屏幕上看到的数字
变化,它就能凭借这些信息,过滤掉部分地址,直到找到
完全正确的地址.比如笔者的FPE就是其中一种,其最
重要的功能就是搜寻.FPE的搜寻接口采用汇编语言语
法,如1,2,ah,'jaw',所以FPE中包含一个分析器去分
析玩家输入的资料格式,然后把它转换为一连串二进制,
再基于这串二进制对游戏内存进行核对.FPE还支持低
阶分析,也就是未知数分析,例如1,2, ,'jaw',+,1:100,
其中第一个问号表示那一格未知,加号表示相对之前情
况数值有增加,1:100表示该格数值范围在1到100之间.
为了能够实现这些特别控制,FPE会由分析器产生出一
个句柄串行,在进行游戏内存核对的时候,这些句柄会被
同时进行考虑.
继"电动克星"后,接下来就是这类常驻型游戏修改
工具的战国时期了,一大堆常驻修改工具纷纷出笼,其中
比较有名的有精讯出版且具有低阶分析能力的 GB4,小
弟我的FPE 2.5,雄中的GBP,可以改DOS/V的DGB,
加拿大的GW,兼具debug功能的GAMETOOLS等等.
不过,后来由于内存技术的翻新,出现了可以切入保护模
式的DOSEXTENDER,许多修改工具无法克服技术问题
而没有再出新版,最后只剩下GW32和FPE4.1a可以修
改保护模式的游戏了.
其实DOS Extender主要目的就是突破DOS 640k
的内存限制,但由于当时真实模式的CS:IP无法索引
1MB 以外的地址,这就造成常驻游戏修改程序相继阵亡.
FPE为了能够修改XMS/EMS内存,使用INT 16h对内
存进行搬移,把XMS/EMS一块一块搬回DOS 640k内
区域进行分析,计算对应地址,再通过INT 16h进行锁
定,这种技术在当时算是一项创举了.
后来,操作系统迈入Win95时代,FPE 5.0通过上
述技巧,加上一些兼容性调整,便成功修改了Win95下的
游戏,成为第一个能够修改Win95游戏的修改软件.FPE
除了能够修改游戏外,还加有一些额外功能进去,比如抓
图,阅览中文档案,听CD音乐,随时修改游戏存盘等.
撰写常驻程序有许多问题要注意,因为常驻修改程
序在游戏中需要随呼随到,所以其拦截键盘的能力,兼
容性以及稳定性都必须很好,此外还有DOS重入(INT
21h),重复调用,常驻内存大小,重设8259 IC以及XMS/
EMS支持等多方面问题.
PC设计中, CPU能够存取的东西都必须被存放在内
存内,包括指令及资料,所以能够修改整个内存的常驻型
修改程序,理论上就可以修改游戏中的所有东西了.不过,
这毕竟是理论,若游戏资料都以特异的格式进行存放,而
你又不是游戏的设计师,那又有什么办法 幸好大部分游
戏设计师都不会无聊到设计种种增加游戏开发难度的东西
去害自己.所以只要具备一定的经验,是可以改出一些新
奇又好玩的东西来的.下面笔者就举出一些修改技巧:
u一般来说,像RPG这种数值参数很多的游戏,游
戏程序设计师都喜欢把各种参数放在一起,比如
对于HP 200/200,MP 100/100,那么通常输入
"200,200,100,100"就可以一次找到正确的存放
地址,否则,可以试着改变一下资料型态.
u正如游戏存盘会被编码,屏幕上你所看到的资料
也可能会欺骗你哦,比如它在实际数值后面多加
一两个零,本来应该是10的就变成了100或1000,
这样在屏幕上会比较好看,但你分析的时候就需
要猜出原本的数值,这就是经验加运气的事情了.
三,某游戏专用修改程序
专用修改程序的历史就无从考据了,最早应该是发
GB4的十六色主界面,好难才截取到,若你是二十三岁以
上的PC玩家,或许这幅画面会勾起你的一段燃情往事吧
FPE2001
www.csdn.net/magazine 11投稿信箱:tougao@csdn.net
特别专题
游戏外挂
生在国外吧.这种程序大多是免费流传的,其工作原理
非常类似于PCTOOLS,先由某位热心的朋友帮你分析
出某个游戏的修改规则,然后他根据这个规则编写一个
自动完成修改的小程序,这样就不需要玩家再拿
PCTOOLS去改存盘,有部分游戏修改软件也可以自动
产生这类程序.正是这个原因,这类修改程序也没法用
在其它游戏中,"专用"就是这么来的.至于这些专用程
序具体修改的地方,从游戏存盘到内存甚至于游戏程序
代码都是可能的.
四,游戏内建的欺骗码(CHEAT CODE)
最早内建密技的游戏发生在电视游戏机上,相信玩过
任天堂的玩家对于"上上下下左右左右BABA"一定非常
熟悉,这也算是一种欺骗码.早期游戏机由于没有常驻修
改软件,游戏本身又被存放在不能修改的ROM中,而又
没有磁盘驱动器可以把它转录下来,使用欺骗码就成为唯
一修改游戏的方法了.而在PC上最早的欺骗码应该算是
"毁灭战士DOOM"的"IDDQD",按下去主角就立即成
为战神.那么,为什么输入IDDQD就会让主角无敌呢
这是由于游戏程序设计师故意加了这样一段程序代码在游
戏中,通常是为了辅助游戏的开发和除错,后来人们慢慢
感觉到这种欺骗码的存在可以增加游戏的多样性,所以现
在游戏大都被加入了各种欺骗码去实现穿墙,瞬间移动,
武器物品全满,换服装等各种奇特的功能,这些都让游戏
增加了乐趣.早期游戏杂志里用来刊登如何用PCTOOLS
修改游戏的板块到后来就都变成了刊登游戏欺骗码和怎样
利用游戏BUG达到变相修改游戏的专栏了.
窗口单机时代
接下来该谈谈现在的情况了.在Windows XP盛行的
今天,DOS下的常驻修改程序还能如过去一般帮助我们在
游戏中如鱼得水,虎虎生风吗 很抱歉,DOS下的常驻修
改软件到了Windows下便全挂了,因为Windows的内存
策略,资源管理方式和DOS截然不同.在Windows下已
经没有"常驻"这个概念,因为Windows系统具有多任务
特性,所以大多数游戏修改程序都把调用及切换工作交给
Windows去做,而自己则只做最核心的分析扫瞄工作.
目前大多数游戏修改软件都是利用WIN32的
debugging APIs,该APIs组合让程序员能够对另一
个进程内的逻辑内存进行读写.除了读写内存外,拦截
键盘消息也是一个重点,此时,DOS下那套拦截INT 9
的方法已经不能用了(除非你要写的是如SoftIce这种在
Windows加载前就得到执行的程序).在Win32平台上,
程序设计师需要编写一个动态链接库(DLL),然后利用
Win32的Hook API去把这个间谍函数库加载到游戏的
逻辑空间,让它去偷偷拦截键盘消息,当拦截到调用热
键时就触发修改程序内核.这里尤其要注意间谍函数库
与修改程序的沟通,解决办法有数种,我在FPE中采用
的是共享内存.此外,分析内存时的效率也非常值得注
意,因为低阶分析要同时扫描游戏的内存和硬盘档案,
此处你可以使用Win32提供的内存映像文件(Memory
Ma ing File)去加快存取速度.
网络时代
前面谈的都是单人单机游戏,但是目前最热门,最抢
手的游戏类型非网络游戏莫属,网络游戏把游戏对象由
原来笨笨死死的计算机改成尔虞我诈的人类,他可能是
你室友,邻居甚至是远在地球另一端的美国玩家,这种游
戏方式很快风靡大多数玩家.早期最受欢迎的网络游戏,
首推MUD(Multiple User Dime ion或Multiple User
Dungeon),简单来讲,它是一种多人文字角色扮演游戏.
它只有文字接口,你必须用想象力去画出画面来,不过在
其中你能够和真实的人物对谈,合作或PK(Player Killer
即玩家间的对战).由于早期CPU和内存太贵,所以信息
处理都集中在一台'主计算机'中,并执行多人多任务的
操作系统,像IBM大型主机操作系统Vax9k就是笔者接
触的第一个大型集中式系统.'那如果很多人要同时操作
怎么办 ',因为这个问题,就有了'终端机'这种东西,
它负责把主计算机的屏幕讯号显示在使用者的屏幕上,
并把使用者的操作讯号传回主计算机.终端机本身并不
执行指令,所有的运算都在主计算机内执行,MUD以及
BBS就是这样的架构.现在的'Telnet'就是利用你的个
人计算机(PC)来模拟终端机,当你用Netterm连接上
MUD时,看到的只是主计算机的执行画面.
所以,如果我们想修改MUD,通过修改PC本身的
内存,我们只能改到一些键盘命令,例如向左走改成向
右走,却没有办法改到真正关键的资料,除非侵入主计
算机修改,而侵入别人的计算机除了需要程序功力外,
还是违法的行为唷!
在CPU和内存价格大幅下降之后,具备运算能力的
12 csdn 开发高手 2003.09
特别专题
游戏外挂
PC日渐普遍,PC游戏也多了起来,于是有人想到了以
PC通过资料机和另一台PC联机,这样两部PC不就可
以对战了吗 这就是'点对点'方式的联机,两台PC具
备同等地位,如'魔兽争霸'及'终极动员令'等通过
IPX进行联机的游戏,就使用了点对点架构,由于没有
使用运算能力强大的主机及高速网络,这种构架只适合
于少数人的小规模对战.
如果想修改基于点对点架构的游戏资料,就得看这
个游戏是如何设计的了.大部分点对点游戏都会运用一
些资料检查技巧,来验证对方传过来的资料正不正确,不
正确的话就发送一个'同步错误'消息,然后结束程序.
所以,如何避开检查是修改这类游戏的重点,而这就要求
我们先了解游戏的检查机制,像有的游戏是用校验和
(checksum)的方式来对比传过来的资料,例如保存游戏金
钱数的内存内容为'02,01'(十进制为258),两个数值加
起来就是3,所以游戏可能会先把这个3存下来,这时如
果你把这两个数值改成'03,04',加起来就不等于3了,
于是游戏就会发现错误.避开这个检查的方法是把原来
的数值对调为'01,02',这样加起来还是3,不过数值却
变成了513(十进制),也就达到了修改游戏的目的.
后来Internet逐渐发达,虽然点对点游戏也搬上
Internet,但小规模对战无法满足那些喜欢一大群人混在
一起,杀来杀去的玩家们,于是有人想到了可以利用大
型主机强大的运算能力,通过快速网络专线去服务更多
的玩家.而这,就是当今线上游戏所采用的分布式'客
户端-服务器端'构架,如第一个国产线上游戏'万王
之王'就采用了这种架构.所谓的'客户端-服务器端'
架构和之前所说的'终端机-主计算机'相当类似,然
而,在今天游戏接口都是全图形显示情况下,若还照以
前那样把全部运算都交给主计算机去做,游戏速度便铁
定跟乌龟爬一般,所以有人就很聪明地把原来终端机的
地位换成PC,把部分运算交给PC去处理,主计算机
则负责协调及交换资料,这种架构下的PC就被称为
'客户端',而负担减轻后的主计算机就被叫做'服务
器'.为什么是'服务器'这个名称呢 因为它代表着
'一台随时等着为客户服务的机器',所以游戏公司的
服务器都是24小时全天候等待玩家联机过去,而联机
路径则由原来的内部网络变成了Internet.
目前来说,若想修改线上游戏主要有三种方式:
第一种就是老方法'侵入服务器偷改资料',但如同
前面所说,这除了需要你具备如'黑客帝国'中基努.李
维斯一般的侵入能力外,还要小心被***局逮捕!所以
笔者建议大家还是不要轻易尝试.
第二种方法就是用如WPE这种工具去拦截客户端传
出的资料,然后照我们的希望对它进行修改,再把这份
假的资料发送给服务器,不过如同前面'点对点'的问
题一样,服务器也会用种种检查方式来验证传送过来的
资料正不正确,而且其中还有许多不确定性,所以同样
困难重重.此外,发送假封包给别人的服务器还存在法
律问题,像前阵子美国就有一个人通过发送大量假封包
去干扰网站服务器,结果就被FBI逮捕了.
第三种方法以破解游戏程序中的游戏规则,或是找
出游戏保护机制的漏洞为主,如前一阵子的'加速器',
就是以破坏发送资料的速度来达到加速的目的.但是每
一个线上游戏的客户端程序都不同,而且游戏公司又非
常勤于改版,所以这类破解程序一般用很短时间之后就
没法用了.
此外,直接以'逆向工程'追踪破解别人的程序也
是违法的行为,目前很多游戏公司都在极积的取缔外挂
WPE PRO的主界面
WPE PRO的主界面
www.csdn.net/magazine 13投稿信箱:tougao@csdn.net
特别专题
游戏外挂
程序,例如很多挂在线上的 GM(Game Master)一旦看
到有疑似外挂的行为就会直接踢人.所以,身为正人君
子的笔者,是从来不会考虑采用这种方式去修改游戏的.
'讲来讲去都是破解,侵入的方法,难道没有其它比
较合法的方法吗 '有的!所谓山不转水转,这里先介
绍一个名词'宏(Macro)'.所谓的宏就是把一连串功能
集合成一个功能,例如要在线上游戏'龙族'中进行练
功的话,需要'把鼠标移到木桩上',然后'按下鼠标左
键',这样你的角色就会打一下木桩来增加功力,把这两
个动作集合在一起,就成了'练功宏'了.
或许你会问:'一直重复执行练功这个宏,不就可以
一直练功了吗 '没错,但是我们却面临其它问题,例如
'刀子钝了怎么办 ','有人偷袭我怎么办 ','力气用
尽了怎么办 '.目前市面上已经有了几个提供宏功能的
程序,虽然它们可以让主角重复执行一个宏,但同样都无
法处理上述问题,此外,因为它们都是针对标准窗口应用
软件设计的,对于DirectX全屏幕游戏也存在很大问题.
接下来重头戏就登场了,游戏修改软件'FPE 2001'
的'机器人'就是改良自宏的解决方案,利用机器人可
以实现各种全自动功能.FPE采用的方式为'录制'和
'播放',我们先操作一遍所需要执行的动作,如前面练
功的步骤'把鼠标移到木桩上','按下鼠标左键',FPE
就会把这些步骤录制成一组机器人,然后就可以在任何
时间,任何地点,通过FPE播放出来,当然也可以循环
播放而达到一直练功的效果.FPE最厉害的地方是,你
可以另外录制两组'补充法力'以及'离线'的机器人,
这样我们可以用一组'练功'的机器人帮我们打木桩练
功,我们自己跑去睡觉,然后当FPE发现你的法力用完,
就会启动第二组机器人'补充法力'来帮你进行补充,但
就在此时若有个坏蛋跑来偷袭你,那么FPE就会发现你
的体力在下降,便启动第三组机器人'离线'去帮助你
关闭程序.在你呼呼大睡的同时,FPE已经帮你做了这
么多事情,是不是觉得很神奇
其实FPE机器人的工作原理就是拦截各种键盘鼠标
消息,把它们储存下来并在需要的时候进行回放.所以
前面所说的间谍函数库就非常重要了,它必须能够精确
控制各种消息并且接受修改程序的指令,包括播放时机,
播放方式,启动及停止时机这些都必须控制得宜.
未完成的任务
有人说玩家永远是老大,玩家总是希望用最省力的
方法去做更多的事情.由于机器人必须配合各种网络速
度,所以发放速度无法加快,这显然无法满足玩家快速
成功的愿望.另一个问题就是很多线上游戏练功所打的
对象并不是静止的木桩,许多都需要攻击怪兽或是会移
动的NPC,要完成这项需求就需要用影像辨识或是其它
能够分析出移动坐标的方法,这又是另一项大课题了.
笔者目前正在研究解决这类问题,希望不久以后可以造
福更多"苦海无边"的玩家!
李国兆简介
台湾著名的FPE系列游戏修改工具的作者.FPE
具有"悠久"的历史,早在DOS年代,FPE就以
其强大的内存扫描功能以及对键盘和鼠标有效的拦
截能力,而得到众多游戏爱好者的青睐.进入到了
Windows时代,众多DOS下的修改工具已无力延
续其辉煌.而FPE却经过几次版本更新后,又重
新回到了焕发了青春活力.
(接27页)问:目前中国的外挂情况
比较严重,请问你对国内网游产业
的前景是否看好
林:个人来说,前景我是看好
的.关于盗版这个问题,光盘都掌
握在盗版商那里,并没有其他机构
介入,只要他们破掉了软件,接下
来工作就太好做了.而线上游戏就
不一样,服务器是放在游戏公司这
边,而且游戏公司本身又有源代码,
只要这两个方面不削弱,基本就会
保持某种优势,这样产业就会慢慢
起来.你知道为什么那些程序员去
做外挂 因为他们没有出路,因为
他们买的产品跟青菜萝卜一样的价,
怎样去获取暴利,只能去做外挂.或
许你觉得那样不错,的确有钱赚,但
实际是错的,那样叫做短多长空,利
益是短暂的.反之,若游戏产业起来
了,需要更多的优秀程序员参与,这
些程序员就可以进来,让产业更加
壮大.就像我这里有些程序员,他们
过去是怀才不遇,因为没有环境去
给他们很好从事这个行业,或者他
努力很久,念到清华,出来搞程序,
工资只有三千,他会感到很不平衡.
那怎么办,只好去做外挂.像在国
外,特别是游戏开发程序员,他们在
公司里的地位和待遇都非常高,现
在就需要我们去把这个观念扶正.
14 csdn 开发高手 2003.09
特别专题
游戏外挂
记得刚到大学时,和大家一起玩的第一件事就是打
牌,相信很多人都会有这个经历;我也是在那时候学会
"升级"("拖拉机")的.
大二时曾经疯狂玩过,所以对"升级"一直情有
独衷;但工作后,一方面找不到足够的人,另一方面
就算找到人了也不能像以前一样通宵的去玩.不过,一
次看到别人在网上玩联众的"升级",呵呵,此后不怕
找不到人了,工作之余可以随时和别人玩一下,过一
把瘾.
现在转入正题,对于做外挂,以前没有做过,因为
没有很多时间,所以也没有在网上去详细的找相关的资
料,如果哪一位有这方面资料,不妨与大家共享一下.
一,数据的获取
1,对于动作游戏类:可以通过API发命令给窗口或
API控制鼠标,键盘等,使游戏里的人物进行移动或者
攻击,这个是对于本地游戏而言的,网上有很多这方面
的介绍,在这里就不再写了.
2,截获消息:通过hook技术,获得与游戏相关的
数据,之后就看你自己怎么处理这些数据了.
3,拦截socket包:要替换winSock.dll或者
wi ock32.dll,我们写的替换函数要和原来的函数一致
才行,就是说它的函数输出什么样的,我们也要输出什么
样子的函数,而且参数,参数顺序都要一致,然后在我们
的函数里面调用原始的winSock32.dll里面的函数就可
以了.当游戏进行的时候它会调用我们的动态库,然后从
我们的动态库中处理完毕后才跳转到真正动态库的函数
地址,这样我们就可以在里面处理自己的数据了;不过
这种方法要自已重新去写.如下例子所示:
winSock32.dll里有很多函数,要自己一个一个的
替换,岂不是很累,况且这个动态库还是公用的,万一
哪一个地方写错了,就会造成很严重的问题,所以建议
不要采用这种方法.
4,直接***网络数据包:这个方法与 iffer和
comview所用的技术差不多,不过我们并不要直接去监
听到网络层或网络层以下几层的数据包,只要到IP层的
就可以了.
5,利用 Raw Socket(原始套接字):它来发送和
接收IP层以上的原始数据包,如ICMP,TCP,UDP等,
一般的游戏数据量不大的话多采用TCP协议传输数据,
如某某网络游戏的"升级"就是这样,而泡泡堂采用的
是UDP发送的,数据量很大.关于这种方法介绍大家看
一篇文章(http://web.nyist.net/~shadowstar/e ay/
security/ iffer1.html),会有很大的帮助,同时要感谢
作者(shadowstar)提供了这么好的文章,我也从中得到不
少帮助.
下面是我写的一段数据接收和分离出来的IP包的程
...........
nIpRevLen = recv( pCtlSocket-m_socket, cIpRevBuff,
MAX_COMMAND_SIZE - 24, 0 ) ;
catch( ... )
if( nIpRevLen == SOCKET_ERROR ) continue ;
IP * p_ip = ( IP * )cIpRevBuff ;
TCP * p_tcp = ( TCP * )(cIpRevBuff + IP_HdrLen( p_ip)) ;
if( p_ip-DstAddr != pCtlSocket-addr_in.
sin_addr.S_un.S_addr ) continue ;
file://这句和下一句过滤其它不要的包
if( p_ip-Protocol != IPPROTO_TCP ) continue;
int nSrcPort = ntohs( p_tcp-SrcPort ) ;
if( nSrcPort != PORT_DODZ ) continue ;
char * pPackConten = ( char * )p_tcp + TCP_HdrLen(
p_tcp ) ;
file://这里就是得到了包的内容了
nPackLen = ntohs( p_ip-TotalLen ) - IP_HdrLen(
p_ip ) - TCP_HdrLen( p_tcp ) ;
file://这个是包的长度
...........
u云网
网络游戏的协议 分析
www.csdn.net/magazine 15投稿信箱:tougao@csdn.net
特别专题
游戏外挂
二,数据的协议分析
下面来分析一下"升级"游戏的协议,本来自己接
收到数据,就可以把数据写下来,不过还是用别人的现
成工具会更好一点,在这里我用的是comview3.3来接收
数据的,这个工具还是很好用的,建议大家可以下载一
个去用一下试一试;下面是一些接收到的数据:
0x000005 02 00 00 22 00 00 00-00 20 00 00 C1 00 00 00....".... .. ..
0x001000 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00...............
0x002006 00 00 00 67 67 2E 68-74 6D 05 02 00 00 23 00....gg.htm...#.
0x003000 00 01 20 00 00 46 00-00 00 00 00 00 00 00 00... ..F.........
0x004000 00 00 00 00 00 00 00-00 00 07 00 00 00 67 67.............gg
0x00502E 68 74 6D 6C.html
像这样的数据,相信谁都会搞不清楚是什么东西,
不过不怀疑有一些天才可以异想天开,不过要从原始数
据来分析别人的协议确实要一些灵感的.好像是在为自
己吹嘘,不好意思了.....不过呢,协议的分析要与实际
的操作结合起来,如果你不会玩"升级",很难想像你会
很容易分析出别人的协议来.还好我自己在这方面还不
错,在游戏"升级"中是一个小官员的级别了.
我们可以想一下游戏整个流程,登录,进入游戏室,
找到玩家,发牌,扣底,出牌和结束.有了这样一个流
程在脑子中可以帮助想象每一个数据的信息.
我用的是一个比较笨的方法,让这个过程和接收到
的数据合在一起来分析:
1,启动comview或其它的接收数据包的工具,设
置好过滤条件,只接收IP/TCP包,目标IP是自己的机
器,如果不设置这些条件,网络的大量数据包就全部被
你接受到了,如果要从几万个包中找出你所要的数据,
太难了吧……
2,接着就启动网络游戏,进入"升级"(为了分析
这些协议,我总被人家说慢得像乌龟,还失去了很多
分),这时你就可要注意收集数据了,记下当前状态,什
么时候叫牌,反牌,得分,很多数据都要记录下来,同
时还要想着如何出牌才能赢,要不真有些对不起和你一
起玩的对家了.
3,有了数据,分析协议就有了着手的地方,我们先
看下面的一段数据:
0x000000 02 00 80 F0 00 00 00-01 00 00 00 04 00 02 00... ..........
0x001000 00 00 00 63 61 6F 77-65 69 5F 30 30 31 30 00....ddddd_0010.
0x002011 20 00 00 18 00 00 00-67 79 75 67 68 00 00 00. ......dddd...
从这里可以看到,ddddd_0010(原始数据不是这个,
我修改了)与一起玩的名称是不是一样呢 如果是一样的就
好了,这个可是服务器返回来的与你一起玩的玩家信息.
如果你做过SCOKET方面的编程,你会知道一个包
的大体结构.包的大致结构是:应用包头标志;包序列
号;整个包的长度;CRC校验(或累加和校验);命令
字;数据体长度;数据体.
网络上的数据并不像我们想象的那样,发一个包出
去,就会在对方接下整个包,很多时候会分几次才能接
收下来整个完整的包.我们再看一个包:
0x000010 20 00 80 24 00 00 00-D9 54 DF 77 01 00 00 00. . $... T w....
0x001001 00 00 00 00 00 00 00-03 00 00 00 00 00 00 00...............
0x002003 00 00 00 01 00 00 00-01 00 00 00 17 71 40 00............q@.
这两个包有什么相同之处,就是包头开始的8个字
节,是不是可以看出来一个包的整体结构了,注意网络
数据格式转换为机器数据格式的话要反转一下,MSDN
上可以找到类似这样的函数ntohl,ntohs,htonl和
hto ,所以我们在看数据时也要把字倒转一下.
如果你了解的话,0x80是作为一个回应包的标识,
这样我们就可以看到两个命令字:
80 00 00 02 十六进制表示 : 0x80000002
80 00 20 10 0x80002010
这两个命令都不同,可以看到,协议上并没有统计
的应用包头标志,直接从命令字开始了.有了上面的概
念,接下来的自然就是长度,因为第一个包不完整,我
们看第二个包,一般长度用两个字节就可以了,但会有
用四个字节的,也就是一个int类型的值,第二个包的长
度不难看到就是0x24,假设长度使用四个字节,那么内
容就应该是D9 54....71 40 00,0x24=36,我们计算
一下,刚好就是这个长度,呵呵,到现在你和我一样,了
解包的结构形式了,我们正在一步步的往成功的方向去
了……
到了这一步,大家也差不多可以动手自己去分析一下
协议了,因为某些原因,我在这里就不再往下分析各个命
令字的具体作用了,不过可以告诉大家0x80000002是用户
登录后服务器返回来的所有玩家信息,注意一下,我们在
注册用户时,最长的登录名称不能超过19个字节,所以包
就加上一个结束符,成为20个字节.
上面的分析只是一个引子,由于本人水平有限,有
什么错误的地方请大家指出,让我们共同学习.
16 csdn 开发高手 2003.09
特别专题
游戏外挂
如果我没记错的话,第一个图形MUD应该就是UO
(网络创世纪)了,那时候就有同学寄光盘过来,问我能不
能开发个UO的外挂,那也是我第一次听到"外挂"这
个说法.到了去年,网络游戏的赚钱效应开始广为人知,
于是便造成了目前网络游戏异常火爆的局面,有人甚至
把网络游戏称为中国IT业的救命稻草,各大门户网站也
开始进军网络游戏市场,同时,一直伴随着网络游戏成
长起来的产物,也就是本文的主角-外挂,便也浮出水
面.当然,主流网络媒体对外挂都是一片喊打声,但外
挂到底是好是坏 这个问题我觉得应当由玩家来裁决,
而不是游戏运营商,也不是外挂开发者,因为他们都有
利益在其中,自然无法说出客观的话来.当然,本文不
是要去讨论这个容易引起争论的问题,本文的目的只是
去探讨外挂的技术原理,试着从技术角度去揭开外挂开
发的神秘面纱.
外挂的定义
外挂到底该如何去定义,什么样的软件叫做外挂
目前,这个问题还没有哪位IT权威人士给我们一个确切
的说法,若按某网络游戏运营商在打击外挂时所给的定
义,就是未经授权的,第三方开发的,对某游戏软件的
功能进行修改,扩充的程序.其实,即使你不玩网络游
戏,你也会经常接触到外挂程序,比如以前Win95刚出
来的时候,市面上出现的中文之星这类中文平台,就是
通过拦截Windows操作系统的API去实现自动翻译,内
码转换等功能,他们也属于外挂,不过是Windows的外
挂.类似还有金山词霸,各种病毒防火墙,网络防火墙,
他们也都采用类似技术,时时刻刻监控着用户计算机内
的内存和网络封包,去实现各种功能,他们同样没有得
到被监控程序开发方的授权,按前面的定义,这些软件
也算外挂,至于像FPE这类游戏修改工具就更不用说了.
所以,我觉得外挂本身并不是一个贬义词,外挂就是在
没有特定软件的源码的情况下,通过高超的技术手段,
实现对此软件进行功能扩展的一种程序.至于外挂是否
u撰文/蓝色天蝎
外挂开发大密揭
非法,应该看程序是否对使用者造成损害(比如木马,病
毒,盗取帐号这些就是明显的破坏行为),而不应该针对
某种技术手段去定义.本文所讲的外挂,专指那些针对
网络游戏进行功能扩展的程序,因为我实在想不到其他
名词来形容这类程序,这里只好沿用旧习,大家也都习
惯那样去称呼.
外挂的历史
从第一款图形MUD网络创世纪诞生以来,网游外
挂也就随之而生,之后出来的每款游戏,只要有玩家基
础,都会有一些玩家兼程序高手开发出相应的外挂来,
因为游戏总是没有办法设计到尽善尽美,不同的网络游
戏运营商对游戏不合理之处的修改往往又有一定的滞后
性,甚至一些游戏运营商为了延长玩家的在线时间,人
为制造一些繁琐的操作放在游戏中,因此,外挂程序也
就有了它出现的理由.存在即是合理的,有了需求,自
然就会出现供应者.不过在刚开始,外挂大都是以免费
形式传播的,当网络三国出来后,部分外挂开发者开始
以共享软件的形式,通过收取注册费去卖外挂,于是,中
国的程序员从此又发现了一个新的赚钱领域.网络三国
之后,金庸,石器,传奇等游戏又创造了好几个开发外
挂而一夜爆富的故事,遗憾的是在众多外挂开发者中,
大部分人都没有把自己赚到的第一桶金用在正确的地方,
这又是题外话了,暂且不表.
外挂开发的境界
我个人把外挂按技术实现手段,分为了4种.为什
么标题称其为"境界"而不是"种类"呢 那是因为每
种外挂的实现难度是递进的,对开发者功力的要求也同
样呈正比例上升.
第一层境界:模拟键盘,鼠标操作,"蜻蜓点水"
这种可以说是最简单的外挂了,最初出现的外挂很
多都属于这种境界,要写这种程序无非就是摆弄几个
www.csdn.net/magazine 17投稿信箱:tougao@csdn.net
特别专题
游戏外挂
Windows的键盘鼠标相关APIs.由于以前网络游戏的界
面按钮位置大都是固定的,所以这些外挂用起来还是满
有效的,不过现在很多新的网络游戏为了防止这种外挂,
界面位置会随机出现,所以这种外挂的用武之地也越来
越小.此类软件的杰出代表:按键精灵.
第二层境界:强行修改游戏数据及代码,"霸
王硬上弓"
这种外挂目前最为普遍,一般都是通过将自己的
程序注入到游戏进程,然后修改游戏的数据和代码来
实现各种功能.现在网上有很多人说这招对网络游戏
已经没用了,其实不然,原因只是他们的功力不够.在
将自己的程序注入目标程序之后,几乎就可以为所欲
为,通过逆向分析游戏程序,甚至可以直接在游戏中
调用游戏相关的子程序段来实现任何想要实现的功能
(逆向分析出相关函数的功能,参数以及地址之后,定
义函数指针指向该函数的地址,接下来的调用就和调
用普通函数没任何差别了).不过,这种方式的缺点就
是工作量太大,游戏一旦更新,就得重新分析程序,找
到大量相关地址(函数地址,数据地址),这些都对外挂
作者的逆向分析以及汇编功力要求很高,而且外挂功
能越多,外挂作者更新一次就越吐血,要更新此类程
序需要有极大的动力才行(金钱 ).此类软件的代表:
传奇的大部分外挂,金庸早期的外挂(极差,神行)以及
奇迹的大部分外挂.
第三层境界:拦截游戏封包,"四两拨千斤"
目前的网络游戏都是瘦客户端,玩家发送相关操作
命令给服务器运算,服务器运算完后把结果返回给客户
端显示,之间都是把数据打包通过TCP/IP协议来传输,
只要拦截到这些数据,进行解密分析之后,通过修改数
据包,再进行发送,就可以实现大部分功能.拦截数据
包的方法有很多种,下面列举常用的几种:
1.代理服务器形式:把游戏连接服务器的地址修改
为自己写的代理服务器程序的地址以及***端口,
代理服务器会对封包进行过滤和修改,之后再转
发给真正的服务器端,服务器端返回的信息也是
以同样方式处理.
2.API HOOK:基于Windows的游戏都要通过Wi ock APIs
来发送和接收数据,所以只要把相关函数(Send,
Recv)拦截,就可以实现封包的修改和伪造.
3.SPI:使用SPI可以在比API HOOK更低一层的层次上
拦截相关Wi ock APIs.不过由于其特性,它更适
合用在防火墙类的软件中,用来做网游外挂反而
不大适合,因为它需要对注册表进行修改,而且
对系统的影响是全局的,稍有不慎,就可能造成
用户网络访问出错,而且外挂使用者一般都喜欢绿
色软件,不喜欢那些对注册表动手动脚的程序.
拦截数据包只是最基本的一步,做到这步是不够的,
因为游戏的封包一般都有经过加密,而且你还需要解开
游戏的一些秘密(相关的数据结构,物品地图格式什么
的),此时逆向分析技术又派上用场了.这部分和第二层
境界的要求是一样的,所以做外挂最关键的还是看汇编
功力.不过,采用这种方式,软件更新起来就要比第二
种境界轻松许多,只要游戏的通信协议格式不变,封包
加密算法不变,基本上都不用什么更新,要添加功能也
更容易.此类软件代表:金庸代理等.
第四层境界:脱离游戏,"任我驰骋"
在达到了第三境界,在你对游戏的通信协议了如指
掌以后,自然会有一个念头:为什么我不自己开发一个客
户端呢 只要封包格式兼容游戏,不用游戏客户端照样
也能和服务器通讯,实现想要的功能,于是,脱离游戏独
立运行的机器人程序就诞生了.这层境界又是建立在第
三层之上,第三层境界要求你熟悉Wi ock编程,有深
厚的汇编功力,到了第四层,就要加上深厚的编程功力
了,你不但要对数据结构和算法很熟悉,还要对面向对象
编程,软件工程都有了解,因为写一个取代游戏客户端的
程序代码量很大,一般都在两万行以上,其中涉及到的知
识已经和开发一个游戏所需的知识有很多重合之处(除了
图形编程方面不要求),像数据结构和算法(图,树,深度
优先广度优先这些),脚本,寻路以及其他许多AI技术都
要用到,同时还需要利用上面第三层境界的技术写一个
自己的封包查看器,这样才能开始分析利用封包.编写此
类软件的工作量很大,一个人完成已经有些吃力,所以得
开始采用建模分析和团队开发.此类软件代表:网三工作
狂,网金也疯狂,魔力挂机MM等.
第五层境界:
不是说只有四层,怎么又多出来一个 其实这是我
前一阵忽然冒出来的想法,在写完机器人程序之后,忽
然想到既然对游戏的通讯协议了如指掌,自己也已经写
18 csdn 开发高手 2003.09
特别专题
游戏外挂
了一个客户端,为何我不自己开发一个服务器端,封包
格式兼容游戏,这样不就可以开设私服了吗 于是,我
便兴冲冲动手搞了一个端口服务器模型(纯粹一时冲动,
所以也没做任何可行性分析),设计了一个服务器集群架
构草图,完成之后继续下一步时却发现这可不是普通的
工程,以个人之力几乎是不可完成的任务,因为游戏的
逻辑太复杂,要实现和游戏一摸一样的逻辑的话,再加
上地图解密,游戏物品,图形ID解密,还有服务器负载
均衡,架构设计……给我一个五个人的团队,或许我可
以做到……我有五个人的团队吗 没有,所以,我只好
把它当作一个设想摆在一边了.如果哪位看官对此有兴
趣,可以来找我,我们也来搞个公开源码的服务器模拟
器协同开发小组…J
直面外挂开发
在大概介绍完外挂的种类之后,我们终于可以转入
正题,具体探讨各种外挂的实现了.由于篇幅的关系,这
里我将集中讨论第二层和第三层这两种最常见的外挂实
现方式,现在市面上的外挂有90%属于这两种.第一种
太容易,程序员翻翻平台SDK与鼠标键盘相关的APIs就
大概能做出来了,而第四种又太复杂,说起来恐怕几天
都说不完.其实市面上很多游戏的外挂都是第二和第三
两种方法的并用,有些功能若单单拦截封包是没办法实
现的,你不得不修改游戏代码才可能(比如传奇的显示血
条,雷达功能)
外挂开发初步,注入目标进程
不管是第二种还是第三种方法,这一步都是必须的,
你先得注入目标进程,才可以为所欲为.注入其他进程
有好几种方法,各自的优缺点在Jeffrey Richter写的
《Windows核心编程》一书里已经有过经典权威的论述,
这本书相信是每个Windows程序员案头必备的,所以我
就不多废话了.在下面的示例中,我采用的是最常用的
SetWindowsHookEx这种方法,也就是消息钩子.和其
他地方介绍不一样的是,为了实现底层逻辑和应用逻辑
分开,在本例子中我使用了两个DLL文件,一个专门负
责SetWindowsHookEx,挂勾成功后,再在运行于目标
线程中的GetMsgProc回调函数中加载真正的应用DLL,
然后用UnhookWindowsHookEx卸载自己.真正对游戏
进行功能扩充的是在GetMsgProc回调函数中被加载的应
用DLL.这样做有什么好处呢 因为对游戏功能扩充的
应用DLL一般都很复杂,而用钩子注入的DLL如果直接
处理这些逻辑的话,一旦出错就容易影响整个系统的稳
定(主要针对Win9X/ME),所以专门弄一个DLL负责注
入,注入成功之后再卸载挂钩,就有助于程序的稳定性.
下面是负责注入的DLL的核心代码:
// 这个单元必须用VC编译
// vcin.c :负责注入应用DLL的DLL文件
#include "stdafx.h"
#include "vcin.h"
co t char DllPath[]="d:\\myprog\\vcin\\call\\test.dll";
// 要注入的应用DLL模块位置
#pragma data_seg("Shared")
HHOOK g_hhook = NULL;
HINSTANCE g_hi tDll = NULL;
#pragma data_seg()
#pragma comment(linker, "/section:Shared,rws")
HINSTANCE g_shi tDll = NULL;
//////////////////////////////////////////////////////
BOOL APIE***Y DllMain(HINSTANCE hi tDll,DWORD fdwReason,PVOID fImpLoad)
switch (fdwReason)
case DLL_PROCESS_ATTACH:
g_shi tDll = hi tDll;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
return TRUE;
//////////////////////////////////////////////////////
void LoadUserDll()
if (!g_hi tDll)
g_hi tDll = LoadLibrary(DllPath);
//加载成功,卸载钩子
if (g_hi tDll)
SetMsgHook(0);
retur }
//////////////////////////////////////////////////////
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam,LPARAM lParam)
static BOOL fFirstTime = TRUE;
if (fFirstTime) // 第一次运行,加载主功能DLL
www.csdn.net/magazine 19投稿信箱:tougao@csdn.net
特别专题
游戏外挂
fFirstTime = FALSE;
LoadUserDll();
return(CallNextHookEx(g_hhook,nCode,wParam, lParam));
//////////////////////////////////////////////////////
// 设置和取消钩子的函数,dwThreadId=0表示要取消钩子
BOOL WINAPI SetMsgHook(DWORD dwThreadId)
BOOL fOk = FALSE;
if (dwThreadId != 0)
if (g_hhook == NULL)
// ***钩子
g_hhook = SetWindowsHookEx(WH_GETMESSAGE,
GetMsgProc, g_shi tDll, dwThreadId);
fOk = (g_hhook != NULL);
if (fOk)
// 向目标程序发送一条消息,激活GetMsgProc
fOk=PostThreadMe age(dwThreadId,WM_NULL,0,0);
fOk = true;
// 钩子是否已经***好
if (g_hhook != NULL)
fOk = UnhookWindowsHookEx(g_hhook);
g_hhook = NULL;
fOk = false;
return fOk;
// vcin.h
#define VCIN_API extern "C" __decl ec(dllexport)
VCIN_API BOOL WINAPI SetMsgHook(DWORD dwThreadId);
此外,还要有个主程序调用上面编译成的DLL中的
SetMsgHook函数来实现功能的激活,一般这个主程序
就是商业外挂中常见的登录窗口,登陆成功后就执行
SetMsgHook,加载运行SetMsgHook的函数实现:
typedef BOOL WINAPI (*MYHOOKFUNC)(DWORD dwThreadId);
/////////////////////////////////////////////////////
void __fastcall TForm1::Button1Click(TObject *Sender)
HINSTANCE hDLL;
String DllPath;
HWND TagWindow;
DWORD TagThreadId;
DllPath = ExtractFilePath(A lication-ExeName)+"vcin.dll";
hDLL = LoadLibrary(DllPath.c_str());
if (hDLL)
Hookfunc=(MYHOOKFUNC)GetProcAddre (hDLL,"_SetMsgHook@4");
if (Hookfunc)
TagWindow=FindWindow("游戏的窗口类名",NULL);
// 也可以查找游戏的窗口标题
TagThreadId = GetWindowThreadProce Id(TagWindow,NULL);
if (TagThreadId) Hookfunc(TagThreadId);
解释一下上面的代码,vcin.c 主要是用来完成设置
钩子,加载应用DLL这些任务.在SetMsgHook中,程序
根据传入的线程ID,对此线程进行挂钩,挂钩完成后,该
线程第一次调用GetMe age时,就会先运行GetMsgProc
这个回调函数,GetMsgProc里面的代码已经是在目标线
程里面运行的了,所以这里我们可以完成加载真正的应用
DLL的动作.在确认应用DLL被加载成功之后,任务完
成,就可以把自己卸载掉了.SetMsgHook按extern"C"
方式导出,这样可以供Delphi或BCB等编译器调用.此
处要注意的是,g_hhook因为需要跨进程访问,所以利用
#pragma data_seg("Shared")的VC编译器功能进行支持,
如果要将vcin.c 在BCB下面进行编译,得用内存映射
文件来实现全局共享变量g_hhook(主要针对Win9x/Me,
在Win2000下系统会自己维护钩子的句柄).在调用的主
程序示例中,通过查找游戏窗口,从而获得游戏主线程的
线程ID,然后就可以调用负责注入DLL的挂钩函数,是
不是很简单呢 此处还有一个问题,就是游戏窗口的类名
如何去获得 这个问题更简单,我们只需要反编译游戏的
窗口进行分析,具体的分析技巧我会在后面讲到,此外,
你也可以用SPY++等工具进行查看.
好了,做完了第一步,我们还得提供一个应用DLL
的示例,应用DLL就是个你可以自由发挥的海阔天空的
地方,因为是在游戏的主线程中运行,所以你可以像主
人一样访问游戏进程中的任何资源,执行游戏的任何一
个函数(当然你要知道函数的调用方式以及参数).同时,
你也可以用SetWindowLong函数去子类化游戏的主消息
函数处理过程,这样就可以掌握整个程序的消息控制权.
下面的示例代码很简单,就是在应用DLL加载的时候,
创建一个以游戏主窗口为父窗口的子窗口.过去经常在
论坛上看到有人问如何在游戏中显示自己的窗口,其实
20 csdn 开发高手 2003.09
特别专题
游戏外挂
说破不值钱,就这么简单:
int WINAPI DllEntryPoint(HINSTANCE hi t, u igned long
reason,void*lpReserved)
HWND TagWindow;
switch (reason)
case DLL_PROCESS_ATTACH:
// DLL第一次映射到进程的地址空间的时候
TagWindow = FindWindow("游戏的窗口类名",NULL);
// 也可以查找游戏的窗口标题
if (TagWindow)
A lication-Handle = TagWindow;
A lication-CreateForm(__cla id(TForm2), &Form2);
// VCL创建窗口的代码
//显示窗口,由于窗口在游戏进程中,父窗口又是游戏主窗
口,所以可以在游戏中显示与隐藏
Form2-Show();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
return TRUE;
上面的程序虽然简单,但基本就是一个外挂程序的
主要框架,同时也是第二和第三种境界外挂共同的基础.
两种外挂的区分就在于应用DLL的编写方法,第二种境
界把ReadProce Memory,WriteProce Memory和函数
指针发挥到极至,随意修改内存中的数据和代码,调用
游戏程序的相关函数,其基本方法在《程序员》2001年
2期的《跨越内存禁区,修改游戏数据》中有比较详细的
论述,这里就省略了.那么第三种境界呢 则是需要你
了解Wi ock编程,还必须把游戏的Send和Recv函数
挂上,从而紧紧把握住游戏数据通讯的七寸咽喉,挂钩
API的方法在程序员2001年2期的《编写Win32 API钩
子》一文有详细讲述,这里再次略过.下面的重点是放
在少有人提及,如何对游戏进行逆向分析这部分内容上,
没有逆向分析这一步,即使你搭成了外挂程序的架子也
全然没用,外挂具体功能实现全部要靠分析游戏程序来
实现.
外挂开发的主活,分析程序和封包
分析程序和封包,需要借助一些静态反编译工具,
比如W32Dasm,IDA,还有动态调试软件SoftIce或者
TRW2000等.静态反编译工具主要用来分析代码和静态
数据,动态调试软件则可以用来获得一些动态的数据,
观察程序的运行流程,这两类工具在逆向分析中都是必
须的.下面,我就是简单介绍几个常见的分析方法,同
时谈谈一个著名网络游戏(匿名)的解密封包程序的分析和
模拟过程,这些内容都假设读者对静态反编译工具以及
动态调试软件有一定使用经验.
分析示例一:寻找游戏窗口的类名,窗口标题名以及窗
口消息处理函数
意义:有了窗口类名和标题,我们可以轻易找到窗
口句柄,才可以用各种Windows API对它进行操作.找
到了消息处理函数,我们就可以用SetWindowLong函数
去子类化该窗口,在游戏代码高一级的地方,优先处理
我们感兴趣的消息.
思路:VC写的游戏比较容易分析,因为VC程序都
是标准的SDK风格,创建窗口的步骤简单固定,当然被
MFC封装的程序要麻烦些,不过有哪个游戏会用MFC
来写呢 所以,我们若要分析VC写的游戏,先找到
CreateWindowEx函数的调用,就可以知道开头那两个
我们感兴趣的东西了:
HWND CreateWindowEx(
DWORD dwExStyle,//extended window style
LPCTSTR lpCla Name,//pointer to registered cla name
LPCTSTR lpWindowName,//pointer to window name
DWORD dwStyle,//window style
int x,//horizontal position of window
int y,//vertical position of window
int nWidth,//window width
int nHeight,//window height
HWND hWndParent,//handle to parent or owner window
HMENU hMenu,//handle to menu, or child-
window identifier
HINSTANCE hI tance,//handle to a lication i tance
LPVOID lpParam//pointer to window-creation data
相应汇编代码一般是这样的:
push0; lpParam
pushedx; hI tance
movedx, [e +20h+Rect.top]
push0; hMenu
subeax, edx
movedx, ds:Y
push0; hWndParent
pusheax; nHeight
moveax, [e +2Ch+Rect.left]
subecx, eax
moveax, ds:X
pushecx; nWidth
www.csdn.net/magazine 21投稿信箱:tougao@csdn.net
特别专题
游戏外挂
pushedx; Y
pusheax; X
loc_4372F0:
pushesi; dwStyle
pushoffset aWindowsName; lpWindowName,这里和下面就
是我们要的东西
pushoffset aWindowsName; lpCla Name
push0; dwExStyle
callCreateWindowExA
movds:hWnd, eax
要查找窗口处理消息回调函数,要在ATOM
RegisterCla (CONST WNDCLASS *lpWndCla )上
着手:
typedef struct _WNDCLASS { // wc
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HANDLE hI tance;
HICON hIco HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR l zMenuName;
LPCTSTR l zCla Name;
} WNDCLASS;
汇编代码一般是这样:
push67h; lpIconName
pushesi; hI tance
movds:stru_807E60.style, 1008h
; 我们要的东西在下面,loc_437590就是窗口消息函数的实际地址
movds:stru_807E60.lpfnWndProc, offset loc_437590
movds:stru_807E60.cbClsExtra, 0
movds:stru_807E60.cbWndExtra, 0
movds:stru_807E60.hI tance, esi
callLoadIconA
push65h; lpCursorName
pushesi; hI tance
movds:stru_807E60.hIcon, eax
callLoadCursorA
push4; int
movds:stru_807E60.hCursor, eax
callGetStockObject
pushoffset stru_807E60; lpWndCla movds:stru_807E60.hbrBackground, eax
movds:stru_807E60.l zMenuName, 0
movds:stru_807E60.l zCla Name,offset aDo_ii ;"窗口类名"
callRegisterCla A
如果是用Delphi或BCB写程序,情况会麻烦一点,
因为VCL层层封装,但如果利DeDe这个工具的话,情
况就完全改观.DeDe可以让你获得不亚于Delphi或BCB
集成开发环境的可读性(当然对汇编要熟),结果反而是分
析用Delphi或BCB写的游戏程序来得更轻松,正应了
"工欲善其事,必先利其器"这句老话,合理的应用工具,
会让你事半功倍!
分析示例二:现在,我们真***实弹地拿一个网络游戏的
解密封包函数来做分析.此处分析的解密
函数只针对该游戏某一个版本,不一定适
用在最新版本上,据说此游戏不久就会停
止运营,这也是选择它的一个原因.
意义:我们知道,在做第三种境界的外挂时,封包
的加密解密是我们必须面对的一个问题,只要搞定了这
个问题,一个外挂就呼之欲出.什么! 你说游戏没有
加密封包 呵呵,这种美事应该不会经常发生,据我所
知,目前只有RO(仙境传说)采用的明码包,结果当然是
外挂满天飞.
思路:首先,我们要找到游戏相应的加解密函数.按
照经验,一般都是在Send数据之前进行加密,Recv数
据之后进行解密,所以第一步要先定位Send和Recv函
数,这个和定位其他Windows API函数一样容易.完
成定位之后,就要观察一下它们附近的代码,如果是直
接进行加解密处理(最原始方式),那你可要谢天谢地,因
为目前大部分游戏都不是这么简单,很多游戏都采用了
队列方式,也就是在Recv接收到数据之后,不直接进行
处理,而是根据通讯协议拆好封包后,将单个封包(未解
密)扔到队列中,然后用一个定时器处理封包队列(当然时
间间隔很短).发送同理,一般是接收到用户操作指令后,
将命令打包后扔到发送队列,然后用定时器进行发送,
基于这种情况,查找就会麻烦些,此时要重点关注
timeGetTime或者GetTickCount函数附近的代码,此时
需要的是经验,耐心以及SoftIce的辅助.下面就是我靠
经验和耐心,找到的一段解密代码(当然,为了便于查看,
函数名已经被我改过) :
decryptproc near; CODE XREF: sub_45B22C+48 p
; CODE:0045B328 p ...
var_28= dword ptr -28h; 局部变量
var_23= byte ptr -23h
var_22= byte ptr -22h
var_21= byte ptr -21h
var_20= dword ptr -20h
var_1C= dword ptr -1Ch
var_18= dword ptr -18h
var_14= dword ptr -14h
var_10= dword ptr -10h
var_C= dword ptr -0Ch
var_8= dword ptr -8
var_4= dword ptr -4
pushe move , e adde , 0FFFFFFD8h
pushebx
pushesi
22 csdn 开发高手 2003.09
特别专题
游戏外挂
pushedi
mov[e +var_C], ecx; MaxLen
mov[e +var_8],edx ; 解密数据存放地址指针
mov[e +var_4], eax ; 待解密数据存放地址指针
moveax, [e +var_4]
call@@LStrAddRef;__linkproc__ LStrAddRef
xoreax, eax
pushe pushoffset aSVI_LxN@ ;
pushdword ptr fs:[eax]
movfs:[eax], e xoreax, eax
pushe pushoffset loc_45B1FB
pushdword ptr fs:[eax] ; 异常保护
movfs:[eax], e moveax, [e +var_4]
callunknown_li ame_7;取得数据长度(Delphi String形式)
mov[e +var_14], eax ; 初始化各个局部变量
mov[e +var_18], 2
xoreax, eax
mov[e +var_1C], eax
xoreax, eax
mov[e +var_20], eax
mov[e +var_22], 0
moveax, [e +var_14]
testeax, eax
jleloc_45B1E7
mov[e +var_28], eax
mov[e +var_10], 1
loc_45B13B: ; 解密过程
moveax, [e +var_4]
movedx, [e +var_10]
movzxeax, byte ptr [eax+edx-1]
subeax, 3Ch
j hort loc_45B15C
moveax, [e +var_4]
movedx, [e +var_10]
moval, [eax+edx-1]
subal, 3Ch
mov[e +var_21], al
jm hort loc_45B166
;------------------------------------
loc_45B15C: ; CODE XREF: decrypt+79 j
xoreax, eax
mov[e +var_20], eax
jmploc_45B1E7
;------------------------------------
loc_45B166: ; CODE XREF: decrypt+8A j
moveax, [e +var_20]
cmpeax, [e +var_C]
jgeshort loc_45B1E7
moveax, [e +var_1C]
addeax, 6
cmpeax, 8
jlshort loc_45B1BC
movecx, 6
subecx, [e +var_18]
moval, [e +var_21]
andal, 3Fh
andeax, 0FFh
shreax, cl
oral, [e +var_22]
mov[e +var_23], al
moveax, [e +var_8]
movedx, [e +var_20]
movcl, [e +var_23]
mov[eax+edx], cl
inc[e +var_20]
xoreax, eax
mov[e +var_1C], eax
cmp[e +var_18], 6
jgeshort loc_45B1B3
add[e +var_18], 2
jm hort loc_45B1BC
;------------------------------------
loc_45B1B3: ; CODE XREF: decrypt+DB j
mov[e +var_18], 2
jm hort loc_45B1DB
;------------------------------------
loc_45B1BC:; CODE XREF: decrypt+A7 j decrypt+E1 j
movecx, [e +var_18]
moval, [e +var_21]
shlal, cl
movedx, [e +var_18]
andal, ds:byte_4A2CBE[edx]
mov[e +var_22], al
moveax, 8
subeax, [e +var_18]
add[e +var_1C], eax
loc_45B1DB: ; CODE XREF: decrypt+EA j
inc[e +var_10]
dec[e +var_28]
jnzloc_45B13B
loc_45B1E7: ; CODE XREF: decrypt+5B j decrypt+91 j ...
moveax, [e +var_8]
movedx, [e +var_20]
movbyte ptr [eax+edx], 0
xoreax, eax
movfs:[eax], edx
jm hort loc_45B205
;------------------------------------
loc_45B1FB: ; DATA XREF: decrypt+2B o
jmp@@HandleAnyException
;------------------------------------
loc_45B205: ; CODE XREF: decrypt+129 j
xor eax, eax
pop edx
pop ecx
pop ecx
mov fs:[eax], edx
push 45B222h
lea eax, [e +var_4]
call@@LStrClr ; __linkproc__ LStrClr
decryptendp ; = -3Ch
由于这个游戏是用Delphi写的,所以用到了一些Object
Pascal库函数和一些VCL的东西,传入数据也是String类
型(把String当作动态数组用),不过这些都没关系,我们只
www.csdn.net/magazine 23投稿信箱:tougao@csdn.net
特别专题
游戏外挂
要当中的解码部分就可以了.现在首先来弄清楚它的入口
参数,用IDA往外跳一层(X键),我们可以看到:
mov ecx, 400h
mov edx, ds:dword_4F7D6C
mov eax, [e +var_4]
call decrypt
lea edx, [e +var_14]
有了上面的调用代码,我们大概就可以知道解密函数
是采用fastcall方式,用寄存器直接传递3个参数,但是
其中两个参数的含义我们无法知道,因为是动态内存地
址,这时候就得请出SoftIce,在mov ecx, 400h处下个
断点,进入游戏,连接服务器,等待数据从服务器返回的
时候,断点中断,观察一番后发现EDX是解密数据存放
地址指针,EAX是待解密数据存放地址指针,ECX固定,
用途我们得在函数内部进行分析才能知道.在decrypt函
数的cmp eax, [e +var_C]这里我们可以知道,400h是
解密后数据最大长度限制.OK,搞清楚了这些参数,现
在就用高级语言把算法部分模拟出来,当然,我们也可以
直接复制上面的汇编代码,修改一下嵌入自己的外挂程
序,而且这样更省事.不过,为了弄清楚整个函数的流程,
就多花点时间,其实也才100多行汇编代码,并不是很麻
烦,除了理清循环和跳转逻辑关系,就是一句一句进行简
单直译.翻译结果如下,一个C++的解密函数:
int TMirProce or::DecryptData(co t String &DataBuf ,
LPBYTE DesBuf,DWORD MaxDesLen)
co t char temp[10] = {0x40,0x0,0xFC,0xF8,0xF0,0xE0,
0xC0,0x8D,0x40,0x0};
DWORD var_28;
BYTE var_23;
BYTE var_22;
BYTE var_21;
DWORD var_20;
DWORD var_1C;
DWORD var_18;
DWORD var_14;
DWORD var_10;
DWORD DataLe DataLen = DataBuf.Length();
var_14 = DataLe var_18 = 2;
var_1C = 0;
var_20 = 0;
var_22 = 0;
var_28 = DataLe for (var_10 =1;var_10=0x3C)
var_21 = DataBuf[var_10-1]-0x3C;
if (var_20=8)
var_23=(var_21 & 0x3F & 0xFF)(6-var_18)| var_22;
DesBuf[var_20] = var_23;
var_20++;
var_1C = 0;
if (var_186)
var_18+=2;
var_22 = var_21 var_18 & temp[var_18];
var_1C += 8-var_18;
var_18=2;
var_22 = var_21 var_18 & temp[var_18];
var_1C += 8-var_18;
DesBuf[0] = 0;
DesBuf[0] = 0;
DesBuf[var_20] = 0;
return var_20;
因为是直译,所以代码有点臃肿累赘,不过经过N
次调试之后,终于能正确进行封包解密了(用前面的知
识,自己写一个封包截取程序吧,不要用什么WPE,那
个太不好用了),算下来从分析解密函数到翻译成高级语
言并调试通过也才花了个把钟头时间.接下来就依样画
葫芦,把加密函数也搞定,就能伪造封包发给服务器,一
个外挂便基本成型,剩下要做的就是玩游戏,倾听玩家
的功能要求,然后去分析封包,编写相应实现了……
尾 声
做外挂,说穿了,苦力活而已,在大部分时间里,你
需要面对的只是枯燥的封包数据和汇编代码,根本无暇
去领略编程所带来的那种快感,中国的程序员日子不好
过呀!最后,如果哪位对本文内容有所异议,或者有什
么新奇的想法和思路要和我共享,讨论,都欢迎来信到
bluely@vip.163.com!(注明,本文有配套工程源码下
24 csdn 开发高手 2003.09
特别专题
游戏外挂
u撰文/冰 蝎
反外挂战略体系 浅析
反外挂是一个很大的话题,涉及的层面也很广,单
从技术细节上很难孤立去讲,由于前面蓝蝎兄已经剖析
了外挂开发技术,在本文里,我就和大家简单谈谈国内
反外挂的一些基本情况,旨在让大家对这个特殊领域有
所了解.这里先要声明,由于阅历所限,我个人对外挂
和反外挂除了技术兴趣外,没有任何倾向,本文也只是
写给大家开开眼界.此外,我要特别感谢沈大哥,玉泉
国际的研发李千照,网星副总林先生以及研发孙先生为
我提供的信息.
好了,回归正题,从策略上讲,反外挂也就三种方
式,一是依靠立法,二是依靠技术,最后是依靠玩家反
馈.(注明:本文所讲的"外挂"不包括游戏机器人技术,
反外挂不会也无法涉及这类情况)
就目前国情来看,立法和普法应该是杜绝外挂的根
本,技术上讲,没有做不出来的外挂,也没有破不了的外
挂,所以,想单从技术