沈阳电脑维修网,沈阳上门维修电脑服务
当前位置: 主页 > 程序数据代码>SRS Audio Sandbox破解纪实 >

SRS Audio Sandbox破解纪实

时间:2017-5-23来源:www.sypcwx.cn 作者: 沈阳电脑维修网点击:
沈阳电脑维修,上门维修电脑
  沈阳电脑维修上门服务13889116605:   最近挺忙的,本来需要各种为前路做准备,无奈自己天生属于低血压型的人,偏偏就是提不起劲儿来干正事儿,却把大好的一天光阴全交代到SRS的分析工作上了。虽然说这多少算不务正业,不过由于本人有...   最近挺忙的,本来需要各种为前路做准备,无奈自己天生属于低血压型的人,偏偏就是提不起劲儿来干正事儿,却把大好的一天光阴全交代到SRS的分析工作上了。虽然说这多少算不务正业,不过由于本人有着严重的软件新版本强迫症,故这算是给自己的一个开脱理由吧。   这款软件的破解工作展开比较容易,没有加壳,直接上工具分析之。首先请出OllyDBG来,通过查找字符串引用和查找APIMessageBox引用的老法子,很容易就定位了大概的关键代码位置。   找到关键位置后,顺手又记录了一下函数调用栈,然后打开了神器IDA。用IDA载入后,跳转到之前找到的关键代码RVA处,着手分析。说起来,我自己喜欢将动态和静态调试方法结合起来用,不如果不愿意太费神分析汇编代码,有时候直接看运行时结果便是最直观和省时的。载入后发觉之前判断的关键点实际上是CWinApp::ShowAppMessageBox函数,继续沿着刚才记录的函数运行时调用栈往上找,依次顺藤摸瓜:AfxMessageBox--->Sub44D240,这才到了SRS程序的代码领空,于是正是着手分析。(IDA这个静态分析功能实在是强大,它可以根据二进制代码特征判断出其是否是库函数代码。这大大节省了我的时间,应为对这类代码我只需要看SDK文档就行了,而不需要去分析其实际的代码行为)   进一步根据线索判断(Sub44D240里包含了SendMessage、AfxMessageBox、GetWindowText等函数,足以说明该函数的关键作用),我锁定在了Sub44D240函数的Sub4430F0调用上,继续追踪到Sub442FF0上,继而是Sub44B9E0过程,最终到了Sub44BC30过程上。在该过程中,我同时追踪到了用户输入的ProductID以及SerialNumber等信息,这进一步是我确认了我的判断。   该过程具体代码如下: .text:0044BC30 .text:0044BC30;===============SUBROUTINE======================================= .text:0044BC30 .text:0044BC30;Attributes:bp-basedframe .text:0044BC30 .text:0044BC30check_PID_SNprocnear;CODEXREF:realCheckSN+182p .text:0044BC30 .text:0044BC30productId_segs_temp=dwordptr-14h .text:0044BC30new_ProdectID=dwordptr-10h .text:0044BC30sn_lowerDWord=dwordptr-4 .text:0044BC30SN=dwordptr8 .text:0044BC30 .text:0044BC30pushebp .text:0044BC31movebp,esp .text:0044BC33andesp,0FFFFFFF8h .text:0044BC36subesp,14h .text:0044BC39pushebx .text:0044BC3Apushesi .text:0044BC3Bpushedi .text:0044BC3Cpush14h;unsignedint .text:0044BC3Emovebx,eax;ebx指向ProductID首位置 .text:0044BC40callj_??2@YAPAXI@Z;operatornew(uint) .text:0044BC45movesi,eax .text:0044BC47leaeax,[esi+6] .text:0044BC4Apusheax .text:0044BC4Bmoveax,[ebp+SN] .text:0044BC4Eleaecx,[esi+4] .text:0044BC51pushecx .text:0044BC52leaedx,[esi+2] .text:0044BC55pushedx .text:0044BC56pushesi;新申请的14h的空间 .text:0044BC57pushoffseta4x4x4x4x;"%4x-%4x-%4x-%4x" .text:0044BC5Cpusheax;SN首地址 .text:0044BC5DcallString2Integer;将字符串SN转换为数组,比如 .text:0044BC5D;“E6E9-24CB-2968-09BC”变为 .text:0044BC5D;E9E6... .text:0044BC62movecx,[esi+4];ECX为后半部分SN .text:0044BC65movedi,[esi];EDI为前半部分SN .text:0044BC67pushesi;void* .text:0044BC68mov[esp+40h+sn_lowerDWord],ecx .text:0044BC6Ccallj__free .text:0044BC71leaedx,[esp+40h+productId_segs_temp] .text:0044BC75pushedx .text:0044BC76pushoffseta4x;"%4x" .text:0044BC7Bpushebx .text:0044BC7CcallString2Integer;将ProductID第一段转换为Word .text:0044BC81movesi,[esp+4Ch+productId_segs_temp];esi储存productId_1 .text:0044BC85leaeax,[esp+4Ch+productId_segs_temp] .text:0044BC89pusheax .text:0044BC8Aleaecx,[ebx+0Ah] .text:0044BC8Dpushoffsetasc_48C804;"%x" .text:0044BC92pushecx .text:0044BC93callString2Integer .text:0044BC98movedx,[esp+58h+productId_segs_temp];EDX储存ProductId_2 .text:0044BC9Caddesp,38h .text:0044BC9Fxoreax,eax .text:0044BCA1pusheax .text:0044BCA2pushesi .text:0044BCA3pusheax .text:0044BCA4pushedx .text:0044BCA5call__allmul .text:0044BCAAmovesi,eax;product_1*product_2乘积的低word放入esi .text:0044BCACleaeax,[esp+20h+productId_segs_temp] .text:0044BCB0pusheax .text:0044BCB1leaecx,[ebx+14h] .text:0044BCB4pushoffsetasc_48C804;"%x" .text:0044BCB9pushecx .text:0044BCBAmov[esp+2Ch+new_ProdectID+4],edx .text:0044BCBEcallString2Integer .text:0044BCC3movedx,[esp+2Ch+new_ProdectID+4] .text:0044BCC7moveax,[esp+2Ch+productId_segs_temp];eax保存productId_3 .text:0044BCCBaddesp,0Ch .text:0044BCCEpushedx .text:0044BCCFpushesi .text:0044BCD0push0 .text:0044BCD2pusheax .text:0044BCD3call__allmul .text:0044BCD8leaecx,[esp+20h+productId_segs_temp] .text:0044BCDCpushecx .text:0044BCDDpushoffsetasc_48C804;"%x" .text:0044BCE2addebx,1Eh .text:0044BCE5pushebx .text:0044BCE6movesi,eax .text:0044BCE8mov[esp+2Ch+new_ProdectID+4],edx .text:0044BCECcallString2Integer .text:0044BCF1movedx,[esp+2Ch+new_ProdectID+4] .text:0044BCF5moveax,[esp+2Ch+productId_segs_temp] .text:0044BCF9addesp,0Ch .text:0044BCFCpushedx .text:0044BCFDpushesi .text:0044BCFEpush0 .text:0044BD00pusheax .text:0044BD01call__allmul;结果edx高位,eax低位 .text:0044BD06movesi,edx .text:0044BD08shresi,10h .text:0044BD0Bmov[esp+20h+new_ProdectID],eax .text:0044BD0Fmov[esp+20h+new_ProdectID+4],edx .text:0044BD13xorebx,ebx .text:0044BD15movcl,10h .text:0044BD17call__allshr;{edx,eax}==new_prodectID>>10h .text:0044BD1Cmovecx,[esp+20h+new_ProdectID+4] .text:0044BD20xoredx,edx .text:0044BD22push1 .text:0044BD24andeax,0FFFF0000h .text:0044BD29pushedx .text:0044BD2Aaddesi,eax .text:0044BD2Cadcebx,edx .text:0044BD2Emovedx,[esp+28h+new_ProdectID] .text:0044BD32pushecx .text:0044BD33pushedx .text:0044BD34call__allmul;eax=0,edx为new_productID的低位 .text:0044BD39push0 .text:0044BD3Baddesi,eax .text:0044BD3Dpush8475h .text:0044BD42adcebx,edx .text:0044BD44pushebx .text:0044BD45pushesi .text:0044BD46call__alldiv;{edx,eax}=={edx,esi}/0x8475 .text:0044BD4Bpush0 .text:0044BD4Dpush0AE6000h .text:0044BD52pushedx .text:0044BD53pusheax .text:0044BD54call__allmul .text:0044BD59addeax,91F2884Dh .text:0044BD5Eadcedx,2DCh .text:0044BD64movcl,0Ah .text:0044BD66call__allshr .text:0044BD6Bpush0 .text:0044BD6Dpush2046h .text:0044BD72pushedx .text:0044BD73pusheax .text:0044BD74call__allmul .text:0044BD79movecx,0FFFFFFFEh .text:0044BD7Esubecx,eax .text:0044BD80moveax,0FFFFFFFFh .text:0044BD85sbbeax,edx .text:0044BD87movedx,[esp+20h+sn_lowerDWord] .text:0044BD8Bshldedx,edi,1 .text:0044BD8Faddedi,edi .text:0044BD91cmpedi,ecx .text:0044BD93jnzshortloc_44BDA5 .text:0044BD95cmpedx,eax .text:0044BD97jnzshortloc_44BDA5 .text:0044BD99moveax,1 .text:0044BD9Epopedi .text:0044BD9Fpopesi .text:0044BDA0popebx .text:0044BDA1movesp,ebp .text:0044BDA3popebp .text:0044BDA4retn .text:0044BDA5;--------------------------------------------------------------------------- .text:0044BDA5 .text:0044BDA5loc_44BDA5:;CODEXREF:check_PID_SN+163j .text:0044BDA5;check_PID_SN+167j .text:0044BDA5popedi .text:0044BDA6popesi .text:0044BDA7xoreax,eax .text:0044BDA9popebx .text:0044BDAAmovesp,ebp .text:0044BDACpopebp .text:0044BDADretn .text:0044BDADcheck_PID_SNendp 基本思路   通过分析,我了解到,其算法大概思路如下:首先,注册流程有效输入为SerialNumber和ProductID,RegistrationNo实际上没有参与注册的验证计算过程。SRS通过系统各种信息生成ProductID,然后用户需要提供与ProductID匹配的SerialNumber方能注册。当然,SerialNumber是需要你拿美刀换的。   简而言之,SRS将ProductID作fp变换,得到一个64bit长的整数,并将用户输入的序列号做fs变换同样得到一个64bit长整数。为了使注册成功,需要满足: fp(gen())=fs(SerialNumber)成立   (1)   这其中,gen()的算法我们不需要管,因为其结果在界面ProductID框中已经显示了。我们需要找到fp和fs的实现算法,并顺利推出fs-1的实现。从而:  SerialNumber=fs-1(fp(ProductID))  (2) ProductID变换算法描述   我们首先描述fp的实现。fp基本上是由我不知道原理的各种数值变换组成,为了精确表述,我直接用C语言描述: ProductID变换函数描述 __int64getProductID(char*id){ __int64temp=1; DWORDelem; for(inti=0;i<4;i++){ sscanf(id+(i*5),"%x",&elem); temp*=elem; } //高地位变换 DWORDlowerDWord=temp; DWORDupperDWord=temp>>0x20; WORDlower=upperDWord; WORDupper=upperDWord>>0x10; upperDWord=lower; upperDWord<<=0x10; upperDWord|=upper; temp=lowerDWord; temp<<=0x20; temp|=upperDWord; temp/=0x8475; temp*=0xAE6000; temp+=0x2DC91F2884D; temp>>=0xA; temp*=0x2046; temp=0xfffffffffffffffe-temp; returntemp; } SerialNumber变换算法描述     接下来描述fs函数的实现。我们称变换后的ProductID为TransPID,并且LowerDW和HighDW表示一个64bit整数的低双字和高双字,shld表示对应汇编指令的函数,TransSerialNumberHighDW和TransSerialNumberLowDW分别表示变换后的序列号高双字和低双字。则有:   TransSerialNumberHighDW(SerialNumber)= shld(UpperDW(SerialNumber),LowerDW(SerialNumber),1); (3)   TransSerialNumberLowDW(SerialNumber)= LowerDW(SerialNumber)+ LowerDW(SerialNumber);     (4)   fs(SerialNumber)= TransSerialNumberHighDW<<32|TransSerialNumberLowDW;           (5)   SerialNumber逆向变换算法描述   了解了fs的实现,我们接下来需要着手研究实现fs-1的思路。由于fs高双字和低双字分别由不同的方式变换的(3)、(4),所以我们需要分别求出SerialNumber的高低双字。得到SerialNumber的低双字很简单,由(4)可知,我们只要将LowerDW(fp(ProductID))除以2就行。但需注意的是,整个双字值域中,LowerDW(fp(ProductID))/2+(2<<31)同样能满足条件(由于溢出导致的相等),www.it165.net这点很重要!   再来考虑高位的算法。我们需要把HighDW(fp(ProductID))往右移一位,这是左边补入的一位可以任意。这时需要注意,考虑到shld性质,有以下两种情况: ①如果HighDW(fp(ProductID))最低位是1则需要LowerDW(SerialNumber)的最高位为1 ②如果HighDW(fp(ProductID))最低位是0则需要LowerDW(SerialNumber)的最高位为0   考虑到LowerDW(fp(ProductID))/2和LowerDW(fp(ProductID))/2+(2<<31)均可满足条件,若是情况①则选取后者,因为此时可保证LowerDW(SerialNumber)的最高位为1。同理,若是情况②则需选择前者。   该算法的C语言描述如下: voidgetSerialNumber(__int64productId,char*buffer){ DWORDupper=productId>>0x20; DWORDlower=productId; assert((lower&1)==0);//lower=snLower+snLower因此lower必须为偶数 DWORDsnUpper=upper>>1; DWORDsnLower=0; if((upper&1)==1){ snLower=lower/2; snLower+=(1<<31); }else{ snLower=lower/2; } DWORDLONGsn=snUpper; sn<<=0x20; sn|=snLower; WORD*p=(WORD*)&sn; sprintf(buffer,"%04x-%04x-%04x-%04x",p[0],p[1],p[2],p[3]); } 小结   IDA很强大,Crack很费时间,收获的免费SRS使用权和投入的大量时间不成正比。结论:以后还是尽量少搞Crack吧。
上一篇:用于保护应用程序安全的DataSecure解决方案
查看[SRS Audio Sandbox破解纪实]所有评论
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码:
推荐内容
关于我们 服务价格 联系我们 企业网站优化 沈阳网站建设 沈阳维修电脑