注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

中国古代易经之精华四柱八字之研究和实践

偏印是人类潜藏的灵感和智慧,火克金初形成之水是智慧之源泉。

 
 
 

日志

 
 

Tornado2之Licence暴力破解 成功案例推荐  

2009-12-22 16:20:40|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Tornado2之Licence暴力破解

Tornado2是VxWorks开发调试工具,试用期为一个月.

超过试用期需要Licence支持,一个Licence需要$6000~$2000.买了软件,还要花钱,真是!@#$%^&*.

破解如下,希望对大家有用. :)

1.跟踪:

Tornado2的Licence程序主要运行在 ...\\host\\x86-win32\\bin\\tgtsvr.exe(...为Tornado2安装目录)

经过痛苦的跟踪过程,发现008B5236处为判断鉴权是否成功(该地址是在NT4.0+SP5.0中,可能系统

不一样,地址会不一样).跟踪过程就不写了吧.大家都是高手,我的跟踪过程写出来,大家会笑话的.

在跟踪过程中,我犯了很多愚蠢的错误,甚至死了很多次.后来发现都是可以避免的.

008B5236前有一系列CALL,是进行计算的.我曾跟进去,但发现是可能一个DLL.该公司用一个DLL进行运

算,我是不能通过算法破解了,只好暴力破解.

写破解代码可能对大家有一些作用,我将详细介绍.

2.破解思路:

该程序是通过加壳的,壳比较奇怪,我孤陋寡闻,没有见过.

我的想法是,我也可以在程序中加外壳,先获得控制修改代码,在原来壳结束时,作跳转到我的修改代码.

原来程序入口是00426DF5,原来壳的结束位置是00426F33.

1)将程序的入口地址改为00400300

mov        ebx,426F33h

mov        dword ptr [ebx],0FD93C8E9h

add        ebx,4

mov        byte ptr [ebx],0FFh

jmp        00426DF5

//以上为将00426F33改为jmp 1111.

1111.为自己代码地址

push        ebx

mov        ebx,426F33h

mov        dword ptr [ebx],535BD0FFh

add        ebx,4

mov        byte ptr [ebx],81h

//以上为将00426F33改为

{

    00426F33 FF D0                call        eax

    00426F35 5B                  pop        ebx

    00426F36 53                  push        ebx

    00426F37 81 EB 2E 0D 00 00    sub        ebx,0D2Eh

}

mov        ebx,eax

add        ebx,0E10Ah

mov        dword ptr [ebx],7DEBC033h

//以上将程序改成鉴权成功

{

    008B5236 33 C0                xor        eax, eax

    008B5238 EB 7D                jmp        008B52B5

}

sub        ebx, 0B7h//ebx=008B517F

mov        word ptr [ebx],xxxx

//以上将程序改成98下跳到NT代码中执行

{

    008B517F jmp 008B51C5

}

pop        ebx

jmp        00426F33

外壳程序详细说明:

1)改变程序的入口地址到自己代码,在自己代码地方写跳转代码.该跳转代码将00426F33处程序改成jmp xxxx.

在该项操作中,需要取硬盘序列号,与jmp xxxx的机器码做xor运算.

取硬盘序列号使用LoadLibrary,GetProcAddress和GetVolumeInformationA.

其中LoadLibrary和GetProcAddress的函数地址需要查原来程序地址.

    LoadLibrary = 00426FD0

    GetProcAddress = 00426FCA

    CALL xxxx = E8 + 偏移(4位)

2)在上面的jmp xxxx的xxxx地方处写代码,改变程序的运行路径.

需要有如下几个具体操作:

(1)将00426F33处还原

(2)改程序为98下也到NT代码中执行

(3)该程序为鉴权成功

3)需要的固定数据:

'KERNEL32.DLL', 0 //13 BYTES,LoadLibraryA用

'GetVolumeInformationA', 0 //22 BYTES,GetProcAddress用

'C:\', 0 //4 BYTES, GetVolumeInformationA用

总共0x27 = 39个BYTE

因此数据从400300开始,代码从00400330开始.

外壳程序实现:

1)将几个固定数据写进文件中:Raw Address = 0x300

00400300    'KERNEL32.DLL', 0

0040030D    'GetVolumeInformationA', 0

00400323    'C:\', 0

00400327    4 BYTE 数据

0040032B    0

