WPE|52wpe|我爱WPE

 找回密码
 注册会员
搜索
  • 2279查看
  • 0回复

主题

好友

1700

积分

禁止访问

发表于 2010-2-3 11:40:08 |显示全部楼层
提起“变速齿轮”(以下简称“齿轮”)这个软件,大家应该都知道吧,该软件号称
是全球第一款能改变游戏速度的程序。我起初用时觉得很神奇,久而久之就不禁思考其实现原理了,但苦于个人水平有限,始终不得其解,成了长驻于脑中挥散不去的大问号。

  偶然一天在BBS上看到了一篇名为《“变速齿轮”研究手记》(以下简称《手记》)的文章,我如获至宝,耐着性子把文章看完了,但之后还是有很多地方不解,不过还是有了比较模糊的认识:原来齿轮是通过截获游戏程序对时间相关函数的调用并修改返回结果实现的呀。

  为了彻彻底底地弄清齿轮的原理,我这次打算豁出去了。考虑到《手记》的作者从是研究的“齿轮”的反汇编代码的,那我也照样从反汇编代码开始。不过自认为汇编功底不够,又从图书馆借了几本关于Windows底层机制和386汇编的书,在经过差不多两周的“修行”之后,自我感觉有点好啦,哈哈,我也有点要迫不及待地把“齿轮”大卸八块了!

  在动手之前,我又把《手记》看了一遍,这次可就清楚多了:通过调用门跳到Ring0级代码段,修改各系统时间相关函数的前8个字节为jmp指令,转跳到“齿轮”映射到2G之上的代码,达到截获对各系统时间相关函数的调用的目的。但同时我的疑惑也更明确了:
    1.“齿轮”怎样建立指向自己映射到2G以上内存的代码的调用门描述符的;
    2.“齿轮”怎样将自己的代码映射到2G以上线性地址的;
    3.映射到2G之上的代码是怎样做到在代码基址更改的情况仍能正确运行的

  带着这样的疑问,我正式开始了对“齿轮”反汇编代码的分析。工具嘛,不用说当
然是Softice for Windows98、W32Dasm,OK,出发啦!

  我的“齿轮”版本是0.221 for win98和winme的,内含有两个文件(变速齿轮.exe
和Hook.dll)。先看看Hook.dll里面有些什么,用W32Dasm将Hook.dll反汇编,看看它的输出函数:

     ?ghWnd@@3PAUHWND__@@A
     ?gnHotKey1@@3KA
     ?gnHotKey2@@3KA
     ?gnHotKey3@@3KA
     ?gnHotKey4@@3KA
     ?nHook@@3HA
     ?SetHook@@YAHPAUHWND__@@@Z
     ?UnHook@@YAHXZ

  看函数名好象该dll只是安装钩子捕获变速热键的,与我的研究目的没太大的关系, 跳过去!
  再看看变速齿轮.exe的导入函数,timeGetTim、GetTickCount等时间相关的函数都
在里面。嘿,还有CreateFileMappingA和MapViewOfFileEx,看来“齿轮”是用这两个函
数创建映射文件的。以下列出几个关键的导入函数:

     Hook.?gnHotKey1@@3KA
     Hook.?gnHotKey2@@3KA
     Hook.?gnHotKey3@@3KA
     Hook.?gnHotKey4@@3KA
     Hook.?SetHook@@YAHPAUHWND__@@@Z
     KERNEL32.CreateFileMappingA
     KERNEL32.GetModuleFileNameA
     KERNEL32.GetModuleHandleA
     KERNEL32.GetTickCount
     KERNEL32.MapViewOfFileEx
     KERNEL32.QueryPerformanceCounte
     USER32.KillTimer
     USER32.SendMessageA
     USER32.SetTimer
     WINMM.timeGetTime
     WINMM.timeSetEvent

  既然“齿轮”截获了timeGetTime,那我就跟踪timeGetTime函数的执行情况。

  我先写了个Win32 APP (以下简称APP),当左击客户区时会调用timeGetTime并将返回的结果输出至客户区。运行这个程序,打开“齿轮”,改变当前速度。

  Ctrl + D 呼出Softice,bpx timeGetTime ,退出,再左击APP客户区,Softice跳出。哈,果然timeGetTime函数的首指令成了jmp 8xxx 002A ,好F8继续执行,进入了“ 齿轮”映射到2G线性地址之上的代码。一路F8下去,发现接着“齿轮”把timeGetTime 首指令恢复,并再次调用timeGetTime,这样就得到了timeGetTime的正确结果,保存结果。“齿轮”再把timeGetTime首指令又改为jmp 8xxx 002A 。接下来都猜得到“齿轮”要干什么了!没错,将得到的返回值修改后返回至调用timeGetTime的程序APP。

快速发帖

您需要登录后才可以回帖 登录 | 注册会员

手机版|Archiver|WPE|52wpe|我爱WPE ( 闽ICP备15009081号 )

GMT+8, 2024-5-2 22:19 , Processed in 0.065639 second(s), 16 queries .

返回顶部