靜態庫破解方法――skinmagic
靜態庫破解方法――skinmagic
靜態庫可以直接硬連結到可執行檔案中,雖然體積大了些,執行效率並不差,另外由於執行時不需要該靜態庫,
用靜態庫編譯生成的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版均是如此。
http://masterdog.blogchina.com
相關文章
- net 靜態方法與非靜態方法2024-05-25
- Linux 依賴動態庫 / 靜態庫的動態態庫 / 靜態庫2017-05-02Linux
- 靜態方法2024-07-26
- 靜態變數與靜態方法2014-07-25變數
- 靜態庫與動態庫2024-06-22
- JavaScript 靜態屬性與靜態方法2018-12-15JavaScript
- 靜態庫生成2018-06-06
- 動靜態庫2024-10-03
- ios靜態庫和動態庫2018-04-22iOS
- Java的方法靜態方法2020-09-05Java
- cmake:生成靜態庫和動態庫2020-12-26
- Android NDK祕籍--編譯靜態庫、呼叫靜態庫2019-04-21Android編譯
- BubbleKing V2.63 完全靜態破解2004-06-14
- .net呼叫靜態庫2009-03-10
- 靜態庫與DLL2011-03-10
- iOS 靜態庫 與私有庫2018-03-16iOS
- 動態庫和靜態庫的區別2017-05-02
- C靜態庫的建立與使用--為什麼要引入靜態庫?2023-10-11
- iOS靜態庫SDK製作(包含第三方靜態庫)2017-12-14iOS
- Linux共享庫、靜態庫、動態庫詳解2024-04-20Linux
- Promise 原始碼:靜態方法2019-03-01Promise原始碼
- Object上的靜態方法2019-02-16Object
- static靜態方法的使用2024-10-08
- PHP 中 static 靜態屬性和靜態方法的呼叫2017-01-16PHP
- PHP類的靜態(static)方法和靜態(static)變數2013-01-31PHP變數
- iOS的Framework靜態庫2018-05-31iOSFramework
- iOS 靜態庫開發2015-09-23iOS
- 靜態資源公共庫2024-06-24
- 動態連結庫與靜態連結庫2021-11-19
- iOS動態庫和靜態庫的運用2022-03-04iOS
- 菜鳥教程——iOS動態庫與靜態庫2017-07-05iOS
- linux下的靜態庫與動態庫2018-04-28Linux
- iOS 靜態庫(.a, .framework) 動態庫(.framework, dylib)2017-06-16iOSFramework
- ios靜態庫與動態庫的區別2016-02-27iOS
- Linux下的共享庫(動態庫)和靜態庫2013-01-10Linux
- Linux下把靜態庫編譯進PHP的方法2017-11-08Linux編譯PHP
- VS 環境下生成靜態lib庫及呼叫方法2013-08-15
- NDK 連結第三方靜態庫的方法2013-08-21