最近在研究软件的破解,其中心酸只有自己知道,走了多少曲折之路,多少个不眠的夜晚。还好我坚持下来了,并且初步尝试到成功的喜悦;下面介绍一款餐饮软件的成功爆破过程;
在逆向工程领域,OllyDbg是最最完美的反编译调试工具。
1,先给软件脱壳(查壳工具:PEiD.exe);
是 aspack的壳,啥也不说脱掉。。。
2,软件脱壳:
成功脱掉原先的aspack壳。让我来看看还有没有壳:
哈哈,没壳了 delphi的程序.用dede反编译分析:
od 分析:
经过千辛万苦的分析调试,终于找到关键跳转:
* Reference to : TRegware4._PROC_00538E64()
|
006FCC3A E825C2E3FF call 00538E64 //此处是判断注册的关键call
006FCC3F 84C0 test al, al
006FCC41 0F8589000000 jnz 006FCCD0 //此处跳转注册还是非注册。。。
好了,改掉他就ok了,006FCC41 0F8589000000 jnz 006FCCD0 改成006FCC41 0F8589000000 jmp 006FCCD0
呵呵,成为成为注册版了。^_^ 成功了???调个系统时间看看还有没有暗壮,往后调一个月看看,哦,shit,还有暗壮。这款软件网上有人也破解的,但是没有去掉这个暗壮。
又要分析了,看他这个软件用的是免费的regware4,呵呵 google一下,发现他写注册表,HKEY_CLASSES_ROOT/CLSID/{pid}/Info/data和 HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/{pid}/Info/data,只要删除这两个键值即可达到正常进入软件,细心的观察每次软件都要判断是否有注册表项,如果有的话,分析对比,然后写注册表。
哈哈,怎样实现爆破呢,永远不提示注册窗口。。od debug半天没找到。。。shit!
苦思冥想,呵呵。有了,PE文件代码注入,我只要在运行这个软件之前加一段代码,破坏这个注册表项就OK.于是,写了一段c++代码:
- #include "stdafx.h"
- #include <windows.h>
- int main(int argc, char* argv[])
- {
- // printf("Hello World!/n");
- HKEY hKey;
- try{
- long ret=::RegOpenKeyEx(HKEY_CLASSES_ROOT,"CLSID//{pid}//Info//",0,KEY_ALL_ACCESS,&hKey);
- if(ret!=ERROR_SUCCESS)
- return 0;
- ::RegDeleteValue(hKey,"Data");
- ::RegCloseKey(hKey);
- }catch(...){}
- return 0;
- }
反编译:
代码注入:(其实就是一个跳转的功能)
改写的汇编:
- // Place your code here ...
- push ecx
- // lea eax, [ebp+_p_dwRet] ;
- lea eax, [esp] ;
- push eax ; /pHandle
- push KEY_ALL_ACCESS ; |Access = KEY_ALL_ACCESS
- push 0 ; |Reserved = 0
- // push 00406038 ; |Subkey = "CLSID/{pid}/Info/"
- lea ebx,[ebp+_p_szPGuid] ;
- push ebx ;
- push 0x80000000 ; |hKey = HKEY_CLASSES_ROOT
- // call dword ptr [<&ADVAPI32.RegOpenKey>; /RegOpenKeyExA
- call _jmp_RegOpenKeyEx
- test eax, eax
- jnz _regopenfailed
- // mov ecx, [ebp+_p_dwRet] ;
- mov ecx, [esp] ;
- // push 00406030 ; /ValueName = "Data"
- lea ebx,[ebp+_p_szData] ;
- push ebx ;
- push ecx ; |hKey
- // call dword ptr [<&ADVAPI32.RegDeleteV>; /RegDeleteValueA
- call _jmp_RegDeleteValue ;
- // mov edx, [ebp+_p_dwRet] ;
- lea edx, [esp] ;
- push edx ; /hKey
- // call dword ptr [<&ADVAPI32.RegCloseKe>; /RegCloseKey
- call _jmp_RegCloseKey
- xor eax, eax ;
- _regopenfailed:
- pop ecx ;
改写老外的Pemaker程序,实现代码注入:
- _p_szAdvApi32: //db "AdvApi32.dll",0,13
- db db db db db db db db db db db db db
- _p_szRegOpenKeyEx: //db "RegOpenKeyExA",0,14
- db db db db db db db db db db db db db db
- _p_szRegDeleteValue: //db "RegDeleteValueA",0,16
- db db db db db db db db db db db db db db db db
- _p_szRegCloseKey: //db "RegCloseKey",0,12
- db db db db db db db db db db db db
- byte_type(0)
- byte_type(0)
- //----------------------------------
- _p_LoadLibrary: dword_type(0xCCCCCCCC)
- _p_GetProcAddress: dword_type(0xCCCCCCCC)
- _p_GetModuleHandle:
- dword_type(0xCCCCCCCC)
- dword_type(0xCCCCCCCC)
- dword_type(0xCCCCCCCC)
- dword_type(0xCCCCCCCC)
- dword_type(0xCCCCCCCC)
- dword_type(0xCCCCCCCC)
- dword_type(0xCCCCCCCC)
- dword_type(0xCCCCCCCC)
- dword_type(0xCCCCCCCC)
- _jmp_GetModuleHandle: __jmp_api dword_type(0xCCCCCCCC)
- _jmp_VirtualProtect: __jmp_api dword_type(0xCCCCCCCC)
- _jmp_GetModuleFileName: __jmp_api dword_type(0xCCCCCCCC)
- _jmp_CreateFile: __jmp_api dword_type(0xCCCCCCCC)
- _jmp_GlobalAlloc: __jmp_api dword_type(0xCCCCCCCC)
- _jmp_MessageBox: __jmp_api dword_type(0xCCCCCCCC)
- _jmp_RegOpenKeyEx: __jmp_api dword_type(0xCCCCCCCC)
- _jmp_RegDeleteValue: __jmp_api dword_type(0xCCCCCCCC)
- _jmp_RegCloseKey: __jmp_api dword_type(0xCCCCCCCC)
- _p_szText:
- bb('H') bb('e') bb('l') bb('l') bb('o') bb(' ')
- bb('W') bb('o') bb('r') bb('l') bb('d') bb('!')
- bb(' ') bb(' ') bb(' ') bb(' ') bb(0)
- _p_szCaption:
- bb('A') bb('s') bb('h') bb('k') bb('b') bb('i') bb('z') bb(0)
- _p_szPGuid:..... bb(0)
- _p_szData:
- bb('D') bb('a') bb('t') bb('a') bb(0)
- const char *szWindowsAPIs[]=
- {
- "Kernel32.dll",
- "GetModuleHandleA",
- "VirtualProtect",
- "GetModuleFileNameA",
- "CreateFileA",
- "GlobalAlloc",
- 0,
- "User32.dll",
- "MessageBoxA",
- 0,
- "AdvApi32.dll",
- "RegOpenKeyExA",
- "RegDeleteValueA",
- "RegCloseKey",
- 0,
- 0,
- };
好了,一切over。破解完成,看看成果把;