吾爱破解网站

2019-05-25 11:35:31 -0400
吾爱破解论坛

【原创】music studio pc版由爆破、追码、到注册机的编写

吾爱pojie 吾爱破解论坛 前天

作者论坛账号:涛之雨


一、免责声明

包含且不限于本文、截图、分析,版权均归本人所有,如需转载,请与本人联系(看雪|吾爱ID相同),软件版权归软件官方所有,如有侵权,请联系管理或本人删帖。
仅供学术交流研究使用,不得用于非法、商业用途!!
请支持正版,购买正版以获得新版更新及更好地服务。

二、软件相关信息

软件名:sofeh music studio 4551
软件官网:http://www.sofeh.net/engl/?page_id=15
软件类型:win
软件大小:74.7MB
下载地址:http://dl.sofeh.net/download/soft-musicstudio4551.7z
注册方式:请求码(机器码生成),本地注册
分析方式:动态
使用软件:吾爱专版 OD(OllyDbg)(下载见爱盘)
分析人员:涛之雨
分析环境:WinXp
鸣谢:感谢 @KaQqi大佬抽出宝贵时间进行指导。

安卓APP版本
请移步本人的另一篇文章
Google Play的一款专业电子琴。ORG 2020 汉化 && 破解版
https://www.52pojie.cn/thread-947671-1-1.html
(出处:吾爱破解论坛)

三、查壳

额。。我先说一下吧。。有能力的朋友也可以试验一下脱壳。。。

KaQqi大佬说,这个软件是:新版enigma的壳。。。我还搞不定。。

查壳完毕,继续。

四、分析软件注册流程

不管破解什么,如何破解,都是至少要对软件注册的流程十分熟悉,
如果不了解流程就去尝试破解,有可能会误入歧途,然后最终导致放弃。
流程如图1所示:

Help-Activate the Professional freatures-输入注册码-判断是否成功-错误代码


(图1)

五、I D A载入

因为是加密压缩壳,所以没有分析出什么有效信息,故不附图了,该做的流程还是要有的,以防万一有什么发现。

六、OD载入

因为没有检测调试器,可以直接拖入OD调试,或是附加调试。

这里推荐附加的方法,因为是虚拟壳,直接载入有时有可能会出问题。这里我们附加到调试器。  

如图2所示:右上角文件-附加-选择【music studio】进程-确定。  


(图2)

因为是附加调试会暂停在系统领空,先按图4所示:

运行程序F9)让程序跑起来,
E(快捷键:Alt+E【Modules】,)显示模块列表
双击Music Studio.exe软件主模块,


(图3)

(一)、找关键跳转

1、查看代码

进入软件,发现软件内机器码全部都是00(图4中所示)应该是虚拟化后释放了


(图4)

2、搜索字符串

回到软件的内存里,如图5所示:右键-转到-表达式(快捷键:Ctrl+G)【Goto】-输入00401000


(图5)

(注:winxp软件的基址一般都是401000,如果是win7及以上版本的系统则不一定。需要自行点M(快捷键:Alt+M)[memory]查看内存,获取基址。详细教程可以看论坛的教程或是到搜索引擎进行搜索)

如图6所示,进行右键-中文搜索引擎-智能搜索的操作。


(图6)

根据四、分析软件注册流程的结果,需要找到弹窗的call

由弹窗的信息,可以尝试搜索关键词Erroractivationcodewrong等以定位弹窗的call,从而向上查找关键跳转。

注:搜索关键词的时候可以稍微减少一点,以防关键词被拆分。

如图7所示,本人搜索的就是activation,有且仅有一处。上下字符串的内容也是符合该处其他内容的,因此可以初步判断,该处即为弹窗的内容。


(图7)

(二)、尝试爆破

双击改行(或是选中该行后按Enter键),查看该处代码。

1、分析、猜测

如图8


(图8)

该段代码比较长,因此可以猜测此处上方有判断语句,

向下观察,发现有一处jmp指令,再次猜测上方有个跳转,可以实现跳过该段错误提示的弹窗。

向上观察,发现有一处jnz指令,鼠标点击改行指令,根据左侧的引导线箭头可知,恰好跳过了错误弹窗的一段内容。

猜测该处为关键跳转。

2、验证猜想