2)写跳转代码,将00426F33处程序改成jmp xxxx, Raw Address = 0x330

00400330   

00400330 55                  push        ebp

00400331 8B EC                mov        ebp,esp

00400333 83 EC 30            sub        esp,70h  ;实际使用0x22 BYTE

00400336 68 00 03 40 00      push        400300h  ;'KERNEL32.DLL'

0040033B E8 90 6C 02 00      call        426FD0h;LoadLibraryA

00400341 68 0D 03 40 00      push        40030Dh  ;'GetVolumeInformationA'

00400346 50                  push        eax      ;hModule

00400347 E8 7F 6C 02 00      call        426FCAh;GetProcAddress

0040034B 6A 0A                push        0Ah      ;sizeof(lpFileSystemNameBuffer)

0040034D 8D 5D D8            lea        ebx,[ebp-28h]

00400350 53                  push        ebx

00400351 8D 5D D0            lea        ebx,[ebp-30h]

00400354 53                  push        ebx

00400355 8D 5D E4            lea        ebx,[ebp-1Ch]

00400358 53                  push        ebx

00400359 8D 5D E8            lea        ebx,[ebp-18h]

0040035C 53                  push        ebx

0040035D 6A 0C                push        0Ch

0040035F 8D 5D F0            lea        ebx,[ebp-10h]

00400362 53                  push        ebx

00400363 68 23 03 40 00      push        400323

00400368 FF D0                call        eax

0040036A 8B 45 E8            mov        eax,dword ptr [ebp-18h];VolumeSerialNumber

0040036D BB 27 03 40 00      mov        ebx,400327h

00400372 33 03                xor        eax,dword ptr [ebx]

00400374 BB 33 6F 42 00      mov        ebx,426F33h

00400379 89 03                mov        dword ptr [ebx],eax

0040037B 83 C3 04            add        ebx,4

0040037E C6 03 FF            mov        byte ptr [ebx],0FFh;原来是E9 54 94 FD FF jmp 0040038D

00400381 83 C4 70            add        esp,70h

00400384 8B E5                mov        esp,ebp

00400386 5D                  pop        ebp

00400387 E9 69 6A 02 00      jmp        00426DF5;跳转代码完成

0040038C

0040038C 53                  push        ebx

0040038D BB 33 6F 42 00      mov        ebx,426F33h

00400392 C7 03 FF D0 5B 53    mov        dword ptr [ebx],535BD0FFh

00400398 83 C3 04            add        ebx,4

0040039B C6 03 81            mov        byte ptr [ebx],81h

0040039E 8B D8                mov        ebx,eax

004003A0 81 C3 0A E1 00 00    add        ebx,0E10Ah

004003A6 C7 03 33 C0 EB 7D    mov        dword ptr [ebx],7DEBC033h

004003AC 81 EB B7 00 00 00    sub        ebx,0B7h

004003B2 66 C7 03 EB 44      mov        word ptr [ebx],44EBh

004003B7 5B                  pop        ebx

004003B8 E9 76 6B 02 00      jmp        00426F33

004003BD

实验数据:

VolumeSerialNumber = 0x283a1709

E9 54 94 FD ^ VolumeSerialNumber = 0xd5ae43e0

其中的GetVolumeInformationA和变化数据,不是必须的.在写这一段代码时,不能将他放到原来的代码块中,

我曾经放过,但程序运行死了.可能有其他检查,但程序死的时候,堆栈已经被破坏了,我无法定位,不知哪位

能指点?

3.C代码

#include <windows.h>

#include <shlobj.h>

#include "resource.h"

#define OPEN_ERROR          -1

#define READ_ERROR          -2

#define WRITE_ERROR        -3

#define FILE_ERROR          -4

#define NO_KEY              -5

int WriteCrack(HANDLE hFile)

