Shell's Home

Jun 4, 2005 - 1 minute read - Comments

病毒编年史-中古

1991年DOS盛行以来被划为中古时代,这个时代的各种病毒主要在dos和win3X上面折腾,win9X和保护模式还是未来的概念。贝壳就经历了这个时代。当时要杀解某种病毒基本是要用户手工去DeBug的。还有专门的小册子指导人怎么做。不过即使现在,能Debug方式杀毒的人又有多少呢?幸好现在有了反毒程序。 贝壳评论: 所谓反毒程序,其实就是感冒药。你吃了感冒药敢去流行性感冒的流行区吗?所以,防毒还是要靠自己小心。 AD 1991,首个多态病毒出现(好快),代表作 Tequila(龙舌兰),作者未知。 贝壳评论: 所谓多态,就是指同个东西的多个表现形式。在C++来讲,就是同个基类的多个行为。在病毒来讲,就是一个动作的多种代码写法。也可以称为变性病毒。基本原理是利用可替代代码,用不同的代码表达一个内容。或者利用变性子,变更病毒的形态,并且执行的时候动态变换回来。其中在DOS时代的皎皎者就是Natas,无穷变形。 插句话,前面所描述的病毒,经历了概念型,游戏型等等非经典形态。在Brain(小球)后才真正是破坏病毒。基本来说分为三个类型,开始的引导型,后来的文件型,和系统型蠕虫。前者出来不久就没了,连作者都没有赶上(赶这个干吗啊?),后者在当代还屡屡出现,生命力超强。最后者直到近年才在windows上广泛出现,由此可见Morris的远见。还有很多是以上的复合型病毒,真正DOS病毒的巅峰之作当数DirII(后文有述)。 AD 199X,Jerusalem病毒出现,又名黑色星期五。在十三号又是星期五的日子,这个病毒就会发作。 AD 1994,恶作剧邮件出现(重复一次,这不是病毒),作者未知。感觉上说,这个很像一个古老的循环。下面的信请在XX天内发给XX人,如果发了你会OOOO,如果没有则会XXXX。其实这个东西(姑且叫东西吧),思想绝对先进。他通过一个信件,发送一个病毒警告给用户,提醒他们小心病毒,并且要求你发送这个信件给所有你认识的人。大家感觉是不是很像邮件蠕虫病毒啊?不过这里并没有真正的病毒,信中提及提及的病毒在其后两年内没有人中过…… AD 199X年,防毒卡终结,DirII横空出世。代表作 DirII,作者未知。 这个病毒贝壳我在DOS病毒中着重描述,为什么呢?因为他有数个特点。首先是他将自身加入了DOS的设备驱动链,合法的修改了系统,导致硬件防毒的一蹶不振。详细请看《信息安全半世纪—一个程序员的简单回顾》江海客(http://netsafe.ayinfo.ha.cn/software/virus/article/teach/teach_25.htm) 贝壳曾经在防毒技术资料上看过病毒分析,非常佩服。同时这个病毒客观上也造成了文件系统格式的变化。当今这种变化可以被用来防御各种本地进攻。 DirII的出世也标志着中古时代的结束,此后的病毒就向win9X平台上迈进了。

Jun 3, 2005 - 1 minute read - Comments

病毒编年史-上古

所谓病毒编年史-上古,指的是自AT&T的Unix出现后到BG的DOS刚刚冒出来的这段时间。这个时间里面我都没有出生,所以所有资料均举自网络。如果有抄袭重复还请见谅……毕竟要我说自己出生前的历史想不背书都不行…… AD1949 ,病毒概念诞生,代表作无,作者John Von Neumann。大家表和我说不知道这个人。冯。诺伊曼结构知道吧,近代计算机理论奠基人。 贝壳评论: 话说具体时间嘛,也不确定是1949年,这年恰也是计算机元年。据说同年John Von Neumann提出一篇论文,描述了病毒的机理和存在,不过没有实际代码,也没人信。但是鉴于病毒的基础理论已经出来了,我们同样定这年为“病毒元年”。而后大约十年的时间内在美国电脑电话电报公司(AT&T)的贝尔(Bell)实验室中,出现了磁芯大战。磁芯大战这个游戏现在还有模拟器可以跑,具体情况可以下载来看看,模拟器访问 http://www.xfocus.net 。里面有中文教程和下载,在此不再赘言。 AD 1959(大约) ,远古病毒诞生,代表作 磁芯大战(Core War) ,作者AT&T Bell 的Douglas Mcllroy、Victor Vysottsky以及Robert T.Morris 。最后一个人大家记住了,这个人是后来非常出名的Morris蠕虫的作者的老爸,当时正好掌管整个ARPANET网络,给儿子闹了个灰头土脸。 同时我要特别提到他的公开者。磁芯大战本来是在程序员间秘密流传的,不过1983年(嘿嘿,我诞生的年头) Ken Thompson在一项杰出电脑奖的颁奖典礼上,他作了一个演讲,不但公开地证实了电脑病毒的存在,而且还告诉所有听众怎样去写自己的病毒程序。这个Ken Thompson,如果我没有记忆错误的话,系Unix的缔造者之一。(致以无上敬意……)另外,Ken Thompson与Dennis Ritchie是唯一两位获得Turing Award(图灵奖,电脑界的诺贝尔)的工程师(其他都是学者),后者是C的缔造者。 AD 1981,苹果病毒1 2 3诞生,近代公开病毒首例,作者未知,传播是通过一个得克萨斯州的盗版游戏传播的…… AD 1983,概念型病毒(不是病毒概念哦),首例病毒研究论文发表,病毒正式定名,作者Fred Cohen。 贝壳评论: 话说此君在南加州大学念书的时候,着重研究了一种导致系统死机的程序。(windows?)结果得不到某些教授的认同。于是此君愤怒之下,直接公开了论文和示例代码。其指导教授Len Adleman将其定名为病毒(virus),Cohen的程序,让电脑病毒具备破坏性的概念具体成形。 BTW,喜欢看近代密码学的人是否觉得哪里很眼熟啊?嘿嘿,Len Adleman的A和RSA加密算法的A是一个A哦…… AD 1986,引导型病毒出现,代表作 小球(巴基斯坦),作者 Basit Amjad兄弟。这个病毒的目的是为了防止盗版游戏。 贝壳评论: 某种意义上说,这个才是近代病毒第一人。笔者曾经研究过这个病毒,感觉非常远古。头部居然还有病毒作者的声明和地址(CIH的前辈啊……)。通过更改系统的BOOT区(0面0道1扇区)来获得系统权限,减小内存总量并且驻留,而后再次载入原始BOOT。目前此种病毒已经失传,原因是因为linux和windows抢MBR区抢的太凶,导致所有BOOT型病毒殃及池鱼……(玩笑……) 为了防止盗版而植入恶意代码的事情后来反复出现,现在形成了一个专门的问题。能否以暴易暴? AD 1987 文件型病毒出现,代表作 Lehigh(这个是Pennsylvania宾夕法尼亚州东部的一个小镇),作者未知,感染对象是command.com。 AD 1988.11.2 ,蠕虫传播,病毒首次发威,代表作 Morris蠕虫,作者是 在康乃尔 (Cornell) 大学攻读学位的研究生,Robert T.Morris Jr,当年23岁(厉害哦,比我大一点而已……)。 1988年11月2日,Morris 蠕虫[8~12]发作,几天之内6000台以上的Internet服务器被感染,损失超过一千万美元。它造成的影响是如此之大,使它在后来的10几年里,被反病毒厂商作为经典病毒案例,虽然它是蠕虫而非病毒;1990年,Morris蠕虫的编写者Robert T. Morris被判有罪并处以3年缓刑、1万美元罚金和400小时的社区义务劳动。Morris蠕虫通过fingerd、sendmail、 rexec/rsh三种系统服务中存在漏洞进行传播。他的主要思路是通过构造缓冲区溢出获得远程管理员权限,并且载入一段引导代码(boot),下载远程的病毒主体并且编译连接,重复感染系统。 AD 1990,出现了首个大型公司的反毒程序,代表作 Norton AntiVirus,作者 Symantec。这个标志着病毒和反毒已经成为商业化的斗争。 远古时代大致到这里就结束了,其中涵盖了多个系统上的各种病毒。提供了最初的各种病毒理念。

Jun 3, 2005 - 1 minute read - Comments

病毒编年史-前言

最近和人聊天,讲到病毒和系统,人家问我要资料了解下历史。我说貌似以前有个大牛人写过一个OS演义,详举了种种系统的历史。病毒就貌似没有了。想想有趣,决定跑回来写个病毒编年史,举各种史上出名的病毒,并且加以评论。不过史上出名四字极难担当。就病毒数目而言,尚远在系统数目之上。其中精品之作汗牛充栋,在此仅仅能分析一二。而且资料不全,有遗漏处还请告知。至于评论更是一家之言,姑且听之,莫笑莫笑……

Jun 2, 2005 - 1 minute read - Comments

利用API插接替换破解软件

刚刚在看软件破解教程,看到一个人说怎么怎么破解软件。然后突然想到,许多软件破解其实不用修改出flag或者找注册算法。只要对话框不出来,软件照常好用就可以了。OK,基于这个原理,试试用DLL注入插接API的方法RIP破解软件。 首先是对话框弹出机理。先写了个MFC程序,然后跑一跑,在运行中按着DoModel()一路F11下去,跟进了CWnd::CreateDialogIndirectPreamA云云的一个函数里面(名字忘记了)。然后就是一个API调用了。(__IMP__Creat…肯定是调用别的DLL的函数了)API内容看不到……我晕。编译一个Release版的出来,然后上Ollydbg。经过跟踪,确定了窗体句柄是在USER32.CreateDialogIndirectPreamAorW里面生成的。如果没有窗体句柄呢? 貌似有两种可能,一种是没事,对话框没了。一种是报错。按照试验,Readbook至少是没事情的。哈哈,这样简单多了。整理下顺序,基本就可以做RIP破解了。 首先是用OllyDbg等等软件定位USER32.CreateDialogIndirectPreamAorW(其实USER32.CreateDialogIndirectPreamA更好,如果只用这个的话比较好确定参数类型)。然后下断点,跑到软件里面触发窗口广告……然后记录对话框的模板位置,调试的任务就结束了。因为没有啥要判断的东西,这个应该说简单到顶点了。 然后写一个DLL注入程序,运行目标程序并且Suspend。然后注入DLL,挂接API。详细参看windows核心编程,现在我们假定挂接了USER32.CreateDialogIndirectPreamA。现在有了一个自主的处理函数,只要在里面判断模板是否为特定模板就好……这个是module的一个res,理论上不是动态生成的,所以位置不变。而且一个对话框一个模板,很好认不会出错。如果是特定模板就返回NULL,否则正常调用。这样程序的提示框就永远弹不出来了。 这个其实是将软件的对话框禁止技术搬到了API层去实现,由于API层代码相对稳定,通用性强,所以破解相对简单。不过也是有代价的。如果软件无法生成对话框会导致出错……这个就没戏了。而且要写注入程序(可以写个注入的模板,或者一次写好可以多次用……),毕竟不是直接运行程序,使用不大方便。而且速度会受影响,如果程序里面对话框满天飞的话……

Jun 2, 2005 - 1 minute read - Comments

首次面试

首次面试,感觉非常怪异。先是过去玩,结果找不到地方。然后就在咖吧里面消磨时间,花了15块……我的钱啊……不过还好,有冷气,有美女(如果那个算的话),还有电插头。拿PDA看看书正好。旁边有音乐,外面看人来人往,风吹树动。真的有点偷得浮生半日闲的感觉。然后跑去吃麦当劳……那个叫出血啊,不过也没有办法,咖吧里面的快餐上手就要挨一刀,还是能省则省吧(虽然麦当劳也省不到哪里去)。 然后吃完,终于进去了。才发现刚刚我就站在门口没有敲门而已……我Ft。老板人还不错,工作有点无聊。后来来了个.net的程序员,号称在微软做的……那个.net的程序员让我感觉非常奇怪。当时问问题的时候感觉总答不上来,可是回来细想发现里面很多都有透换概念的迹象,而且还有错误。 例如问我ASM调用C的时候,压栈顺序问题,我想了半天,结果他没有没说对还是错。这个就算了。这个问题引申出来了一个栈堆增长问题,他居然告诉我栈堆是正增长的。如果栈堆真的正增长,那溢出问题怎么可能出的来? 就是CLR和.net支持多门语言的问题,的却,CLR的优点非常多。不过事实上,VS.NET支持的所有语言的却使用了.net framework,这个导致了语言传承的断链。C类语言不兼容ANSI C,VB类语言库都变了。所有使用过原始语言的人变成了新人重新训练……而且说的明白点,高级程序员学门语言的语法根本不用几分钟。如果用VB掌握了framework,那么换成C#又有多困难呢?这和完全的使用一门语言有区别吗?.net号称支持多门语言,虽然是事实,不过有意思吗? 还有那个winsock的问题就不说了,MSDN上能查到还问我。当我白痴还是背书机器啊?accpet在异步无连接的返回值可能有三种,INVAILD_HANDLE一种,特定错误一种,SEH一种。除此外还有可能(虽然不大可能)当场阻塞。此外还有啥可能?不过现在三选一,运气不大好……选择错误。应该是特定错误标志的选择成INVAILD_HANDLE用GetLastError()察看了。 那个按钮的问题到的却是我看的不够仔细,如果知道BM系列message的话应该答的上来的。不过关于SendMessage返回的问题,这么理所当然的事情还郑重其事的去问。我真是无语了。PostMessage当然没有返回值,因为是异步,对方甚至还可能处于阻塞状态,怎么返回值啊?至于使用Callback,可能不大。PostMessage本身逻辑同步问题不大的,要是Callback就要自行头痛同步问题,相信没啥人这么笨的……SendMessage的流程大约是(貌似有人和我说过,或者windows核心编程里面写过),首先如果是同进程接收的话直接调用接收函数,如果异线程先置标志,然后发出一个消息(和Post的不大一样),然后对方接收结束后返回一个消息,再开启运行。回头翻翻核心编程好了,貌似在那里的…… 郁闷啊郁闷啊……

May 31, 2005 - 1 minute read - Comments

Bittorrent

关于纯粹的BT技术,并没有啥好说的。BT的迅猛发展表明了这个技术的生命力。不过BT还要面对几个问题。首先,也是最大的一个,就是Copyright的问题。 嗯,先回顾下网络文件发布的方式和版权追究的历史。最开始的互联网是bbs形式的,而且比firebird一类的telnet形式还要落后。这种情况下要么是通过bbs交换文件,要么就是ftp。多数是大学在用,很少有追究版权的,而且多数东西用于研究时可以藐视版权法。所以这个时期根本没有所谓版权的问题。 然后就是欧洲某个研究所(似乎是欧洲核物理研究所)搞出的html协议,到今天成为了xml协议的基础。这个协议可以在客户端灵活的使用各种媒体对象表示,而不用管对方是啥系统。今天的xml可以保存和创建各种内存对象也不用管是啥系统,从某个意义上说,这是一脉相承的重大进步……呃,好像扯远了。这个时候出现的各种文档基本都是本人发布或者转载,多数也是大学使用,没有版权问题。 后来我们的网络渐渐转向民用,这个时候微软也搅合了进来,发布了IE。然后很多网站就搞了个人主页服务。还有部分小型网站根本就是大流量的个人主页。为了吸引访问量,经常东抄抄西搬搬。这个时候就有了盗版的概念,不过盗版的多数是文字,也经过修改。这个时期的后期渐渐演变成了盗版歌曲,Mp3格式之争由此而来,相信大家非常熟悉了。 网页毕竟比较好处理,盗版的人虽然多,不过稍成气候就可以一个警告让ISP关闭服务。唱片公司们虽然头痛还比较好处理。(当然,他们可能认为这已经是比较严重的问题了。但是和后来的境况相比,他们的却还没有见到啥大场面。)而后出现了分布式的歌曲共享系统和搜索引擎,这让各个公司大大的头痛了。两者的结合使得免费的歌曲在网络上满天飞,整个唱片行业据说损失惨重。唱片公司们为此甚至将歌曲共享先锋的Netisper(貌似这个名字,偶忘记了)告倒了。不过倒了一个人,起来千万个。反正目前来说,唱片公司已经放弃封杀所有免费歌曲流行的可能。改成授权下载了。用非常低廉的价格销售所谓“授权正版Copy”。老实说对于这个我非常的佩服,不但宣传了自己,减少了盗版损失。对于我们来说,合理合法,支持了自己喜欢的歌手,而且还方便查找。这手算是诸公司们非常成功的举措。 然后就是近代,Edonkey和Bittorrent为代表的两种DFS横空出世(其实ED是个老家伙了)。满世界乱飞的盗版根本没法解决,而且盗版的范畴从主要是音乐和文字扩展到了各个领域。从游戏到电影,啥都有。甚至严重的打击了盗版商,将中国多年未竟的反盗版销售的事业推向了顶点。一个卖盗版的朋友是这么评价的:“以后我们只卖三种软件光盘,系统,office,大众软件”。我今年的所有电视和电影都是从网络上下载的。由此可见我们的盗版正式进入了战国时代。 为盗版而生想必不是P2P软件的本意,不过去除盗版后P2P恐怕没啥明天可言。不信你可以上bt.btchina.net数数到底多少共享是有授权的,包括shareware,XXX授课录像Live这种就算授权过好了。照样是盗版比非盗版多。但是P2P极大的刺激了网络的发展,并且可能成为将来的一个核心技术。 当然我相信,立个法禁止P2P软件简单。但是,这是倒退,而不是进步。P2P软件现在逐渐分布化,BT可以自我组件平台,并且透网络运行,凡可上网处皆可BT。如此优良的技术弃而不用,岂非倒行逆施?但是相对,BT也无法参照歌曲运营的模式来个网络授权正版。如此一来,BT被告上法庭的机会就非常高。要是真的禁止了BT,相信会有新的共享软件应需求而生,状况非但没有好转,反而恶化。绝对不是立法禁了就解决的了的。 目前来说,寻求一种共享中盈利的模式是当务之急。不但是各个损失惨重的公司,而且是众多的BTFans。如果公司倒了,我们还能BT啥呢? 另外一个就是BT的共享方式。BT的算法仅仅可以用于静态文件,这点另我非常不齿。目前最需要分布运行的多数都是动态数据,例如电视广播,股票数据等等。BT不可以用于动态数据的原因我比较清楚,因为我曾经就算法设计问过运筹的老师。不过有分流比没有分流好,仔细看看当今诸多股票提供上捉襟见肘的状况就可以知道了。如果BT2.0协议提供包括动态数据流和认证下载,网络穿越在内的一系列能力,相信会非常具备竞争力的。这个我早在一年前就考虑过,不过奇怪的是,我预计一年可以实现,现在都快一年半了……根本没有声音。

May 31, 2005 - 1 minute read - Comments

debain

根据babylon的结果,没有debian这个词。根据我的拼音加加的结果,debian打出来是“得便”的意思。而事实上……debian是一个linux的版本。 不过我很奇怪了,why所有的linux发行版本都这么大呢?windows2000的发行版本是4in1,四个版本合一张光盘。而RedHat9的发行版本是1in3,一个版本放了三张光盘……这个居然还好意思号称内核精简。windows的内核严格说起来也只有2M而已,smss大约100K,Csrss不知道多大,加上NTDLL.user32.Kernel32.win32k.gdi32也没有多大。不过windows组件模型比较大,搞得整个windows貌似比较庞大而已。一般来说,优化过后服务器上大约需要2-3G的分区空间。而一个正常可以跑的linux桌面大致也需要这么多的空间……界面和通用性上还不及。这厢真是郁闷大了。 不过仔细想想,linux和windows的传奇都貌似到了顶点。windows自从2003后就基本没有了声音,就算现在他出什么新版本我会不会买账还是回事情。(2003现在都没有试过呢……)linux出新版本总比windows落后一步,usb如此,摄像头亦如此。加上PDA或者智能手机一类的嵌入设备中越来越多的使用WinCE(就是PPC啦),ActiveSync和windows捆绑的迹象越发严重。linux的路不好走啊。 下面恐怕就是分布式系统了吧,如同我前面所讲。分布式系统相对正常系统具备极大的优势。例如硬盘空间共享,这样利用效率就会上升。软件的安装和维护集成,节约成本。CPU资源共用,有利于承担突发事件,并且方便利用用户使用不了的CPU时间。(例如一个在看网页的人的空闲CPU可以分配给运行大型程序的)不过最大的问题就是保密性、可维护性和网络速度问题。一般来说只有当网络速度和硬盘读写速度量级相当的时候才可以考虑分布系统。目前的接入普遍都不快,只有内部网络貌似可以达到这个级别。100Mbps=12.8MB/s,硬盘大约是30MB/s-60MB/s。尚可以考虑考虑。 分布系统的话首先应当选择微内核,否则不同的机器跑不同的内核岂不乱套。网络部分可能会编译到内核里面来加速。不过最大的问题就是,进程如何跨越机器?如果进程无法跨越机器,那么分布系统啥意思都没有了,干脆上一个DFS算了。如果进程要跨越机器,那么操作台占有,信号,等待,互斥等等就都成了问题。以前可能不明显的互斥问题在网络上就会产生明显效应,不同的互斥算法造成的效率差异会非常显著。 我设想分布系统可能如此实现。网络和文件系统编译入内核来加速。程序的运行都要在中央服务器上启动才行。每个进程会派生出控制端的概念,控制端对应不同的权限。严格来说,控制端是一个亚进程的概念。因为同样一个程序可能又多个机器要运行,例如IE一类的浏览器。如果放出多个进程恐怕太过浪费,但是如果放出一个进程,那么这个进程的权限又不好控制。考虑中是否可以将界面控制部分和程序分立开,成为控制端。控制端具备独立的变量空间和权限环境,对应不同终端上的用户窗口,可以容纳多个线程。或者进一步说,同样代码在不同机器上运行时候,环境理论上应当相同,除了控制端部分的数据应当不同(替换成本地的数据)。这样输出窗口的时候可以输出到不同的窗口上。 理论上说,每个程序应当只允许运行一个Instance。如果有人运行某个程序,则应当建立程序的私有空间,并且初始化程序,察看是否已经在运行中。如果在运行中则自网络上虚拟映射入整个程序。而后初始化控制端,并且派生出本地线程。由本地线程来运作整个程序。程序对非控制端部分的操作都要进行互斥访问……真麻烦。 如果某个机器具备空CPU,而另外一个机器CPU运行满,则将整个进程映射入空闲机器中,包括控制端部分。这样可以用空闲的CPU,当然前提必须是支持多线程,这样才可以移动一个线程过去。不过问题是保密性,还有如果空闲的机器也要运行这个程序了怎么办?这样恐怕就要将线程移动回去,然后清空控制端重新初始化。但是空闲的CPU就无法利用了。 呃……貌似扯的蛮远了,从linux安装失败一直扯到了分布系统……今天就这样吧,郁闷……

May 31, 2005 - 1 minute read - Comments

la paloma

原本以为la paloma是法文的鸽子,前几天和Gigi谈起。她说……法文的鸽子,和英文有差别吗?我当时一愣,难倒是意大利文或者拉丁文?回来抄起工具,下了一个babylon pro5.05 tiral。然后找个破解补丁上去,再下载我看的到的本地词典,连接所有可行的网络词典。总共花费400M的磁盘空间,查了下,终于出来了。 la paloma是西班牙文,意思是……鸽子……

May 31, 2005 - 1 minute read - Comments

郁闷

今天没事,看看大家的blog去。结果发现基本都没有更新。然后看到Gigi的上面写的郁闷宣言。然后万分悲惨的……我也郁闷了…… 算算已经快六一了,当然我已经不是儿童,儿童节没啥好企盼的。不过答辩在6.13,目前核心算法还只写了一半,优化和美化完全没有做,文档动笔才3000字。最郁闷的就是,找不到老师,也找不到研究生。毕设还打不打算让我准时过去啊? 当然,要仅仅如此还不至于郁闷到死。那个做的太快导致老师来不及布置任务也就算了,反正我不着急毕业,也不准备拿啥奖。(不给我个最差劲学生奖就不错了)就算准时答辩照样还有30号的运筹学考试拦着,左右无法正常毕业,拖也无妨。问题是现在很无聊,所以家里就开始催我找工作。我说,这人是不是没有被某些人雇佣就不是人啦?那雇人的人呢? 我又不是很差(呃……不说我的成绩……),找个一千二千的工作肯定找的到。问题是好的工作不好找啊。一个个不知道啥理由的催催催,仿佛多催催就可以找到好工作似的。没有找到工作我也暴郁闷啊(在此再次BS中国的就业率)。 更郁闷的就是程序的问题了,呃,不是编程上的问题。最近看看行情,悲哀的发现,中国计算机还过的去的MM就如同秃子的头发,没几个。而且还要排除如花……干吗,BS我?BS我也要排除,我又不是周星星。剩下的人再排排队。然后,意料之中的发现……轮不到我。我周围计算机最顶尖的MM就算Gigi和zoomy了。不过按照程序员的角度来看问题的话,那个也没啥东西……其他的就更别提了,最基础的系统优化都做不好,写个程序头痛的要死。发嗲和骗GG代劳的本事比计算机水平要高,对于电脑的感觉就和对于体重计的感觉差不多。 虽然说我已经做好了没有人分享心理的准备,也决定了今后不相信任何一只动物,尤其是人。不过对于生命繁衍的需要和某些乐趣(呃,请诸MM不要扁我,扁我也不要拿东西,拿东西也别拿硬的,拿硬的也别扁我脸)的需要,一个共享空间和环境的对象是必须的。(写完才发现,上帝啊,系统引论真的看多了。越看越像不同程序共享同一进程空间……)目前状况来看,恐怕不是运气级好的撞上一个秃子的头发(去去,如花退散……),就是必须忍受一个讲话如同对XX谈琴的对象。 不过总总来说,这还不是郁闷之最。郁闷之最的是……我该干什么?迷茫啊…… 呃……我没醉……我没醉,妈的,谁把啤酒换成香槟的……

May 28, 2005 - 4 minute read - Comments

从游戏修改到程序优化

前几天在家没事情干,就写了一个通用游戏修改器。代码很简单,利用argv参数获取传入文件位置,然后反复调用EditFile。重复映射文件,并且定位目标位置,修改指定数量的数据,然后保存。然后,我为了某些特殊目的,决定赋予程序动态运行和可扩展的功能。并且加入搜索支持。其实后者并不困难,我们只要反复调用函数对比和赋值,并且逐步推进指针就好。但是前者的实现具有一定困难,为此我不得不增加了部分程序开销,来保存一个函数指针,并且可以动态的调用。这样我们就可以实现诸如轩辕剑中的物品修改。其过程大致如下所述。 轩辕剑中的物品是一个数组,但是数组头的RVA是不固定的,仅仅知道大致位置。我们必须先定位某个物品的代码(特征代码),然后修改后面紧跟的一个WORD,实现修改物品数量。程序会自动的建立一个指针,并且逐步推进。我们的实现函数仅仅需要判断当前指针指向的WORD对象是否等于一个特定值,等于的时候进行修改就好。主体框架如下: #define NOSEARCH 0x00000000 #define SEARCHALL 0xFFFFFFFF #define RADDR(x) (LPVOID)((DWORD)RVABase+(x)) typedef DWORD (*tpEditData)(LPVOID Data); struct _RVATable{ DWORD RVA; DWORD SearchEnd; int size; tpEditData pfnEditData; LPVOID OldData; LPVOID DataBuff; }; _RVATable RvaTab[]={ {0xBA4C, NOSEARCH, 01, NULL, NULL, “x09”}, {0xBA4E, NOSEARCH, 01, NULL, NULL, “x5B”}, {0x76AB, NOSEARCH, 01, NULL, NULL, “x09”}, {0x0000, NOSEARCH, 0, NULL, NULL, NULL} }; void EditFile(LPTSTR lpPath); int CompareMemory(LPVOID mem1, LPVOID mem2, int size); void main(int argc, TCHAR* argv[]){ for(int i=1;i<argc;i++) EditFile(argv[i]); return ; } void EditFile(LPTSTR lpPath){ int i; HANDLE hMap, hFile; LPVOID RVABase=NULL, DataByRva, DataEndRva, DataNow; DWORD FileSize; __try{ hFile=CreateFile(lpPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if( hFile==INVALID_HANDLE_VALUE ) return ; FileSize=GetFileSize(hFile, NULL); hMap=CreateFileMapping(hFile, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL); if( !