经过分析,猜测如图12中005D81C2处为判断是否注册成功的关键跳转。

如图9所示:选中改行-右键-断点-切换(快捷键:F2)在该处下一个断点


(图9)

如图10所示,再次重复注册操作,可以看到再点击Activate后,软件断在了下断点改行,并且左上角显示暂停字样。


(图10)

断点行左侧引导线为灰色,证明跳转不成立,双击右侧寄存器窗口的控制符Z以使该跳转成立。

更改后,效果如图11,引导线变为红色,即跳转成立。点击如图15所示左上角运行按钮(快捷键:F9)。


(图11)

运行后发现成功!

结果如图12所示。


(图12)

再次运行该软件,发现存在如图13所示的问题:

软件依旧为试用版,未解锁专业版
软件注册按钮没有消失(官网说注册成功后Activate按钮会消失)


(图13)

因此破解到此尚未成功。

(三)、尝试追码

1、定位关键call

回到刚才下断点的地址,

注:如果没有找到可以

1:按上文【误解】的内容跳转到指定地址。)
2:点击菜单下侧B按钮(快捷键:Alt+B)【Break】

向上查看关键比较代码

如图14,关键跳转上方的三个call都很可疑,均需要分析。


(图14)

3、单步步过,猜测call的作用

如图15,一路按F8单步步过(图中右侧绿色箭头所示按钮;白色箭头所示为:单步步入),不跟入call内部,先猜测每个call的作用,然后重点分析怀疑对象,以提高效率和成功率。


(图15)

跟到如图16所示的地方,刚刚经过一个call,通过分析、查看下侧信息窗口、右侧寄存器窗口堆栈窗口返回的数值,可以猜测005D81A6call是得到假码的call,继续分析下面两个call可以猜测出下面第二个call 判断注册是否成功,而根据返回的al标志符的值,判断是否注册成功。


(图16)

4、跟进关键call

因此需要着重跟进该处call进行分析

如图17所示,在该处call下断点,重复注册操作,进程在该处断下,按F7单步跟入,追踪真码。


(图17)

如图18所示,发现在上下移动代码行后,EIP所在行出现了错误。
此处因为本人理解出错,感谢H大纠正。
这是编译器编译出的数据,od可以按ctrl+A分析

(图18)

或是像本人一样手动改为00或90

分析完,代码如图19所示,因为篇幅原因,下面的两个call已经分析过了,依然是单步步过下几行。


(图19)

分析如下图20。至此,真码已经出炉了。在寄存器的EAXEDX中,已经把真码告诉我们了。。。


(图20)

5、测试追出的真码

如图28所示,虽然已经确认了是真的注册码,但测试一下还是要令人愉悦的23333。
至此可以利用论坛的其他教程写出内存注册机了。(善用论坛搜索功能)


(图21)

(四)、注册码算法分析

1、取消已有的注册码授权

要分析算法,首先要取消刚刚注册码,方法如下,任选其一即可:

1) 再次打开注册窗口,改动注册码,按回车键;
2) 如图22所示,在软件根目录下,注册成功后会新生成一个Activation注册文件,以文本方式打开该文件,即可发现请求码和注册码。删掉该文件即可。

注:软件需要重新打开才会生效


(图22)

2、跟进关键call

之前追码追到的算法关键call地址,如图23所示,我的电脑是004DFE68,观察下面的代码,发现OD识别出了字符-,结合上面的je跳转判断,再联系到注册码的结构,应该是在此处进行连接的,但是前面没有4个call,因此可能是循环。


(图23)

依然是单步步过每一个call,分析、猜测每一个call可能的含义。如图31所示,第一此到达该je的时候为跳转状态(没有连接符-),注意到后面的jnz前的判断代码:

inc esi
cmp esi,0x4

即:如果esi不大于4则跳转到上面(循环)。


(图24)

单步步过下面四个call以猜测每个call的含义。

本段详细含义见图25。


(图25)

到此厘清了软件注册码生成结构和流程:

判断是否需要加上"-"
连接字符串
生成四位数(整数)
转换为字符串
如果不满四位,转到1
        生成了四段,则退出循环

接下来就是一个找到如图25中004DFEADcall对应的生成算法了。

3、跟进生成四位数的call

如图26所示,单步步入该函数,依旧是花指令,去之!去后效果如图27所示。