{

    DWORD dwWrited;

//1.写入口

    SetFilePointer(hFile, 0xf0, 0, FILE_BEGIN);

    DWORD dwEntry = 0x330;

    WriteFile(hFile, &dwEntry, 4, &dwWrited, NULL);

//2.写固定数据

    LPTSTR tt = MAKEINTRESOURCE(IDR_CRACKDATA1);

    HRSRC hRsrc = FindResource(GetModuleHandle(NULL),

        MAKEINTRESOURCE(IDR_CRACKDATA1), "CRACKDATA");

    HGLOBAL hGlobal = LoadResource(GetModuleHandle(NULL), hRsrc);

    LPVOID lpData = LockResource(hGlobal);

    SetFilePointer(hFile, 0x300, 0, FILE_BEGIN);

    WriteFile(hFile, lpData, 0xc0, &dwWrited, NULL);

//3.写变化数据

    DWORD dwChangeData = 0xfd9454e9;//E9 54 94 FD

    BYTE lpRootPathName[4] = "c:\\"; //取C盘的序列号

    BYTE lpVolumeNameBuffer[12];//磁盘卷标

    DWORD nVolumeNameSize = 12;

    DWORD VolumeSerialNumber;//磁盘序列号

    DWORD MaximumComponentLength;

    BYTE lpFileSystemNameBuffer[10];

    DWORD nFileSystemNameSize=10;

    DWORD FileSystemFlags;

    GetVolumeInformation((char*)&lpRootPathName[0],

        (char*)&lpVolumeNameBuffer[0], nVolumeNameSize,

        &VolumeSerialNumber, &MaximumComponentLength,

        &FileSystemFlags,

        (char*)&lpFileSystemNameBuffer[0], nFileSystemNameSize);

    dwChangeData ^= VolumeSerialNumber;

    SetFilePointer(hFile, 0x327, 0, FILE_BEGIN);

    WriteFile(hFile, &dwChangeData, 4, &dwWrited, NULL);

    return 1;

}

int WriteCrackData(char* szFileName)

{

    HANDLE hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,

        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    if(hFile == INVALID_HANDLE_VALUE)

    {

        MessageBox(NULL, "Please quit TornadoII program!\r\n"

            "Ensure not any program lock TornadoII resource!", "Warnning", MB_OK | MB_ICONHAND);

        return OPEN_ERROR;

    }

//读数据,判断该文件是否可写

    SetFilePointer(hFile, 0xf0, 0, FILE_BEGIN);

    DWORD dwEntry;

    DWORD dwReaded;

    if(ReadFile(hFile, &dwEntry, 4, &dwReaded, NULL) == FALSE)

    {

        MessageBox(NULL, "Please quit TornadoII program!\r\n"

            "Ensure not any program lock TornadoII resource!", "Warnning", MB_OK | MB_ICONHAND);

        CloseHandle(hFile);

        return READ_ERROR;

    }

    if(dwEntry != 0x330)//自己写的入口

    {

        if(dwEntry != 0x26df5)//原本的程序入口

        {

            if(MessageBox(NULL, "TornadoII maybe infected by virus!\r\nRun the patch maybe destroy TornadoII!\r\n"

                "If you want continue,press OK,CANCEL to quit!\r\nDo you want continue?", "Warnning", MB_OKCANCEL | MB_ICONHAND)

                == IDCANCEL)

                CloseHandle(hFile);

                return FILE_ERROR;

        }

    }

    WriteCrack(hFile);

    CloseHandle(hFile);

    return TRUE;

}

int WriteBack()

