欢迎光临散文网 会员登陆 & 注册

C++程序反编译笔记(18) 拆分函数

2023-01-09 21:08 作者:GC_CH  | 我要投稿

    如果无法找到突破口, 那么就从界面入手.

    程序总是要输入和输出的, 这里说的界面是指显示输出的界面, 可以是控制台, 窗口, 文本文件等.

    一般程序总是调用系统API来制作界面的, 操作系统屏蔽掉了显卡显示器等的操作接口.

    而操作系统的API的参数和返回值都是可以查到的, 这就有利于反编译时分析代码, 从已知的推断未知的.

消息处理

    Windows操作系统的界面是基于消息处理的, 因此, 要了解操作界面后会调用什么代码, 就需要分析窗口的消息处理函数.

    

    从上图中的 lpfnWndProc 字段可以知道扫雷主窗口的消息处理函数.

拆分函数

    为什么要拆分函数? 因为很大的函数看起来十分头疼, 我认为一个漂亮的函数应该在50行左右.

    MainWndProc_1001BC9 就是一个比较大的函数, 我们需要把它按照不同的消息来拆分. 比较好的做法是将它改成一个仅有一个switch语句的函数, 而且每个case分支只是简单的调用具体的消息函数, 这样我们看起来就一目了然了.

    本来它是这样的

        里面有很多if, switch 和 goto, 看起来还行, 不是特别乱. 拆分后是这样的

    一般是On + 消息名来给某个消息命名处理函数, 这样找起来比较方便.

    可以使用 TortoiseGit 将我上传到gitee的项目切换到 21 这个版本来对比拆分前后的区别.

菜单资源

    我并没有从鼠标消息入手, 而是从菜单消息入手. 原因是直接看鼠标消息的处理代码, 肯定会遇到很多不知道具体含义的变量, 从菜单入手有一个好处就是菜单项是有文本的, 我们可以根据文本直接对应的处理代码做了什么.

    菜单也是一种资源, 我们可以从Visual Studio的资源视图看到菜单的消息.

    比如, 点击"开局"菜单, 那么对应的代码肯定是游戏开始要做的事了. 而初级, 中级, 高级, 自定义这四个菜单就更好理解了, 设置游戏级别(难度), 那么我们就可以知道表示游戏级别的变量是哪个了.

    菜单点击对应的消息是WM_COMMAND, 这里我用OnCommand函数来处理该消息.

    再资源视图选中某个菜单项, 在属性窗口就可以看到它的ID了, 我们需要根据ID来找到它的处理代码.

    

    WM_COMMAND消息处理中的WPARAM参数的低2个字节就是菜单项ID. 具体的处理代码就下篇再说了.


C++程序反编译笔记(18) 拆分函数的评论 (共 条)

分享到微博请遵守国家法律