(图26)


(图27)

如图28,单步步过到第一个call处,寄存器eax出现请求码,是传入该call的参数。


(图28)

如图29,再次步过call下一行eax变为00000047(H),即71(D),联系传入的注册码,发现是注册码的位数(注:每台计算机的请求码位数不统一)。


(图29)

继续分析代码。分析的截图如图30、图31所示。点击可查看大图


(图30)


(图31)

七、注册机的实现

易语言实现

咳咳大佬误笑。。

完整代码就不贴了,以防被大佬笑话。。。上图吧。

全工程代码:见图32、图33。


(图32)


(图33)

实验结果:如图34所示,算法无误,成功!


(图34)

C语言实现

咳咳qt,mfc都不懂。。。刚开始学习。。
那就用控制台打印一个界面吧。。

C语言精简版

第一版注册机。。。要手动输入请求码,生成的注册码也不方便取出。

代码的截图及运行截图如图35、图36所示:


(图35)


(图36)

#include <stdio.h>
#include <windows.h>
#include <string.h>

int getSignCode ( long myCode )
{
    int mySignedCode[4]= {27,16,47,34},i=0,retSignCode[4];

    for ( ; i<4; i++ )
    {
        long a,b;
        a = myCode;

        while ( 1 )
        {
            b = a * 16 / mySignedCode[i];

            if ( b <= 9999 )
                break;
            a = a /2;
        }
        retSignCode[i]=b;
        printf ( "%ld",b);
        if(i!=3)    printf("-");
    }

    return *retSignCode;
}
int main()
{
    char code[90];
    long codeSum=0;
    int i;
    printf ( "请输入您的请求码!\n" );
    scanf ( "%s",code );
    //strcpy ( code,"459111219222217181919201718181927282329343637-121525877-7161211-8126676" );//我的注册码
    printf ( "\n" );
    for ( i=0; i<strlen ( code )+1; i++ )
        codeSum+=code[i]* ( i+1 );
    printf ( "\n请求码算出的校验值为%ld\n\n",codeSum );
    getSignCode ( codeSum );
    return 0;
}

c语言 (相对)完整版

在上一段代码的基础上加上了读取剪贴板、写入剪贴板的功能,
添加上了吾爱的免责声明。
源代码附在下面,需要的可以自行修改、编译

代码的截图及运行截图如图37、图38所示:


(图37)


(图38)

#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include<ctype.h> //需要使用到判断字符的函数

void echo52PJ()
{
    printf ( "#########################################################\n" );
    printf ( "版权声明:不得用于非法及盈利用途\n" );
    printf ( "请支持正版!到官网购买正品以获取最新版和更好地服务\n" );
    printf ( "POWER BY 涛之雨\n" );
    printf ( "吾爱破解独发!\n" );
    printf ( "未经被人允许禁止转载!\n" );
    printf ( "#########################################################\n" );
    printf ( "\n\n" );
    printf ( "免责声明:\n" );
    printf ( "吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。\n\n\n" );
    return;
}
int * getSignCode ( long myCode )
{
    int mySignedCode[4]= {27,16,47,34},i=0;
    static int retSignCode[4];

    for ( ; i<4; i++ )
    {
        long a,b;
        a = myCode;

        while ( 1 )
        {
            b = a * 16 / mySignedCode[i];

            if ( b <= 9999 )
                break;

            a = a /2;
        }

        retSignCode[i]=b;
        //printf ( "%ld", b );
        //if(i!=3)    printf("-");
    }

    return retSignCode;
}

