杉宫竹苑工作室

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 4078|回复: 0

【转】用OllyDbg静态分析修改字体

[复制链接]
发表于 2015-1-23 15:10:49 | 显示全部楼层 |阅读模式

正式会员享受无限制浏览网站功能和高速网盘下载,赶快加入本站吧!

您需要 登录 才可以下载或查看,没有账号?立即注册

x

作者: 雅枫

源地址:http://teach.hanzify.org/article/233-1110556800.html


Ollydbg是一个动静结合的工具,能非常快捷的分析程序,并且其内建汇编器与编辑器,能在不用十六进制编辑器的情况下修改文件,并且反汇编代码也比W32dasm清晰的多,所以我们有足够的理由抛弃W32dasm而用Ollydbg来做静态分析,有人要说了,既然Ollydbg支持动态分析,为什么还要讲静态分析呢?因为静态是动态的基础,动态可以说是进行更好的静态分析的辅助手段(我一般不会纯静态分析,不到迫不得已,我一般是一边调试一边分析的)。所以只有在掌握静态分析技术的基础上,才有可能使用动态辅助理解。好了,不说废话了。让我们试着用ollydbg分析一个程序先。

这是我用汇编写的一个程序,其中与字体有关的有两处CreateFontA(菜菜:这是什么?)的调用,一处CreateFontIndirectA(菜菜:这个更长了!俺不懂英文撒)的调用,两处GetStockObject(菜菜:又来了!不懂啊,放弃吧……)的调用。可能你还不知道这三个东东是什么,不要急嘛!我这不正想解释嘛……,上边是三个API,也就是三个字体函数,也就是三个能生成字体的功能块,你可以把它们想象成三个黑匣子,你给它不同的条件(传入一些描述字体的参数),他们就会生成不同的字体(返回想要的字体句柄)。句柄又是什么?术语是一个32位的指针或者id,如果不懂你就可以认为他就代表了这个字体。也可以在大脑中把它们等同起来,认为字体跟字体句柄就是一个东东(实际上当然不是,假设一个字体函数返回了12340000,在刚运行函数后你用这个值可以代表一种字体,时间长了可能这串数字就没啥意义了)。那一个函数是怎么调用的呢?当然是用Call指令来调用,这个没啥好说的,call这个指令就是调用函数,比如我们调用CreateFontA这个函数,我们可以写上Call CreateFontA。刚才我说了,我们用函数生成字体,要有一些参数啊,要不CreateFontA怎么知道我们要什么样的字体呢?这些参数怎么传入呢?利用堆栈!我们把函数的参数先用入栈的指令push一个一个的写入堆栈就可以传入函数了,如果我们不传入参数可不可以呢?答案是不可以,因为这些API函数默认是从堆栈取出参数来用的,假如一个函数需要4个参数,在函数内部就会取出4个参数并且在函数内部会清除这4个参数(堆栈最顶部的四个数据(标准调用约定)),如果你在调用前不幸没有把参数压入堆栈,或者少压或多压几个参数,那么堆栈就完全乱套了,运行后就是一个非法操作……。值得说一下,API调用是从右往左入栈的,即如果一个函数有3个参数,分别是P1,P2,P3,则你就需要在调用改函数前:

PUSH P3

PUSH P2

PUSH P1

CALL 函数

在WIN32ASM中,每个参数都是固定的4个字节(32位嘛)那么长,那如果我想输入一个大于4个字节的参数(如一个字串)怎么办呢?传入指针!也就是地址,在32位的WINDOWS下,一个地址也是4个字节的。我们先看看CreateFontA函数的原型:

HFONT CreateFontA(

    int nHeight,   //字体高度

    int nWidth,    // 字体宽度(一般设置为0)

    int nEscapement,  // 这个一下边一个是设置斜度

    int nOrientation,   //

    int fnWeight, //字体的粗细400是正常600是粗体,输入0则与400效果相同

    DWORD fdwItalic,     //这个以及下边两个都是是否有下画线之类的属性一般为0

    DWORD fdwUnderline,      //

    DWORD fdwStrikeOut,      //

    DWORD fdwCharSet, //语系,这是造成乱码的罪魁,中文要设成1或者86

    DWORD fdwOutputPrecision,    // 这个与下边三个也基本没啥用,都设成0即可

    DWORD fdwClipPrecision, //

    DWORD fdwQuality,   //

    DWORD fdwPitchAndFamily,    //

    LPCTSTR lpszFace    // 这个是字体名,一般我们要设置为宋体。

   );

这个函数的参数居然有14个,也就是说在Call CreateFontA前要有14个PUSH!不能多也不能少,当然最下边的字体名要第一个压入堆栈,而字体高度要最后一个压入堆栈。我们再来看看某个程序调用CreateFontA的反汇编代码:
1.jpg