{

    HKEY hKey;

    if(RegOpenKey(HKEY_CURRENT_USER, "TNT TornadoII Patch1", &hKey)

        != ERROR_SUCCESS)

        return NO_KEY;

    char szFileName[255];

    memset(szFileName, 0, sizeof(char) * 255);

    long length = 255;

    DWORD FileAttribute = 0;

    BYTE FileTime[255];

    memset(FileTime, 0, sizeof(BYTE) * 255);

    DWORD dwLength;

    if(RegQueryValue(hKey, "Path", szFileName, &length)

        != ERROR_SUCCESS)

    {

        RegCloseKey(hKey);

        return NO_KEY;

    }

    dwLength = 4;

    DWORD type;

    if(RegQueryValueEx(hKey, "Attribute", 0, &type, (BYTE*)&FileAttribute, &dwLength)

        != ERROR_SUCCESS)

    {

        RegCloseKey(hKey);

        return NO_KEY;

    }

    dwLength = 255;

    if(RegQueryValueEx(hKey, "Time", 0, &type, FileTime, &dwLength)

        != ERROR_SUCCESS)

    {

        RegCloseKey(hKey);

        return NO_KEY;

    }

    FILETIME* temp = (FILETIME*)FileTime;

    FILETIME CreateTime;

    CreateTime = *temp;

    temp ++;

    FILETIME LastAccessTime;

    LastAccessTime = *temp;

    temp ++;

    FILETIME LastWriteTime;

    LastWriteTime = *temp;

    HANDLE hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,

        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    if(hFile == INVALID_HANDLE_VALUE)

    {

        MessageBox(NULL, "Please quit TornadoII program!\r\n"

            "Ensure not any program lock TornadoII resource!", "Warnning", MB_OK | MB_ICONHAND);

        return OPEN_ERROR;

    }

//读数据,判断该文件是否可写

    SetFilePointer(hFile, 0xf0, 0, FILE_BEGIN);

    DWORD dwEntry;

    DWORD dwReaded;

    if(ReadFile(hFile, &dwEntry, 4, &dwReaded, NULL) == FALSE)

    {

        MessageBox(NULL, "Please quit TornadoII program!\r\n"

            "Ensure not any program lock TornadoII resource!", "Warnning", MB_OK | MB_ICONHAND);

        return READ_ERROR;

    }

    if(dwEntry != 0x330)//自己写的入口

    {

        CloseHandle(hFile);

        return FILE_ERROR;

    }

    DWORD dwWrited;

//1.写入口

    SetFilePointer(hFile, 0xf0, 0, FILE_BEGIN);

    dwEntry = 0x26df5;

    WriteFile(hFile, &dwEntry, 4, &dwWrited, NULL);

//2.数据

    BYTE buffer[0xc0];

    memset(buffer, 0, sizeof(BYTE) * 0xc0);

    SetFilePointer(hFile, 0x300, 0, FILE_BEGIN);

    WriteFile(hFile, buffer, 0xc0, &dwWrited, NULL);

   

    SetFileTime(hFile, &CreateTime, &LastAccessTime, &LastWriteTime);

    CloseHandle(hFile);

    RegDeleteKey(hKey, "Path");

    RegCloseKey(hKey);

    RegDeleteKey(HKEY_CURRENT_USER, "TNT TornadoII Patch1");

    SetFileAttributes(szFileName, FileAttribute);

   

    return TRUE;

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nShowCmd)

{

    if(WriteBack() == TRUE)

        return TRUE;

    BROWSEINFO  bi;

    ITEMIDLIST* pidl;

    char        path[255];

    memset(path, 0, sizeof(char) * 255);

    bi.hwndOwner = NULL;

    bi.pidlRoot = NULL;

    bi.pszDisplayName = NULL;

    bi.lpszTitle = "Please choose the path of TornadoII installed";

    bi.ulFlags = BIF_BROWSEINCLUDEFILES;

    bi.lpfn = NULL;

    bi.lParam = 0;

    bi.iImage = 0;

    pidl = SHBrowseForFolder(&bi);

    SHGetPathFromIDList(pidl, path);

    char        szFileName[255];

    int        length = strlen(path);

    if(length == 0)

        return FALSE;

    int        temp;

    char*      szName = "\\host\\x86-win32\\bin\\tgtsvr.exe";

    memset(szFileName, 0, sizeof(szFileName));

    memcpy(szFileName, path, length);

    temp = length;

    length = strlen(szName);

    memcpy(&szFileName[temp], szName, length);

    HANDLE hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,

        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    if(hFile == INVALID_HANDLE_VALUE)

    {

        MessageBox(NULL, "Please quit TornadoII program!\r\n"

            "Ensure not any program lock TornadoII resource!", "Warnning", MB_OK | MB_ICONHAND);

        return FALSE;

    }

    BY_HANDLE_FILE_INFORMATION FileInfo;

    GetFileInformationByHandle(hFile, &FileInfo);

    CloseHandle(hFile);

    DWORD FileAttribute = FileInfo.dwFileAttributes;

    BYTE FileTime[255];

    memset(FileTime, 0, sizeof(BYTE) * 255);

    length = 0;

    memcpy(&FileTime[length], &FileInfo.ftCreationTime, sizeof(FILETIME));

    length += sizeof(FILETIME);

    memcpy(&FileTime[length], &FileInfo.ftLastAccessTime, sizeof(FILETIME));

    length += sizeof(FILETIME);

    memcpy(&FileTime[length], &FileInfo.ftLastWriteTime, sizeof(FILETIME));

    length += sizeof(FILETIME);

    DWORD newAttribute = FileAttribute & 0xfffffffe;

    SetFileAttributes(szFileName, newAttribute);

    if(WriteCrackData(szFileName) == TRUE)

    {

        HKEY hKey;

        RegCreateKey(HKEY_CURRENT_USER, "TNT TornadoII Patch1", &hKey);

        RegSetValue(hKey, "Path",

            REG_SZ, szFileName, strlen(szFileName));

        RegSetValueEx(hKey, "Attribute", 0, REG_DWORD, (BYTE*)&FileAttribute, 4);

        RegSetValueEx(hKey, "Time", 0, REG_BINARY, FileTime, length);

        if(MessageBox(NULL, "TornadoII Patch1 is OK!\r\nYou can run me again when registered,\r\n"

            "or press yes when you registed.\r\nHave you run TornadoII to register?", "OK!", MB_YESNO) == IDYES)

        {

            WriteBack();

        }

    }

    return TRUE;

}