BOOL setClipCode ( char* setStr )
{
    HGLOBAL hclip;//剪切板句柄

    if ( OpenClipboard ( NULL ) ==0 )
    {
        printf ( "打开剪切板失败!\n" );
        return FALSE;
    }

    if ( !EmptyClipboard( ) )
    {
        printf ( "清空剪切板失败!\n" );
        CloseClipboard();
        return FALSE;
    }

    TCHAR *strToSet=setStr;
    hclip = GlobalAlloc ( GMEM_MOVEABLE, ( ( strlen ( strToSet )+1 ) *sizeof ( TCHAR ) ) );

    if ( !hclip )
    {
        printf ( "内存分配失败!\n" );
        CloseClipboard();
        return FALSE;
    }

    LPSTR lpstr= ( LPSTR ) GlobalLock ( hclip ); //加锁,返回一个VOID类型的指针
    memcpy ( lpstr,strToSet, ( ( strlen ( strToSet ) ) *sizeof ( TCHAR ) ) );
    //lpstr[strlen ( strToSet )]= ( TCHAR ) 0; //字符串结尾的'\0'
    GlobalUnlock ( hclip ); //解锁
    SetClipboardData ( CF_TEXT,lpstr );
    CloseClipboard();
    printf("注册码已成功复制到剪贴板");
    return TRUE;
}
char * getClipCode()
{
    //局部变量
    static char *pbuf=NULL;
    HANDLE hclip;//剪切板句柄

    //打开剪切板,获取里面的数据
    if ( OpenClipboard ( NULL ) ==0 )
    {
        printf ( "打开剪切板失败!\n" );
        return "ERR";
    }

    //剪切板当中的数据是不是文本类型的
    if ( !IsClipboardFormatAvailable ( CF_TEXT ) )
    {
        printf ( "剪切板当中的数据类型非文本!\n自动跳过。" );
        CloseClipboard();//关闭剪切板,不然其他程序无法正常0使用剪切板
        return "ERR";
    }

    //获取剪切板里面的数据
    hclip=GetClipboardData ( CF_TEXT );
    pbuf= ( char * ) GlobalLock ( hclip ); //加锁,返回一个VOID类型的指针
    GlobalUnlock ( hclip ); //解锁

    //清除前导的非字母和数字字符
    while ( *pbuf&&!isalnum ( *pbuf ) )
        ++pbuf;

    //测试剪切板是否能使用
    printf ( "   检测到剪贴板内的文本如下:\n   =======================================================================\n   %s\n   =======================================================================\n   是否使用该数据作为请求码?\n\nY/N\n",pbuf );
    CloseClipboard();//关闭剪切板,不然其他程序无法正常0使用剪切板
    Sleep(1000);
    char Kword=getchar();

    if ( Kword!='y'&&Kword !='Y' ) return "ERR";

    return pbuf;
}
int main ( void )
{
    system ( "color 1f" );
    system ( "mode con:cols=80 lines=20" );
    system ( "title 请支持正版!到官网购买正品以获取最新版和更好地服务  POWER BY 吾爱破解 涛之雨" );
    echo52PJ();
    printf ( "按下回车键开始,并且表示接受以上条款!!" );
    getchar();
    system ( "cls" );
    long codeSum=0;
    int i;
    char code[90];
    strcpy ( code,getClipCode() );

    if ( !strcmp ( code,"ERR" ) )
    {
        printf ( "   请手动输入请求码,形如\n   =======================================================================\n   459111219222217181919201718181927282329343637-121525877-7161211-8126676\n   =======================================================================\n   按回车继续\n" );
        scanf ( "%s",code );
    }

    system ( "cls" );

    printf ( "   获取到的请求码如下:\n   =======================================================================\n   %s\n   =======================================================================\n",code );
    //strcpy ( code,"459111219222217181919201718181927282329343637-121525877-7161211-8126676" );
    printf ( "\n" );

    for ( i=0; i<strlen ( code )+1; i++ )
    {
        codeSum+=code[i] * ( i+1 );
    }

    printf ( "\n请求码算出的校验值为%ld\n",codeSum );
    int *regCode=getSignCode ( codeSum );
    printf ( "\n\n计算出的注册码为:\n\n" );

    for ( i=0; i<4; i++ )
    {

        sprintf ( code+i*5,"%d", regCode[i] );

        if ( i!=3 ) strcat ( code-1,"-");
    }

    printf ( "%s", code );
    printf ( "是否将该注册码复制到剪贴板?\n\nY/N\n" );
    char Kwd;
    scanf("%c",&Kwd);
    Kwd=getchar();
    //scanf("%c",&Kword);
    if ( Kwd=='y'||Kwd=='Y' )
        {
            setClipCode ( code );
        }

    printf ( "\n\n任意键键退出\n\n                            POWER By 涛之雨" );
    system ( "pause>nul" );
    return 0;
}

VC的QT界面版

请移步KaQqi大佬的

