炎之川 |
2003-04-24 13:53 |
[原创] GetStockObject 非标准字体手动修改方法简介
GetStockObject 非标准字体手动修改方法简介
在这篇文章中,我将向大家简单的介绍一下使用 GetStockObject 设置的非标准字体块的修改方法。 相对于使用 CreateFontA 及 CreateFontIndirectA 两个函数的字体块来说,GetStockObject 并没有具体的设置使用某个字体,而是按照参数来“选择”一种备用字体来显示,所以相对而言,GetStockObject 字体块的修改比其他两类还要更容易一些。 通过查阅 MSDN,可知 GetStockObject 函数的结构: HGDIOBJ GetStockObject( int fnObject // stock object type ); 这个函数只有一个作为“标识”的参数,具体参数如下: #define BLACK_BRUSH 4 #define DKGRAY_BRUSH 3 #define GRAY_BRUSH 2 #define HOLLOW_BRUSH 5 #define LTGRAY_BRUSH 1 #define NULL_BRUSH 5 #define WHITE_BRUSH 0 #define BLACK_PEN 7 #define NULL_PEN 8 #define WHITE_PEN 6 #define ANSI_FIXED_FONT 11 #define ANSI_VAR_FONT 12 #define DEVICE_DEFAULT_FONT 14 #define DEFAULT_GUI_FONT 17 #define OEM_FIXED_FONT 10 #define SYSTEM_FONT 13 #define SYSTEM_FIXED_FONT 16 #define DEFAULT_PALETTE 15 用来选择画笔、画刷和调色版这些参数我们可以忽略不看,所以设置字体参数的就是 11~14、16~17,具体来说,压入堆栈的数值就是 0ah~0eh、10h。 字体参数对应的含义如下: ANSI_FIXED_FONT Windows fixed-pitch (monospace) system font. ANSI_VAR_FONT Windows variable-pitch (proportional space) system font. DEVICE_DEFAULT_FONT Windows NT/2000: Device-dependent font. DEFAULT_GUI_FONT Default font for user interface objects such as menus and dialog boxes. This is MS Sans Serif. Compare this with SYSTEM_FONT. OEM_FIXED_FONT Original equipment manufacturer (OEM) dependent fixed-pitch (monospace) font. SYSTEM_FONT System font. By default, the system uses the system font to draw menus, dialog box controls, and text. Windows 95/98 and NT: The system font is MS Sans Serif. Windows 2000: The system font is Tahoma SYSTEM_FIXED_FONT Fixed-pitch (monospace) system font. This stock object is provided only for compatibility with 16-bit Windows versions earlier than 3.0. 所以我们需要的字体就是“DEFAULT_GUI_FONT”,其对应代码是 17,即 0x11。 写到这里,使用 GetStockObject 设置的非标准字体块的修改方法就已经出来了,就是找到软件适用此函数的地方,前面的压栈语句 push xxx,如果“xxx”是 0A~0E,10,则将其改为 11 即可,即改为 push 11。
下面举几个具体的例子来说明一下: 例子一、点睛字体设置示例 我们需要的是梁利锋兄特别写的一个版本,其中包括使用 CreateFontA、CreateFontIndirectA、GetStockObject 三种函数设置字体的例子,这个文件可以在汉化新世纪论坛“梁利锋专版”找到。 使用 W32Dasm 反汇编,搜索“GetStockObject”,找到下面的代码段: :004010D8 6A0B push 0000000B //ObjType = ANSI_FIXED_FONT * Reference To: GDI32.GetStockObject, Ord:01A5h | :004010DA FF1514204000 Call dword ptr [00402014] :004010E0 50 push eax :004010E1 56 push esi :004010E2 FFD5 call ebp :004010E4 6880204000 push 00402080 :004010E9 FFD7 call edi :004010EB 50 push eax :004010EC 6880204000 push 00402080 :004010F1 6854010000 push 00000154 :004010F6 6A3C push 0000003C :004010F8 56 push esi :004010F9 FFD3 call ebx :004010FB 6A0C push 0000000C //ObjType = ANSI_VAR_FONT * Reference To: GDI32.GetStockObject, Ord:01A5h | :004010FD FF1514204000 Call dword ptr [00402014] :00401103 50 push eax :00401104 56 push esi :00401105 FFD5 call ebp :00401107 6880204000 push 00402080 :0040110C FFD7 call edi :0040110E 50 push eax :0040110F 6880204000 push 00402080 :00401114 6868010000 push 00000168 :00401119 6A3C push 0000003C :0040111B 56 push esi :0040111C FFD3 call ebx :0040111E 6A0D push 0000000D //ObjType = SYSTEM_FONT * Reference To: GDI32.GetStockObject, Ord:01A5h | :00401120 FF1514204000 Call dword ptr [00402014] :00401126 50 push eax :00401127 56 push esi :00401128 FFD5 call ebp :0040112A 6880204000 push 00402080 :0040112F FFD7 call edi :00401131 50 push eax :00401132 6880204000 push 00402080 :00401137 687C010000 push 0000017C :0040113C 6A3C push 0000003C :0040113E 56 push esi :0040113F FFD3 call ebx :00401141 6A0E push 0000000E //ObjType = DEVICE_DEFAULT_FONT * Reference To: GDI32.GetStockObject, Ord:01A5h | :00401143 FF1514204000 Call dword ptr [00402014] :00401149 50 push eax :0040114A 56 push esi :0040114B FFD5 call ebp :0040114D 6880204000 push 00402080 :00401152 FFD7 call edi :00401154 50 push eax :00401155 6880204000 push 00402080 :0040115A 6890010000 push 00000190 :0040115F 6A3C push 0000003C :00401161 56 push esi :00401162 FFD3 call ebx :00401164 6A10 push 00000010 //ObjType = SYSTEM_FIXED_FONT * Reference To: GDI32.GetStockObject, Ord:01A5h | :00401166 FF1514204000 Call dword ptr [00402014] :0040116C 50 push eax :0040116D 56 push esi :0040116E FFD5 call ebp :00401170 6880204000 push 00402080 :00401175 FFD7 call edi :00401177 50 push eax :00401178 6880204000 push 00402080 :0040117D 68A4010000 push 000001A4 :00401182 6A3C push 0000003C :00401184 56 push esi :00401185 FFD3 call ebx :00401187 6A11 push 00000011 //ObjType = DEFAULT_GUI_FONT,这是我们需要的字体,即宋体 * Reference To: GDI32.GetStockObject, Ord:01A5h | :00401189 FF1514204000 Call dword ptr [00402014] :0040118F 50 push eax 所以修改方法很简单,将我做注释的代码改为 push 00000011 即可,修改前后的效果如图一所示。
例子二、1toX v2.63 Build 2002.05.03 1toX 是一个文件分割软件,官方主页是 http://www.logipole.com/ 软件主程序使用 Armadillo 2.52 加壳,支持语言文件。脱壳并优化文件结构后,随便汉化一点,可以看到菜单字体显示极为难看(如图二),通过分析可知软件使用了 GetStockObject 函数设置字体,所以使用 W32Dasm 反汇编,并搜索“GetStockObject”,发现有两处是设置字体的:
第一处 * Referenced by a CALL at Address: |:004044E5 | :00404180 83EC0C sub esp, 0000000C :00404183 53 push ebx :00404184 8B5C2414 mov ebx, dword ptr [esp+14] :00404188 55 push ebp :00404189 56 push esi :0040418A 8B6B14 mov ebp, dword ptr [ebx+14] :0040418D 57 push edi :0040418E 6A0C push 0000000C //使用 ANSI_VAR_FONT,我们改为 push 00000011 * Reference To: GDI32.GetStockObject, Ord:01A6h | :00404190 FF1560504300 Call dword ptr [00435060] :00404196 8BF8 mov edi, eax :00404198 6A00 push 00000000 :0040419A 897C2414 mov dword ptr [esp+14], edi 第二处 * Referenced by a CALL at Address: |:004044C5 | :00404210 83EC10 sub esp, 00000010 :00404213 53 push ebx :00404214 55 push ebp :00404215 56 push esi :00404216 8B742420 mov esi, dword ptr [esp+20] :0040421A 57 push edi :0040421B 6A0C push 0000000C //使用 ANSI_VAR_FONT,我们改为 push 00000011 :0040421D 8B462C mov eax, dword ptr [esi+2C] :00404220 89442428 mov dword ptr [esp+28], eax * Reference To: GDI32.GetStockObject, Ord:01A6h | :00404224 FF1560504300 Call dword ptr [00435060] :0040422A 89442418 mov dword ptr [esp+18], eax :0040422E 8A4610 mov al, byte ptr [esi+10] :00404231 A801 test al, 01 :00404233 7442 je 00404277 修改完成后保存,看看效果,呵呵,搞定了 (如图三)
例子三、RenderSoft CamStudio v2.00 CamStudio 是一个屏幕摄像工具。它可以捕获屏幕上你所进行的操作,保存为标准的 AVI 视频文件。其官方主页为:http://www.atomixbuttons.com/ 分析后发现软件共有三处使用了 GetStockObject 设置字体,分别如下:
第一处 * Reference To: GDI32.CreateCompatibleDC, Ord:002Ah | :0041C707 FF15F0904200 Call dword ptr [004290F0] :0041C70D 6A0C push 0000000C //使用 ANSI_VAR_FONT,我们改为 push 00000011 :0041C70F 8BE8 mov ebp, eax * Reference To: GDI32.GetStockObject, Ord:015Fh | :0041C711 FF15B8904200 Call dword ptr [004290B8] :0041C717 50 push eax 第二处 * Referenced by a (U)nconditional or ©onditional Jump at Address: |:0041E4C3(U) | :0041E4D2 6A0C push 0000000C //使用 ANSI_VAR_FONT,我们改为 push 00000011 * Reference To: GDI32.GetStockObject, Ord:015Fh | :0041E4D4 FF15B8904200 Call dword ptr [004290B8] :0041E4DA 50 push eax
第三处 :0041E998 FFD3 call ebx :0041E99A 6A0C push 0000000C //使用 ANSI_VAR_FONT,我们改为 push 00000011 :0041E99C 8944244C mov dword ptr [esp+4C], eax * Reference To: GDI32.GetStockObject, Ord:015Fh | :0041E9A0 FF15B8904200 Call dword ptr [004290B8] :0041E9A6 50 push eax :0041E9A7 55 push ebp :0041E9A8 FFD3 call ebx
修改之后,软件界面就很清爽了
OK,这篇文章就写到这里了,希望在碰到 GetStockObject 设置的非标准字体修改问题时,本文能够对大家有所启发和帮助。
参考资料: 1、微软 MSDN 2、“一个小小的挑战……”(http://bbs.hanzify.org/bbs/cgi-bin/topic.cgi?forum=27&topic=9&show=0)
附录:MSDN 中的相关内容 GetStockObject The GetStockObject function retrieves a handle to one of the stock pens, brushes, fonts, or palettes. HGDIOBJ GetStockObject( int fnObject // stock object type ); Parameters fnObject [in] Specifies the type of stock object. This parameter can be one of the following values. Value Meaning BLACK_BRUSH Black brush. DKGRAY_BRUSH Dark gray brush. DC_BRUSH Windows 98, Windows 2000: Solid color brush. The default color is white. The color can be changed by using the SetDCBrushColor function. For more information, see the Remarks section. GRAY_BRUSH Gray brush. HOLLOW_BRUSH Hollow brush (equivalent to NULL_BRUSH). LTGRAY_BRUSH Light gray brush. NULL_BRUSH Null brush (equivalent to HOLLOW_BRUSH). WHITE_BRUSH White brush. BLACK_PEN Black pen. DC_PEN Windows 98, Windows 2000: Solid pen color. The default color is white. The color can be changed by using the SetDCPenColor function. For more information, see the Remarks section. WHITE_PEN White pen. ANSI_FIXED_FONT Windows fixed-pitch (monospace) system font. ANSI_VAR_FONT Windows variable-pitch (proportional space) system font. DEVICE_DEFAULT_FONT Windows NT/2000: Device-dependent font. DEFAULT_GUI_FONT Default font for user interface objects such as menus and dialog boxes. This is MS Sans Serif. Compare this with SYSTEM_FONT. OEM_FIXED_FONT Original equipment manufacturer (OEM) dependent fixed-pitch (monospace) font. SYSTEM_FONT System font. By default, the system uses the system font to draw menus, dialog box controls, and text. Windows 95/98 and NT: The system font is MS Sans Serif. Windows 2000: The system font is Tahoma SYSTEM_FIXED_FONT Fixed-pitch (monospace) system font. This stock object is provided only for compatibility with 16-bit Windows versions earlier than 3.0. DEFAULT_PALETTE Default palette. This palette consists of the static colors in the system palette.
Return Values If the function succeeds, the return value is a handle to the requested logical object. If the function fails, the return value is NULL. Windows NT/2000: To get extended error information, call GetLastError. Remarks Use the DKGRAY_BRUSH, GRAY_BRUSH, and LTGRAY_BRUSH stock objects only in windows with the CS_HREDRAW and CS_VREDRAW styles. Using a gray stock brush in any other style of window can lead to misalignment of brush patterns after a window is moved or sized. The origins of stock brushes cannot be adjusted. The HOLLOW_BRUSH and NULL_BRUSH stock objects are equivalent. The font used by the DEFAULT_GUI_FONT stock object could change. Use this stock object when you want to use the font that menus, dialog boxes, and other user interface objects use. It is not necessary (but it is not harmful) to delete stock objects by calling DeleteObject. Windows 98, Windows 2000: Both DC_BRUSH and DC_PEN can be used interchangeably with other stock objects like BLACK_BRUSH and BLACK_PEN. For information on retrieving the current pen or brush color, see GetDCBrushColor and GetDCPenColor. See Setting the Pen or Brush Color for an example of setting colors. The GetStockObject function with an argument of DC_BRUSH or DC_PEN can be used interchangeably with the SetDCPenColor and SetDCBrushColor functions. Requirements Windows NT/2000: Requires Windows NT 3.1 or later. Windows 95/98: Requires Windows 95 or later. Header: Declared in Wingdi.h; include Windows.h. Library: Use Gdi32.lib.
作者:汉化新世纪成员-炎之川 2003.4.23 主页:http://skipli.yeah.net/ |
|