1.Use static libary 此时被调用函数的代码将会被打包进可执行文件。 ---------------------------------------------------------------------------- 静态库破解方法――skinmagic
(DylanWind)静态库可以直接硬链接到可执行文件中,虽然体积大了些,运行效率并不差,另外由于运行时不需要该静态库, 用静态库编译生成的exe文件就看不出使用像skinmagic之类的库的痕迹了:) 。不过与动态库不同,静态库是 COFF格式的,无法像可执行文件那样被直接反编译,给破解带来了一定的难度,本文提供了skinmagic静态库的 破解过程,不失一般性,文中所用的方法可以用在其它静态库的破解中。 SkinMagic的静态库包括: =============== Visual C++6 .0 =============== SkinMagicLibMT6Trial.lib For Visual C++ 6.0 link with multithreaded run-time library. SkinMagicLibMD6Trial.lib For Visual C++ 6.0 link with multithreaded DLL run-time library. =============== Visual C++ 7.0 =============== SkinMagicLibMT7Trial.lib For Visual C++ 7.0 link with multithreaded run-time library. SkinMagicLibMD7Trial.lib For Visual C++ 7.0 link with multithreaded DLL run-time library. 其中的MT代表multithreaded,而MD代表multithreaded DLL,需要在 msdev 的Project/Setting的C++ / Code Generation标签下选择,如果你的工程要用MT类型的静态库,则debug版要选择"Debug Multithreaded",release 版要选择"Multithreaded";如果要用MD类型的静态库,则debug版需要选择"Debug Multithreaded DLL",release 版要选择"Multithreaded DLL"。 数字6代表for Visual C++ 6.0, 7代表for Visual C++ 7.0 我个人用msvc6,因此这里以SkinMagicLibMT6Trial.lib为例进行破解,其它静态库文件破法相同。 首先选择debug版,将静态库包含在stdAfx.h中: #include "SkinMagicLib.h"#pragma comment(lib, "SkinMagicLibMT6Trial.lib") 然后按照skinmagic帮助在你的工程中添加代码,编译运行后弹出消息框提示未注册,点击确定后发现皮肤正常 加载。这当然不是我们希望看到的,需要去掉这个讨厌的消息框。该消息框是由User32.dll中的函数MessageBox 产生的(其实是个宏,真正会调用MessageBoxA或MessageBoxW拉)。MessageBoxA(或MessageBoxW,为了行文方 便,不再提它了)在静态库SkinMagicLibMT6Trial.lib中属于导入(import)函数,因此首先想到的是将静态库 IAT中的MessageBoxA symbol给搞掉。 方法一(失败): 用UtraEdit将静态库打开(HEX模式),alt+F3 查找ASCII字符串:"MessageBoxA",直到找到: __imp__MessageBoxA@16 ??_C@_0N@FCOF@Unregistered?$AA __imp__XXX是一个Symbol(注意不是地址,这也是失败原因),能够定位到import library(User32.dll)中正确 的IAT entry,当你自己写动态库时,定义函数:__declspec(dllimport) __stdcall void Fun(void);会产生类似 效果。@16表示参数占16个字节,我们知道MessageBoxA有四个参数,函数原型: WINUSERAPI int WINAPI MessageBoxA( HWND hWnd , LPCSTR lpText, LPCSTR lpCaption, UINT uType); 其实就是: __declspec(dllimport) int __stdcall MessageBoxA( HWND hWnd , LPCSTR lpText, LPCSTR lpCaption, UINT uType); 我把UtraEdit定位的代码改成了其它函数(比如Sleep),列举如下: __imp__Sleep @ 4 注意其它未被覆盖的地方一律用0x00填充,保存后将修改后的静态库重新编译链接到工程,运行后OK了,不再弹 那个NAG了,这么简单就搞定了!!! 没高兴太久就发现Debug版虽然OK了,可是Release版运行时会出错!这种野蛮的方式行不通。 方法二(成功): 需要用到msdev提供的两个命令行方式的工具:lib管理器和dumpbin, 要想在任何地方都可以运行最好确保以下批 处理文件已经被执行过了: "install path"\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT 要查看lib管理器的版本,在console中运行"lib"后,提示:Microsoft (R) Library Manager Version 6.00.8168 要查看dumpbin的版本,在console中运行"dumpbin"后,提示:Microsoft (R) COFF Binary File Dumper Version 6.00.8168 破解流程如下:我们需要用lib管理器定位并导出静态库中那个产生消息框的obj,然后用dumpbin分析该obj文件, 用hex编辑器(这里用的是hiew)屏蔽掉该obj文件中调用MessageBox的代码,最后将修改后的obj再导入到静态库 中,这就是整个破解过程。 步骤1 --导出obj,定位需要被破解的obj: 首先运行以下命令将静态库中的所有*.obj文件导出到一个文件中:lib /LIST SkinMagicLibMT6Trial.lib > liblist.txt 内容如下(总共124个obj文件,不一一列举了): \WORKING\temp\vc6\Trial_Release\AnimateCtrlSkinData.obj \WORKING\temp\vc6\Trial_Release\AnimEffect.obj \WORKING\temp\vc6\Trial_Release\ApplicationSkinData.obj \WORKING\temp\vc6\Trial_Release\AreaSkinData.obj ... ... 然后利用UltraEdit编辑liblist.txt,用Column菜单的Insert/Fill column功能做一个批处理文件dumpobj.bat,形如: lib SkinMagicLibMT6Trial.lib /EXTRACT:\WORKING\temp\vc6\Trial_Release\AnimateCtrlSkinData.obj lib SkinMagicLibMT6Trial.lib /EXTRACT:\WORKING\temp\vc6\Trial_Release\AnimEffect.obj lib SkinMagicLibMT6Trial.lib /EXTRACT:\WORKING\temp\vc6\Trial_Release\ApplicationSkinData.obj lib SkinMagicLibMT6Trial.lib /EXTRACT:\WORKING\temp\vc6\Trial_Release\AreaSkinData.obj ... ... 运行该批处理文件会将静态库中的所有obj文件导出到当前目录下,此时再用UltraEdit将所有obj文件打开,选择 "search / Find in Files",查找关键字"__imp__MessageBoxA",发现只有在SkinMagicLib.obj中找到了它,需 要破解的obj文件找到了!就是SkinMagicLib.obj。 步骤2 --分析需要被破解的obj: 运行以下命令dump出SkinMagicLib.obj中尽可能详细的信息:dumpbin /ALL SkinMagicLib.obj > dumpcrackingobj.txt 在该文件中查找__imp__MessageBoxA,发现以下信息: ... ... RELOCATIONS #38 Symbol Symbol Offset Type Applied To Index Name -------- ---------------- ----------------- -------- ------ ... ... 00000149 DIR32 00000000 C6 __imp__MessageBoxA @ 16 ... ... 表示在RELOCATIONS #38的00000149处调用了MessageBoxA函数,向上滚屏,看一下 SECTION HEADER #38的信息: SECTION HEADER #38 .text name 0 physical address 0 virtual address 291 size of raw data 3690 file pointer to raw data 3921 file pointer to relocation table 0 file pointer to line numbers 3A number of relocations 0 number of line numbers 60101020 flags Code Communal; sym= "int __stdcall InitSkinMagicLib(struct HINSTANCE__ *,char const *, char const *,char const *)" (?InitSkinMagicLib@@YGHPAUHINSTANCE__@@PBD11@Z) 1 byte align Execute Read RAW DATA #38 00000000: B8 00 00 00 00 E8 00 00 00 00 83 EC 20 A1 0C 00 ............ ... 00000010: 00 00 53 33 DB 56 57 8B 3D 00 00 00 00 3B C3 BE ..S3.VW.=....;.. 00000020: 00 00 00 00 0F 85 2A 01 00 00 56 FF 15 00 00 00 ......*...V..... 00000030: 00 56 89 75 EC FF D7 8B 45 08 68 00 00 00 00 89 .V.u....E.h..... 00000040: 5D FC A3 00 00 00 00 FF 15 00 00 00 00 68 00 00 ]............h.. 00000050: 00 00 50 FF 15 00 00 00 00 A3 00 00 00 00 E8 00 ..P............. 00000060: 00 00 00 85 C0 75 2C FF 15 00 00 00 00 89 45 E4 .....u,.......E. 00000070: 8D 45 E4 50 89 5D E8 8D 45 DC 50 B9 00 00 00 00 .E.P.]..E.P..... 00000080: E8 00 00 00 00 8B 00 C7 40 10 01 00 00 00 E9 8F ........@....... 00000090: 00 00 00 E8 00 00 00 00 85 C0 75 15 FF 15 00 00 ..........u..... 000000A0: 00 00 89 45 E4 8D 45 E4 50 89 5D E8 8D 45 DC EB ...E..E.P.]..E.. 000000B0: C9 E8 00 00 00 00 8B C8 53 89 4D F0 E8 00 00 00 ........S.M..... 000000C0: 00 FF 75 08 8B 4D F0 E8 00 00 00 00 E8 00 00 00 ..u..M.......... 000000D0: 00 3B C3 A3 00 00 00 00 7C 05 83 F8 03 7E 0A E8 .;......|....~.. 000000E0: 00 00 00 00 A1 00 00 00 00 83 F8 07 75 42 FF 75 ............uB.u 000000F0: 08 E8 00 00 00 00 85 C0 59 75 35 FF 15 00 00 00 ........Yu5..... 00000100: 00 89 45 E4 8D 45 E4 50 8D 45 DC 50 B9 00 00 00 ..E..E.P.E.P.... 00000110: 00 89 5D E8 E8 00 00 00 00 8B 00 C7 40 10 11 00 ..].........@... 00000120: 00 00 56 FF 15 00 00 00 00 33 C0 E9 50 01 00 00 ..V......3..P... 00000130: 6A 40 68 00 00 00 00 68 00 00 00 00 53 C7 05 00 j@h....h....S... 00000140: 00 00 00 01 00 00 00 FF 15 00 00 00 00 56 FF 15 .............V.. 00000150: 00 00 00 00 56 89 75 E8 FF D7 8B 3D 00 00 00 00 ....V.u....=.... 00000160: C7 45 FC 01 00 00 00 FF D7 89 45 08 8D 45 08 50 .E........E..E.P 00000170: 8D 45 F0 BB 00 00 00 00 50 8B CB E8 00 00 00 00 .E......P....... 00000180: 8B 45 F0 3B 05 04 00 00 00 75 3E FF 75 08 FF 35 .E.;.....u>.u..5 00000190: 00 00 00 00 68 00 00 00 00 6A 04 FF 15 00 00 00 ....h....j...... 000001A0: 00 85 C0 89 45 EC 74 72 8B 45 08 83 65 E0 00 89 ....E.tr.E..e... 000001B0: 45 DC 8D 45 DC 50 8D 45 D4 50 8B CB E8 00 00 00 E..E.P.E.P...... 000001C0: 00 8B 00 8B 4D EC 89 48 10 8D 45 08 BB 00 00 00 ....M..H..E..... 000001D0: 00 50 8D 45 EC 50 8B CB E8 00 00 00 00 8B 45 EC .P.E.P........E. 000001E0: 3B 05 04 00 00 00 89 45 F0 75 73 FF 75 08 FF 35 ;......E.us.u..5 000001F0: 00 00 00 00 68 00 00 00 00 6A 02 FF 15 00 00 00 ....h....j...... 00000200: 00 85 C0 89 45 EC 74 39 8D 45 08 8B CB 50 E8 00 ....E.t9.E...P.. 00000210: 00 00 00 8B 4D EC 89 08 EB 44 FF D7 89 45 DC 8D ....M....D...E.. 00000220: 45 DC 50 8D 45 D4 33 FF 50 B9 00 00 00 00 89 7D E.P.E.3.P......} 00000230: E0 E8 00 00 00 00 8B 00 C7 40 10 02 00 00 00 EB .........@...... 00000240: 36 FF D7 89 45 EC 8D 45 EC 50 B9 00 00 00 00 E8 6...E..E.P...... 00000250: 00 00 00 00 C7 00 03 00 00 00 33 FF EB 19 FF D7 ..........3..... 00000260: 89 45 EC 8D 45 EC 50 B9 00 00 00 00 E8 00 00 00 .E..E.P......... 00000270: 00 83 20 00 6A 01 5F 56 FF 15 00 00 00 00 8B C7 .. .j._V........ 00000280: 8B 4D F4 5F 5E 5B 64 89 0D 00 00 00 00 C9 C2 10 .M._^[d......... 00000290: 00 ^_^,可以看到SECTION HEADER #38是InitSkinMagicLib函数的实现部分: int __stdcall InitSkinMagicLib(struct HINSTANCE__ *,char const *,char const *,char const *) 也就是说MessageBoxA是在InitSkinMagicLib函数中调用的,而且位置在00000149。 看看上面RAW DATA #38中函数体部分(00000000-00000290),可以看到00000149所在行的二进制信息: 00000140: 00 00 00 01 00 00 00 FF 15 00 00 00 00 56 FF 15 其中00 00 00 00表示00000149起始的函数地址,所以FF 15 00 00 00 00 表示:call 0000000实际上就是调 用MessageBoxA函数,只不过这里的地址不是实际地址罢了,我们不必关心它。 通过上述分析可以确定00000000-00000290间的部分就是需要修改的代码,你可以用二进制编辑器(如 UltraEdit)在SkinMagicLib.obj中定位到这部分代码,导出到一个文件中后用反汇编软件进行分析,或者 像我接下来要做的那样直接用dumpbin来分析(效果要好些,也更简单些)。 再次运行dumpbin,反汇编SkinMagicLib.obj,命令如下: dumpbin /disasm SkinMagicLib.obj > dumpasm.txt 编辑该文件,查找InitSkinMagicLib,会看到如下信息: ?InitSkinMagicLib@@YGHPAUHINSTANCE__@@ PBD11 @ Z (int __stdcall InitSkinMagicLib(struct HINSTANCE__ *, char const *,char const *,char const *)): 00000000: B8 00 00 00 00 mov eax,offset ?InitSkinMagicLib@@YGHPAUHINSTANCE__@@PBD11@Z 00000005: E8 00 00 00 00 call 0000000A 0000000A: 83 EC 20 sub esp,20h ... ... 000000EC: 75 42 jne 00000130 000000EE: FF 75 08 push dword ptr [ebp+8] 000000F1: E8 00 00 00 00 call 000000F6 000000F6: 85 C0 test eax,eax 000000F8: 59 pop ecx 000000F9: 75 35 jne 00000130 ... ... 0000012B: E9 50 01 00 00 jmp 00000280 00000130: 6A 40 push 40h 00000132: 68 00 00 00 00 push offset ?InitSkinMagicLib@@YGHPAUHINSTANCE__@@PBD11@Z 00000137: 68 00 00 00 00 push offset ?InitSkinMagicLib@@YGHPAUHINSTANCE__@@PBD11@Z 0000013C: 53 push ebx 0000013D: C7 05 00 00 00 00 mov dword ptr [?InitSkinMagicLib@@YGHPAUHINSTANCE__@@PBD11@Z],1 01 00 00 0000000147: FF 15 00 00 00 00 call dword ptr [?InitSkinMagicLib@@YGHPAUHINSTANCE__@@PBD11@Z] 0000014D: 56 push esi 0000014E: FF 15 00 00 00 00 call dword ptr [?InitSkinMagicLib@@YGHPAUHINSTANCE__@@PBD11@Z]... 可以看出与破解dll时候碰到的代码基本一致, 我做了如下修改(用hiew): ... ... 000000EC: 75 42 jmps 0000013D ... ... 00000147: FF 15 00 00 00 00 jmps 0000014D ... ... 就可以跳过MessageBox调用了:) 步骤3 --分将修改后的obj导入到静态库: 直接运行以下命令将修改后的obj文件再导入到静态库:lib SkinMagicLibMT6Trial.lib SkinMagicLib.obj 或者生成一个新的库:lib /OUT:SkinMagicLibMT6.lib SkinMagicLibMT6Trial.lib SkinMagicLib.obj 将这个库(已经破解了)链接到你的工程,编译运行后发现不再提示注册了,debug和release版均是如此。附件是破解文件 附件[SkinMagicLibMT6.rar]http://blog.blogchina.com/upload/2004-11-17/20041117085223218762.rar |