【原创破解】music studio算法注册机
https://www.52pojie.cn/thread-953570-1-1.html
(出处:吾爱破解论坛)

bat(cmd|dos)版

bat没有获取ASCII的方法,所以很蛋疼的写了个call,不是很聪明的办法。
使用起来其实比上面两个都简单:
复制该段代码,新建一个文本,粘贴代码,保存,后缀改为.bat|.cmd双击即可使用。。。
界面就没做,懒得。。。

注:因为论坛的网页编码是UTF-8,因此直接复制到文本也是UTF-8的。请注意转码。。

@echo off
setlocal enableextensions enabledelayedexpansion
title 请支持正版!到官网购买正品以获取最新版和更好地服务  POWER BY 吾爱破解 涛之雨
color 1f
mode con:cols=80 lines=20
cls
set z=0
set /p w=请输入请求码,以回车键结束:
echo 加载中。。。。
        set q=1
:nexti
        if not "%w%"=="" (
                set w_%q%=%w:~0,1%
                call :v !w_%q%!
                set x=!errorlevel!
                set "x=!x!*%q%"
                set /a "z=!x!+!z!"
                set "w=%w:~1%"
                set /a q+=1
        goto :nexti)
echo 请稍后。。
set str=-
for /l %%i in (1,1,4) do (
        call :s !z! %%i
        set x=!errorlevel!
        set m=!m!!x!
        if %%i neq 4   set m=!m!%str%)
echo 请求码算出的校验值为:!m!
ping 127.0.0.1 > nul
echo 任意键退出
pause>nul
exist
:v
        if %1==9 exit /b 57
        if %1==8 exit /b 56
        if %1==7 exit /b 55
        if %1==6 exit /b 54
        if %1==5 exit /b 53
        if %1==4 exit /b 52
        if %1==3 exit /b 51
        if %1==2 exit /b 50
        if %1==1 exit /b 49
        if %1==0 exit /b 48
        if %1==- exit /b 45
exit /b 0
:s
    if %2==1 set l= 27
    if %2==2 set l= 16
    if %2==3 set l= 47
    if %2==4 set l= 34
        set /a tempcode = %1
        set b = 0
        :whilestart
        set /a b = !tempcode!  * 16 / l
        if !b! leq 9999 exit /b !b!
        set /a tempcode = !tempcode! /2
        goto whilestart

效果图见图39。


(图39)

结束语

小计:

本文较完整的记录了本人由爆破,到追码,再到编写注册机的全过程
全过程,是因为本文写的十分详细,就是为了想和那些想写注册机,又没有多少基础的小白们一起学习,共同进步,
较完整,是因为其实写出来的是想做为教程,而不是完整的再现我是如何一步步走错而又从头开始分析的,
我需要告诉大家的是正确的(或者是比较正确)过程,而不是和大家分享我是如何走错的,
这个软件我破解的时候大概用了三四种方法找到这个关键的call,
但是其他的或多或少都会有一些繁琐或是错误之处,最后,在写教程的时候,我才发现之前走错的路是多么奇葩,
经过这次教程,我本身也学到很多,为什么前面几大块没有什么内容,我依然要打出来?不是为了字数,而是思路。。。

之前破解的时候,因为搜索了过多的(还是打错了)关键词,没有搜索到关键的字符串,即-(一)-2的步骤,
所以我是通过了弹窗回溯的方法、还有按钮事件的方法

注:有兴趣的朋友也可以自己试验一下,就会发现这么走是多么的困难。
另外,本软件是MFC写的,但是貌似是把MFC内置了?
万能断点是能用的,不过要在程序领空才能找到,一开始走了很多的弯路,正文没有体现出来,就在最后稍微吐个槽吧23333~

最后,祝大家都能在吾爱破解学有所成,
伸手、模仿的进步是微弱甚至没有的,需要自行钻研,不会就去查资料。
有疑惑就去提问
(最后再次感谢KaQqi 大佬和H大)

全文终

全文终!撒花~~~~

--官方论坛

www.52pojie.cn


--推荐给朋友

公众微信号:吾爱破解论坛

或搜微信号:pojie_52

文章已于2019-05-21修改
    阅读原文
    已同步到看一看

    发送中

    微信扫一扫
    关注该公众号

    «Newer      Older»

    Back to home

    Subscribe | Register | Login | N