Heath's Blog

There is no end, it is just the beginning! - A Game Developer's Notes

HOW TO PerfHUD

    PerfHUD是NVidia提高的免费DX图形程序性能分析工具,目前最新版本为6.1。PerfHUD使用起来也很方便,只需在CreateDevice时将设备ID设置为PerfHUD虚拟设备的ID(如果只有一个显卡,该ID通常为1),类型设置为D3DDEVTYPE_REF,然后将编译好的可执行文件通过右键菜单的“Send to”或者直接拖到PerfHUD图标上的方式就可以运行该分析工具。

    然而对于手上没有源码的图形程序,如发行的游戏,我们就无法直接使用PerfHUD了。当遇到这个问题时,我想了两种办法:1)使用D3D Hook;2)逆向分析直接修改调用CreateDevice传入的前两个参数。
    对于第一种方案,我使用了DLL function forwarders的方式只hook了Direct3DCreate9,然后将d3d9.Direct3DCreate9的返回值保存后替换成自己的实现的IDirect3D9接口指针,这样我几乎可以监视所有d3d9提供的接口方法。理论上,采用第一种方案,只需在CreateDevice方法中将传入的前两个参数修改让后调用d3d9.CreateDevice即可。然而,事实却往往不如人意,后来仔细分析了一下PerfHUD的实现原理:实际上PerfHUD也是一个D3D Hook,当程序作为PerfHUD参数启动时,PerfHUD判断前两个参数,然后如果允许分析,就载入几个包含分析功能的DLL,最终PerfHUD还是会将真正创建D3D设备的前两个参数恢复成应用程序使用的参数,因为PerfHUD仅仅是虚拟了一个设备和Hook了一下D3D。然而,使用第一种方案你自己就可以写出另外一个PerfHUD来了(不过就得花些功夫了),而且普适性很强。
    对于第二种方案,可使用动态分析软件,先定位d3d39.Direct3DCreate9,然后根据其返回值定位CreateDevice入口,最后找到调用CreateDevice的地方,修改前两个参数就OK了。笔者用此方法,测试了Wow和Call of Duty-World at War,其中Wow由于直接使用立即数作为CreateDevice前两个参数,所以不需要调整代码,而Call of Duty-World at War采用了直接寻址来得到第1个参数,修改起来就有点麻烦了。 此方案不具有普适性,针对每个图形程序,需要去修改其二进制代码。

 
 

posted on 2008-11-22 17:29 Heath 阅读(3046) 评论(3)  编辑 收藏 引用 所属分类: Studying

Feedback

# re: HOW TO PerfHUD 2008-12-08 19:35 TC

你的WOW 是私服的吧,你用的两个方法没一个可行的,在公服上一个都行不过(我的意思是仅靠你上述的方法,如果还有隐藏的技巧那是我错了)
  回复  更多评论   

# re: HOW TO PerfHUD[未登录] 2008-12-10 14:48 Heath

@TC
我这里只说方法,如果你在登陆界面可以用PerfHUD,证明我的方法没问题。  回复  更多评论   

# re: HOW TO PerfHUD 2008-12-22 18:05 TC

哇哦,搜其它东西的时候还回到这个内容来
呵呵,登陆界面没问题的,提两个问题:
1) 如果加入文件合法性验证怎么办?
2) 如果没有固定的IAT怎么办?  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理