其中的IDR_CRACKDATA1为:

00000000 4B 45 52 4E 45 4C 33 32 2E 44 4C 4C 00 47 65 74    //KERNEL32.DLL Ge

00000010 56 6F 6C 75 6D 65 49 6E 66 6F 72 6D 61 74 69 6F    //VolumeInformati

00000020 6E 41 00 43 3A 5C 00 00 00 00 00 00 00 00 00 00    //nA C:\

00000030 55 8B EC 83 EC 30 68 00 03 40 00 E8 90 6C 02 00

00000040 68 0D 03 40 00 50 E8 7F 6C 02 00 6A 0A 8D 5D D8

00000050 53 8D 5D D0 53 8D 5D E4 53 8D 5D E8 53 6A 0C 8D

00000060 5D F0 53 68 23 03 40 00 FF D0 8B 45 E8 BB 27 03

00000070 40 00 33 03 BB 33 6F 42 00 89 03 83 C3 04 C6 03

00000080 FF 83 C4 70 8B E5 5D E9 69 6A 02 00 53 BB 33 6F

00000090 42 00 C7 03 FF D0 5B 53 83 C3 04 C6 03 81 8B D8

000000a0 81 C3 0A E1 00 00 C7 03 33 C0 EB 7D 81 EB B7 00

000000b0 00 00 66 C7 03 EB 44 5B E9 76 6B 02 00 00 00 00

后记:

今年7月底破解该软件,原来想买给xx公司.不过后来失败了.这也是加GeVolumeInformatinA的原因.

前两天看到贵论坛上一篇文章,深有感触.破解应该是一个业余爱好吧,

希望能和大家交个朋友.

运行该Patch程序注意:

1.保证您已经安装好TornadoII,且TornadoII的应用程序没有运行.

2.运行程序patch.

3.选择TornadoII的安装路径.

4.将出现如图patch1OK.jpg所示,此时patch1已经成功,这时

  patch.exe可以按否关闭,或者不关闭,直接运行TornadoII进行注

  册.

  注意:现在一定不能马上按"是"按钮.如果您按下,那么只好从第

  二步重新来.

5.注册TornadoII将出现如register.jpg所示,此时您可以输入

  任意的26个数字或字母,可以数字和字母混合.注册成功后,将

  TornadoII的应用程序退出.

6.如果刚才您没有关闭patch.exe,现在直接按patch1OK.jpg所示的

  "是"按钮,TornadoII将完全破解.如果您刚才将patch.exe推出了,

  现在需要重新运行他.这一步成功的标志是patch2OK.jpg所示.

注意:如果您的操作系统是98/95,在第5步时将出现如98.jpg所示(98.jpg不能贴上来,见谅),

    此时实际已经注册成功.您需要关闭TornadoII的注册程序,按照

    第六步的指示做.如果您的操作系统是98/95,而且已经过期了,该

     Patch无能为力.只好重装系统和TII了.:(

哈哈,这个昂贵的商业软件的保护说穿了实在是不值得一提!

它是用Crypkey加壳的(www.crypkey.com),而Crypkey Instant的通用注册机早被Duelist/CORE写出来了,在Keygen Studio上可以得到,用的RSA算法。

至于脱壳,更是简单得不得了,写个ProcDump的s cript自动把tgtsvr.exe脱壳即可(壳调用cryp*.dll判断时间),得到的exe的import table未做任何手脚,可以在各种版本的32-bit windows上运行!

所有用Crypkey加壳的大软件如法炮制!

  评论这张
 
阅读(499)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017