不多不少,从字体名Arial开始正好14个吧?更为可贵的是:Ollydbg给我们把每一个参数都列了出来,我们就不用去数第几个push了。就这个字体的修改来说,只要把FaceName改成“宋体”,CharSet改成1或者86h,Height改为-12就可以了。最终的修改如下图:
2.jpg


大家会有疑问:为什么语系改成了push –7A而不是刚才的86了呢?因为就2字节的十六进制数来说,86实际上是被认为是-7A的,观察一下最左边的十六进制窗口,你就会发现代码实际上是6A86,即push 86。同样,-12的十六进制对应的是-0C。至于字体名,当然是我们的宋体。可以看到,压入字体名的那句是push 00402054,这个00402054是什么呢?当然不是“宋体”的ascii,而是“宋体”这个字串的指针,即字串的地址了。用Ollydbg的内存窗口查看该程序地址为00402054的地方可以清楚地看到该处是“宋体”:
3.jpg


或许看到这里你开始急了:这些都是怎么弄出来的啊?OD我还不会用啊,下边我就讲解一下具体步骤。

第一步,打开Ollydbg并装入我们的文件(这个该不用我给大家讲怎么做吧?)我打开的是附件中的我写的一个字体设置的例子.你会看见OllyDbg在分析我们的软件,因为大家的机器都比较好,我写的程序也比较短大家可能不注意看看不到这个过程哈,Ollydbg分析是相当快滴。分析完了就开始我们的操作:在反汇编代码区点击右键(注意了一定要在反汇编代码区,不同的区的右键菜单可是不同的)->搜索->所有模块间调用
4.jpg


你会发现列出了一个长长的列表,全是密密麻麻的英文,呵呵。
5.jpg


其中当然有我们要找的CreateFontA,不过如果是个大程序呢?找到相应的函数岂不很难了?我们可以排一下序,点击一下列表最上边的“目标”
6.jpg


这样就比较好找了吧?排序是以英文字母排序的因为CreateFontA的第一个字母是C所以比较靠前。我们先来分析第一个:把鼠标放在第一处调用CreateFontA的那一条上,双击,是不是切换到了主界面?并且选中了Call CreateFontA上?如图
7.jpg


这就找到了我上边刚开始说的地方啦,哈哈,是不是很简单?怎么改呢?第一个Arial改成“宋体”不用我教,你们汉化的本事都比我强。最好多余的补00,我们就试着改改别的参数。我不推荐到UE下去改,建议直接在Ollydbg下改。把鼠标在CharSet上点一下,然后按一下空格键出现了下图:
8.jpg


改成push 1或者push –7A,点击“汇编”按钮,就改好啦,用相同的方法,我又改了字体的字号,改的是push –0C.如下图:
9.jpg


接下来的工作就是把修改的结果复制回我们的程序了,操作如下:在反汇编代码区点击右键-〉复制到可执行文件-〉全部修正:
10.jpg


然后在弹出的对话框中选择复制的地方,我们选择“全部复制”弹出了下边的对话框
11.jpg


不用管他,关掉后弹出下边的对话框:
12.jpg


点击“是”即可弹出保存对话框。在98下无法覆盖原来的,2000/XP下则可以。当然我推荐你改个新名字来保存,如果出错可以返工。完成后运行我们的修改结果,你会发现第一个字体修改已经成功了。我暂时没改字体名,如可以用其他工具把字体名也改成“宋体”,这个CreateFontA也就算完美了。
13.jpg


CreateFontIndirectA的字体最好在动态下修改,先不作介绍,我在来讲讲GetStockObject的字体修改。GetStockObject这个词分开是Get Stock Object意思是“获得固有的对象”什么是固有的对象呢?就是windows自带的一些绘图对象,这个可不光包括字体,还有画笔,画刷,调色板等多种,每一种对象都对应一个数字号码,即一个id。我们所做的,就是把所有的FONT对象改成DEFAULT_GUI_FONT,即11号对象,以前我们用W32dasm改这类字体,需要查相应的说明,否则容易错改,如果你把人家获得画笔的代码改成了获得字体,那不出问题才怪。但是Ollydbg的出现大大减少了我们的工作量,因为Ollydbg能给我们标出是不是我们要改的地方。我实际改一下:在Ollydbg中找到GetStockObject的调用结果如下:
14.jpg


两处都是字体,分别是OEM_FIXED_FONT,跟SYSTEM_FONT,反正都是FONT,统一改成PUSH 11h,修改后如下:
15.jpg


按照上边的方法保存,运行结果如下图:
16.jpg


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SgzyStudio

GMT+8, 2024-4-28 10:34 , Processed in 0.125640 second(s), 25 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表