首页
社区
课程
招聘
[原创]两个 rsa 加密的程序
发表于: 2006-4-11 15:42 35456

[原创]两个 rsa 加密的程序

2006-4-11 15:42
35456

【文章标题】: 两个 rsa 加密的程序
【文章作者】: rdsnow[BCG][PYG][D.4s]
【作者邮箱】: [email]rdsnow@163.com[/email]
【作者主页】: http://rdsnow.ys168.com
【作者QQ号】: 83757177
【下载地址】: Allok Video Splitter:http://www.alloksoft.com/allok_vsplitter.exe
              All Video Splitter:http://www.zealotsoft.net/download/allsplitter.exe
【保护方式】: RSA
【使用工具】: ODbyDYK v1.10[05.09] rsa_toolII V1.10 ppsiqs
【软件介绍】: a tool to split, cut or trim a video file.
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【文章简介】

感觉很多视频处理程序采用了RSA对程序保护,我下载了几个视频剪接工具,竟然有不少使用了RSA1024,最后一个个放弃,最后找了两个容易的,高手就不要看了。rsa256的可以作出注册机,rsa1024就干脆暴算了。

--------------------------------------------------------------------------------
【破解过程】

Allok Video Splitter 1.6.4

程序友好提示注册码是:XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX,跟进才发现上当了,注册码有 8 段,试探性的输入:
username = "rdsnow[BCG][PYG][D.4s]";
serial = "9876abcd-4321abcd-1234abcd-5678abcd-9876cdef-4321cdef-1234cdef-5678cdef";
然后 Ultra String Reference 搜索错误信息,很容易找到关键代码:

要注意该程序试用的大数运算库中,大数表示是低位在前,高位在后,跟

0040F1D9   .  50            PUSH EAX
0040F1DA   .  51            PUSH ECX
0040F1DB   .  E8 A0E4FFFF   CALL Allok_Vi.0040D680                     ;  关键调用
0040F1E0   .  83C4 08       ADD ESP,8
0040F1E3   .  85C0          TEST EAX,EAX
0040F1E5   .  75 2B         JNZ SHORT Allok_Vi.0040F212              ;  关键跳跃
0040F1E7   .  6A 40         PUSH 40
0040F1E9   .  68 44284200   PUSH Allok_Vi.00422844                   ;  ASCII "Sorry"
0040F1EE   .  68 20284200   PUSH Allok_Vi.00422820                   ;  ASCII "Invalid user name or register code"
0040F1F3   .  8BCD          MOV ECX,EBP
0040F1F5   .  E8 14900000   CALL <JMP.&MFC42.#4224_CWnd::MessageBoxA>
……………………
0040F236   .  50            PUSH EAX                                 ; /<%s>
0040F237   .  8D8424 DC0000>LEA EAX,DWORD PTR SS:[ESP+DC]            ; |
0040F23E   .  68 F8274200   PUSH Allok_Vi.004227F8                   ; |format = "Register successful! License to:%s.   "
0040F243   .  50            PUSH EAX                                 ; |s
0040F244   .  FF15 38B64100 CALL DWORD PTR DS:[<&MSVCRT.sprintf>]    ; \sprintf

跟进 40D680:

0040D680  /$  6A FF         PUSH -1
0040D682  |.  68 D9954100   PUSH Allok_Vi.004195D9                   ;  SE 处理程序安装
0040D687  |.  64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
0040D68D  |.  50            PUSH EAX
0040D68E  |.  64:8925 00000>MOV DWORD PTR FS:[0],ESP
0040D695  |.  81EC 94000000 SUB ESP,94
0040D69B  |.  8B8424 A40000>MOV EAX,DWORD PTR SS:[ESP+A4]
0040D6A2  |.  53            PUSH EBX
0040D6A3  |.  56            PUSH ESI
0040D6A4  |.  50            PUSH EAX
0040D6A5  |.  8D4C24 10     LEA ECX,DWORD PTR SS:[ESP+10]
0040D6A9  |.  C74424 60 C38>MOV DWORD PTR SS:[ESP+60],E6A982C3       ;  n = 0x5F935AC64498D4D5A20B6EAFCC6515DF03EBDAB4FE566A7D4E09CA73E6A982C3
0040D6B1  |.  C74424 64 73C>MOV DWORD PTR SS:[ESP+64],4E09CA73
0040D6B9  |.  C74424 68 7D6>MOV DWORD PTR SS:[ESP+68],FE566A7D
0040D6C1  |.  C74424 6C B4D>MOV DWORD PTR SS:[ESP+6C],3EBDAB4
0040D6C9  |.  C74424 70 DF1>MOV DWORD PTR SS:[ESP+70],CC6515DF             ;  注意,按照高位在后,低位在前的原则得到 n
0040D6D1  |.  C74424 74 AF6>MOV DWORD PTR SS:[ESP+74],A20B6EAF
0040D6D9  |.  C74424 78 D5D>MOV DWORD PTR SS:[ESP+78],4498D4D5
0040D6E1  |.  C74424 7C C65>MOV DWORD PTR SS:[ESP+7C],5F935AC6
0040D6E9  |.  E8 88A90000   CALL <JMP.&MFC42.#537_CString::CString>  ;  CString username = "rdsnow[BCG][PYG][D.4s]"
0040D6EE  |.  8B8C24 B00000>MOV ECX,DWORD PTR SS:[ESP+B0]
0040D6F5  |.  C78424 A40000>MOV DWORD PTR SS:[ESP+A4],0
0040D700  |.  51            PUSH ECX
0040D701  |.  8D4C24 0C     LEA ECX,DWORD PTR SS:[ESP+C]
0040D705  |.  E8 6CA90000   CALL <JMP.&MFC42.#537_CString::CString>  ;  CString serial = "9876abcd-4321abcd-1234abcd-5678abcd-9876cdef-4321cdef-1234cdef-5678cdef"
0040D70A  |.  8B5424 0C     MOV EDX,DWORD PTR SS:[ESP+C]
0040D70E  |.  8B35 28B64100 MOV ESI,DWORD PTR DS:[<&MSVCRT._mbscmp>] ;  msvcrt._mbscmp
0040D714  |.  68 04354200   PUSH Allok_Vi.00423504                   ; /s2 = ""
0040D719  |.  52            PUSH EDX                                 ; |s1
0040D71A  |.  C68424 AC0000>MOV BYTE PTR SS:[ESP+AC],1               ; |
0040D722  |.  FFD6          CALL ESI                                 ; \_mbscmp
0040D724  |.  83C4 08       ADD ESP,8
0040D727  |.  85C0          TEST EAX,EAX
0040D729  |.  0F84 0F020000 JE Allok_Vi.0040D93E                     ;  if(username=="") return flase
0040D72F  |.  8B4424 08     MOV EAX,DWORD PTR SS:[ESP+8]
0040D733  |.  68 04354200   PUSH Allok_Vi.00423504                   ; /s2 = ""
0040D738  |.  50            PUSH EAX                                 ; |s1
0040D739  |.  FFD6          CALL ESI                                 ; \_mbscmp
0040D73B  |.  83C4 08       ADD ESP,8
0040D73E  |.  85C0          TEST EAX,EAX
0040D740  |.  0F84 F8010000 JE Allok_Vi.0040D93E                     ;  if(serial=="") return flase
0040D746  |.  57            PUSH EDI

以上是注册的第一步,检查是否受到用户名和注册码的输入,如果没有输入就返回 false,同时,我们也已经找到了 RSA 算法中的公钥 e 和模 n,可以进入下一步参与大数运算了。

0040D747  |.  6A 00         PUSH 0
0040D749  |.  8D4C24 44     LEA ECX,DWORD PTR SS:[ESP+44]
0040D74D  |.  E8 3E830000   CALL Allok_Vi.00415A90                   ;  bigint n 初始化
0040D752  |.  6A 00         PUSH 0
0040D754  |.  8D4C24 4C     LEA ECX,DWORD PTR SS:[ESP+4C]
0040D758  |.  C68424 AC0000>MOV BYTE PTR SS:[ESP+AC],2
0040D760  |.  E8 2B830000   CALL Allok_Vi.00415A90                   ;  bigint m 初始化
0040D765  |.  B3 03         MOV BL,3
0040D767  |.  68 01000100   PUSH 10001                               ;  注意这个数值
0040D76C  |.  8D4C24 5C     LEA ECX,DWORD PTR SS:[ESP+5C]
0040D770  |.  889C24 AC0000>MOV BYTE PTR SS:[ESP+AC],BL
0040D777  |.  E8 14830000   CALL Allok_Vi.00415A90                   ;  bigint e = 0x10001
0040D77C  |.  8D4C24 58     LEA ECX,DWORD PTR SS:[ESP+58]
0040D780  |.  C68424 A80000>MOV BYTE PTR SS:[ESP+A8],4
0040D788  |.  51            PUSH ECX
0040D789  |.  8D4C24 4C     LEA ECX,DWORD PTR SS:[ESP+4C]
0040D78D  |.  E8 5E830000   CALL Allok_Vi.00415AF0
0040D792  |.  8D4C24 58     LEA ECX,DWORD PTR SS:[ESP+58]
0040D796  |.  889C24 A80000>MOV BYTE PTR SS:[ESP+A8],BL
0040D79D  |.  E8 9E830000   CALL Allok_Vi.00415B40
0040D7A2  |.  8D5424 60     LEA EDX,DWORD PTR SS:[ESP+60]
0040D7A6  |.  6A 08         PUSH 8
0040D7A8  |.  52            PUSH EDX
0040D7A9  |.  8D4C24 48     LEA ECX,DWORD PTR SS:[ESP+48]
0040D7AD  |.  E8 AE810000   CALL Allok_Vi.00415960
0040D7B2  |.  B9 08000000   MOV ECX,8
0040D7B7  |.  33C0          XOR EAX,EAX
0040D7B9  |.  8D7C24 18     LEA EDI,DWORD PTR SS:[ESP+18]
0040D7BD  |.  8D5424 2C     LEA EDX,DWORD PTR SS:[ESP+2C]
0040D7C1  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
0040D7C3  |.  8D4424 34     LEA EAX,DWORD PTR SS:[ESP+34]
0040D7C7  |.  8D4C24 30     LEA ECX,DWORD PTR SS:[ESP+30]
0040D7CB  |.  50            PUSH EAX
0040D7CC  |.  51            PUSH ECX
0040D7CD  |.  8D4424 30     LEA EAX,DWORD PTR SS:[ESP+30]
0040D7D1  |.  52            PUSH EDX
0040D7D2  |.  8D4C24 30     LEA ECX,DWORD PTR SS:[ESP+30]
0040D7D6  |.  50            PUSH EAX
0040D7D7  |.  8D5424 30     LEA EDX,DWORD PTR SS:[ESP+30]
0040D7DB  |.  51            PUSH ECX
0040D7DC  |.  8D4424 30     LEA EAX,DWORD PTR SS:[ESP+30]
0040D7E0  |.  52            PUSH EDX
0040D7E1  |.  8B5424 24     MOV EDX,DWORD PTR SS:[ESP+24]
0040D7E5  |.  8D4C24 30     LEA ECX,DWORD PTR SS:[ESP+30]
0040D7E9  |.  50            PUSH EAX
0040D7EA  |.  51            PUSH ECX
0040D7EB  |.  68 68274200   PUSH Allok_Vi.00422768                   ; |format = "%08lX-%08lX-%08lX-%08lX-%08lX-%08lX-%08lX-%08lX
"
0040D7F0  |.  52            PUSH EDX                                 ; |s
0040D7F1  |.  FF15 34B64100 CALL DWORD PTR DS:[<&MSVCRT.sscanf>]     ; \sscanf
0040D7F7  |.  8B4424 50     MOV EAX,DWORD PTR SS:[ESP+50]            ;  s4
0040D7FB  |.  8B4C24 4C     MOV ECX,DWORD PTR SS:[ESP+4C]            ;  s3
0040D7FF  |.  8B7C24 48     MOV EDI,DWORD PTR SS:[ESP+48]            ;  s2
0040D803  |.  8B5424 44     MOV EDX,DWORD PTR SS:[ESP+44]            ;  s1
0040D807  |.  03C1          ADD EAX,ECX                              ;  result1 = s4 + s3
0040D809  |.  8B4C24 5C     MOV ECX,DWORD PTR SS:[ESP+5C]            ;  s7
0040D80D  |.  03C7          ADD EAX,EDI                              ;  result1 += s2
0040D80F  |.  8B7C24 58     MOV EDI,DWORD PTR SS:[ESP+58]            ;  s6
0040D813  |.  03C2          ADD EAX,EDX                              ;  result1 += s1
0040D815  |.  8B5424 40     MOV EDX,DWORD PTR SS:[ESP+40]            ;  s0
0040D819  |.  33C8          XOR ECX,EAX                              ;  result1 ^= s7
0040D81B  |.  8B4424 54     MOV EAX,DWORD PTR SS:[ESP+54]            ;  s5
0040D81F  |.  83C4 28       ADD ESP,28
0040D822  |.  03C2          ADD EAX,EDX                              ;  result2 = s0 + s5
0040D824  |.  894C24 34     MOV DWORD PTR SS:[ESP+34],ECX            ;  save result1=(s1+s2+s3+s4)^s7
0040D828  |.  33F8          XOR EDI,EAX                              ;  result2 ^= s6
0040D82A  |.  6A 00         PUSH 0
0040D82C  |.  8D4C24 3C     LEA ECX,DWORD PTR SS:[ESP+3C]
0040D830  |.  897C24 34     MOV DWORD PTR SS:[ESP+34],EDI            ;  save result2=(s0+s5)^s6
0040D834  |.  E8 57820000   CALL Allok_Vi.00415A90                   ;  bigint m = result

以上到了注册的第二步,如果注册码是 s0-s1-s2-s3-s4-s5-s6-s7,首先把 s6 和 s7 原先处理一下,处理的方法是:
s6 = ( s0 + s5 ) ^ s6
s7 = ( s1 + s2 + s3 + s4 ) ^ s7
然后按照低位前,高位后的原则:m = s7s6s5s4s3s2s1s0
比如我输入的serial是:9876abcd-4321abcd-1234abcd-5678abcd-9876cdef-4321cdef-1234cdef-5678cdef
s6 变换为:0xC9ACB453
s7 变化为:0x123D1CB9
最后,m = 0x123D1CB9C9ACB4534321CDEF9876CDEF5678ABCD1234ABCD4321ABCD9876ABCD


0040D839  |.  8D4C24 18     LEA ECX,DWORD PTR SS:[ESP+18]
0040D83D  |.  6A 08         PUSH 8
0040D83F  |.  51            PUSH ECX
0040D840  |.  8D4C24 40     LEA ECX,DWORD PTR SS:[ESP+40]
0040D844  |.  C68424 B00000>MOV BYTE PTR SS:[ESP+B0],5
0040D84C  |.  E8 0F810000   CALL Allok_Vi.00415960                   ;  rsa_de( ),计算 c = m^e mod n
0040D851  |.  8D5424 38     LEA EDX,DWORD PTR SS:[ESP+38]
0040D855  |.  8D4424 50     LEA EAX,DWORD PTR SS:[ESP+50]
0040D859  |.  52            PUSH EDX
0040D85A  |.  50            PUSH EAX
0040D85B  |.  8D4C24 48     LEA ECX,DWORD PTR SS:[ESP+48]
0040D85F  |.  E8 2C060000   CALL Allok_Vi.0040DE90                   ;  结果以大数输出 c
0040D864  |.  B9 08000000   MOV ECX,8
0040D869  |.  33C0          XOR EAX,EAX
0040D86B  |.  8D7C24 18     LEA EDI,DWORD PTR SS:[ESP+18]
0040D86F  |.  6A 08         PUSH 8
0040D871  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
0040D873  |.  8D4C24 1C     LEA ECX,DWORD PTR SS:[ESP+1C]
0040D877  |.  C68424 AC0000>MOV BYTE PTR SS:[ESP+AC],6
0040D87F  |.  51            PUSH ECX
0040D880  |.  8D4C24 58     LEA ECX,DWORD PTR SS:[ESP+58]
0040D884  |.  E8 17810000   CALL Allok_Vi.004159A0                   ;  大数结果转为十六进制字节串 c
0040D889  |.  B9 08000000   MOV ECX,8
0040D88E  |.  33C0          XOR EAX,EAX
0040D890  |.  8DBC24 800000>LEA EDI,DWORD PTR SS:[ESP+80]
0040D897  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
0040D899  |.  5F            POP EDI                                  ;  以下交换每一个dword的高位和低位
0040D89A  |>  8A5404 17     /MOV DL,BYTE PTR SS:[ESP+EAX+17]
0040D89E  |.  8A4C04 16     |MOV CL,BYTE PTR SS:[ESP+EAX+16]
0040D8A2  |.  885404 7C     |MOV BYTE PTR SS:[ESP+EAX+7C],DL
0040D8A6  |.  8B5404 14     |MOV EDX,DWORD PTR SS:[ESP+EAX+14]
0040D8AA  |.  884C04 7D     |MOV BYTE PTR SS:[ESP+EAX+7D],CL
0040D8AE  |.  8A4C04 14     |MOV CL,BYTE PTR SS:[ESP+EAX+14]
0040D8B2  |.  C1EA 08       |SHR EDX,8
0040D8B5  |.  885404 7E     |MOV BYTE PTR SS:[ESP+EAX+7E],DL
0040D8B9  |.  884C04 7F     |MOV BYTE PTR SS:[ESP+EAX+7F],CL
0040D8BD  |.  83C0 04       |ADD EAX,4
0040D8C0  |.  83F8 20       |CMP EAX,20
0040D8C3  |.^ 7C D5         \JL SHORT Allok_Vi.0040D89A

这里到了注册的第三步:对以上信息RSA运算,并将结果分成 8 个dword,将每一个dword 的高位和低位交换

0040D8C5  |.  8D5424 7C     LEA EDX,DWORD PTR SS:[ESP+7C]
0040D8C9  |.  8D4C24 10     LEA ECX,DWORD PTR SS:[ESP+10]
0040D8CD  |.  52            PUSH EDX
0040D8CE  |.  E8 A3A70000   CALL <JMP.&MFC42.#537_CString::CString>
0040D8D3  |.  8B4424 10     MOV EAX,DWORD PTR SS:[ESP+10]
0040D8D7  |.  8B4C24 0C     MOV ECX,DWORD PTR SS:[ESP+C]
0040D8DB  |.  50            PUSH EAX
0040D8DC  |.  51            PUSH ECX
0040D8DD  |.  FFD6          CALL ESI                                 ;  rsa 结果跟用户名比较
0040D8DF  |.  83C4 08       ADD ESP,8
0040D8E2  |.  8D4C24 10     LEA ECX,DWORD PTR SS:[ESP+10]
0040D8E6  |.  85C0          TEST EAX,EAX
0040D8E8  |.  C68424 A40000>MOV BYTE PTR SS:[ESP+A4],6
0040D8F0  |.  0F84 86000000 JE Allok_Vi.0040D97C                     ;  关键跳跃
0040D8F6  |.  E8 F7A30000   CALL <JMP.&MFC42.#800_CString::~CString>
0040D8FB  |.  8D4C24 4C     LEA ECX,DWORD PTR SS:[ESP+4C]
……………………
0040D964  |.  33C0          XOR EAX,EAX                                     ;  return false
0040D966  |.  5B            POP EBX
0040D967  |.  8B8C24 940000>MOV ECX,DWORD PTR SS:[ESP+94]
0040D96E  |.  64:890D 00000>MOV DWORD PTR FS:[0],ECX
0040D975  |.  81C4 A0000000 ADD ESP,0A0
0040D97B  |.  C3            RETN
0040D97C  |> \E8 71A30000   CALL <JMP.&MFC42.#800_CString::~CString>
0040D981  |.  8D4C24 4C     LEA ECX,DWORD PTR SS:[ESP+4C]
……………………
0040D9E9  |.  8B8C24 9C0000>MOV ECX,DWORD PTR SS:[ESP+9C]
0040D9F0  |.  5E            POP ESI
0040D9F1  |.  B8 01000000   MOV EAX,1                                     ;  return true
0040D9F6  |.  5B            POP EBX
0040D9F7  |.  64:890D 00000>MOV DWORD PTR FS:[0],ECX
0040D9FE  |.  81C4 A0000000 ADD ESP,0A0
0040DA04  \.  C3            RETN

--------------------------------------------------------------------------------
既然已经找到了模数 n ,我们得化一些时间去分解这个模数,将数值转为十进制,复制到 ppsiqs 窗口,然后等待......
还好256位的数值分解,ppsiqs完全可以胜任,Sempron 2200+ 256M DDR 运行,几十分钟后,PPsigs 的 logo 文件中给出答案:
43230073636397487656983558936559823181690578386630754424326657423034966180547 = P39 * P39
P39 = 152459900927658332219918333765741632151
P39 = 283550450796304794710461168046173026997
cputime 0:33:53:29
然后rsa_tool计算出密钥 d,由此可得:
n:5F935AC64498D4D5A20B6EAFCC6515DF03EBDAB4FE566A7D4E09CA73E6A982C3

p:72B2B5774A8A54DCC5BC6B499852DA97
q:D551D494A7EE88B04694CF5CD17F7AB5

e:10001
d:3B60C4E8A0FD825D274B8AFCD533881E35FB43F58255A6962D7E8878D5B2A9A1

程序拿 RSA_de 的结果和用户名比较,判断是否授权

拿 username 得到 serial 的运算过程是:现将 username 分成若干 dword,并交换 dword 的高位和低位,我的用户名是:rdsnow[BCG][PYG][D.4s]
换位后得到:c = s]/0/0[D.sPYG]CG][ow[Brdsn,注意中间的两个'/0',如果 strlen(username) 是四的整数倍,则不会出现,按照顺序转为 HEX 文本,然后 RSA_en,最后用
s6 = ( s0 + s5 ) ^ s6
s7 = ( s1 + s2 + s3 + s4 ) ^ s7
恢复 s6 和 s7。
另外程序中没有对 m 和 c 是否大于 n 的判断,所以建议 strlen(username) 小于 32 ,以确保 m 不会大于 n。
注册信息保存在 data.ini 中,删了这个文件,程序就会变成未注册版。

--------------------------------------------------------------------------------
【注册机源码】

用 miracl 运算库写个 keygen ,要注意 mriacl 的 big_to_bytes 输出的字节串是高位在前的,跟程序中不同,要注意改过来。

extern "C"
{
#include "miracl.h"
#include "mirdef.h"
}

#pragma comment( lib, "ms32.lib" )

void CKeygenDlg::OnOK()
{
        // TODO: Add extra validation here
        byte username[32]={0},i;
        char temp[4];
        TCHAR buff[68]={0};
        UINT serial[8];

        Beep(1000,10);
        UpdateData(true);
        i=m_Edit1.GetLength ();
        memcpy (username,m_Edit1,i+1);

//将用户名每四个字符倒序,并转成十六进制字符串
        for(i=32;i>0;i=i-4){
                sprintf(temp,"%02X",username[i-4]);strcat((char *)buff,temp);
                sprintf(temp,"%02X",username[i-3]);strcat((char *)buff,temp);
                sprintf(temp,"%02X",username[i-2]);strcat((char *)buff,temp);
                sprintf(temp,"%02X",username[i-1]);strcat((char *)buff,temp);
        }
       
//MIRACL大数运算库运算
        miracl *mip=mirsys(100,0);
        mip->IOBASE=16;                //16进制模式
       
//定义并初始化变量
        big m=mirvar(0);        //m 放明文:注册码serial
        big c=mirvar(0);        //c 放密文:用户名username
        big n=mirvar(0);        //n 模数
        big d=mirvar(0);        //d 私钥
       
        cinstr(c,buff);                                                                        //初始化密文c
        memset(buff,0,68);
        cinstr(n,"5F935AC64498D4D5A20B6EAFCC6515DF03EBDAB4FE566A7D4E09CA73E6A982C3");        //初始化模数n         
        cinstr(d,"3B60C4E8A0FD825D274B8AFCD533881E35FB43F58255A6962D7E8878D5B2A9A1");        //初始化私钥e

        powmod(c,d,n,m);                                //计算m=c^d mod n
        big_to_bytes(0,m,buff,FALSE);        //将c转换成数组写入buff
        mirkill(m);
        mirkill(c);
        mirkill(n);
        mirkill(d);
        mirexit();

        for(i=0;i<8;i++){
                serial[7-i]=(byte)buff[(i<<2)];
                serial[7-i]=(serial[7-i]<<8)+(byte)buff[(i<<2)+1];
                serial[7-i]=(serial[7-i]<<8)+(byte)buff[(i<<2)+2];
                serial[7-i]=(serial[7-i]<<8)+(byte)buff[(i<<2)+3];
        }
        serial[7]=(serial[1]+serial[2]+serial[3]+serial[4])^serial[7];
        serial[6]=(serial[0]+serial[5])^serial[6];

        m_Edit2.Format ("%08lX",serial[0]);m_Edit2+='-';
        sprintf(buff,"%08lX",serial[1]);m_Edit2+=buff;m_Edit2+='-';
        sprintf(buff,"%08lX",serial[2]);m_Edit2+=buff;m_Edit2+='-';
        sprintf(buff,"%08lX",serial[3]);m_Edit2+=buff;m_Edit2+='-';
        sprintf(buff,"%08lX",serial[4]);m_Edit2+=buff;m_Edit2+='-';
        sprintf(buff,"%08lX",serial[5]);m_Edit2+=buff;m_Edit2+='-';
        sprintf(buff,"%08lX",serial[6]);m_Edit2+=buff;m_Edit2+='-';
        sprintf(buff,"%08lX",serial[7]);m_Edit2+=buff;

        UpdateData(false);       
}


--------------------------------------------------------------------------------
【对比另一个类似程序】

在调试这个软件的同时我也调试过另一个视频剪接软件All Video Splitter,不同的是用了 rsa1024 ,两个程序也有了不一样的命运。

004B126B  |.  BA 60164B00   MOV EDX,videospl.004B1660          ;  ASCII ".DEFAULT\Software\Zealotsoft\All Video Splitter"
004B1270  |.  8BC3          MOV EAX,EBX
004B1272  |.  E8 C17EF8FF   CALL videospl.00439138
004B1277  |.  84C0          TEST AL,AL
004B1279  |.  0F84 B1020000 JE videospl.004B1530
004B127F  |.  E8 D8FAFFFF   CALL videospl.004B0D5C             ;  read username & regcode
004B1284  |.  A1 543E4B00   MOV EAX,DWORD PTR DS:[4B3E54]
004B1289  |.  8338 00       CMP DWORD PTR DS:[EAX],0
004B128C  |.  0F84 EE000000 JE videospl.004B1380               ;  if(strlen(username)==0) return false
004B1292  |.  A1 F43E4B00   MOV EAX,DWORD PTR DS:[4B3EF4]
004B1297  |.  8338 00       CMP DWORD PTR DS:[EAX],0
004B129A  |.  0F84 E0000000 JE videospl.004B1380               ;  if(strlen(regcode)==0) return false
004B12A0  |.  B8 645D4B00   MOV EAX,videospl.004B5D64
004B12A5  |.  8B15 F43E4B00 MOV EDX,DWORD PTR DS:[4B3EF4]      ;  videospl.004B5CD8
004B12AB  |.  8B12          MOV EDX,DWORD PTR DS:[EDX]
004B12AD  |.  E8 DE2EF5FF   CALL videospl.00404190
004B12B2  |.  BA 485D4B00   MOV EDX,videospl.004B5D48
004B12B7  |.  A1 645D4B00   MOV EAX,DWORD PTR DS:[4B5D64]
004B12BC  |.  E8 1FCDFFFF   CALL videospl.004ADFE0             :  跟进,跟进代码在后面
004B12C1  |.  B8 645D4B00   MOV EAX,videospl.004B5D64
004B12C6  |.  E8 712EF5FF   CALL videospl.0040413C
004B12CB  |.  8D55 E8       LEA EDX,DWORD PTR SS:[EBP-18]
004B12CE  |.  A1 9C3E4B00   MOV EAX,DWORD PTR DS:[4B3E9C]
004B12D3  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
004B12D5  |.  8B80 38030000 MOV EAX,DWORD PTR DS:[EAX+338]
004B12DB  |.  E8 1CFEFAFF   CALL videospl.004610FC             ;  取得 e:65537 即 0x10001
004B12E0  |.  8B45 E8       MOV EAX,DWORD PTR SS:[EBP-18]
004B12E3  |.  8D55 EC       LEA EDX,DWORD PTR SS:[EBP-14]
004B12E6  |.  E8 D572F5FF   CALL videospl.004085C0
004B12EB  |.  8B45 EC       MOV EAX,DWORD PTR SS:[EBP-14]
004B12EE  |.  BA 4C5D4B00   MOV EDX,videospl.004B5D4C
004B12F3  |.  E8 DCD0FFFF   CALL videospl.004AE3D4             ;  将 e 转为大数
004B12F8  |.  8D55 E0       LEA EDX,DWORD PTR SS:[EBP-20]
004B12FB  |.  A1 9C3E4B00   MOV EAX,DWORD PTR DS:[4B3E9C]
004B1300  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
004B1302  |.  8B80 3C030000 MOV EAX,DWORD PTR DS:[EAX+33C]
004B1308  |.  E8 EFFDFAFF   CALL videospl.004610FC             ;  取模 n:6433969951……985573
004B130D  |.  8B45 E0       MOV EAX,DWORD PTR SS:[EBP-20]
004B1310  |.  8D55 E4       LEA EDX,DWORD PTR SS:[EBP-1C]
004B1313  |.  E8 A872F5FF   CALL videospl.004085C0
004B1318  |.  8B45 E4       MOV EAX,DWORD PTR SS:[EBP-1C]
004B131B  |.  BA 545D4B00   MOV EDX,videospl.004B5D54
004B1320  |.  E8 AFD0FFFF   CALL videospl.004AE3D4             ;  将 n 转为大数
004B1325  |.  68 5C5D4B00   PUSH videospl.004B5D5C
004B132A  |.  68 5C5D4B00   PUSH videospl.004B5D5C
004B132F  |.  68 5C5D4B00   PUSH videospl.004B5D5C
004B1334  |.  68 5C5D4B00   PUSH videospl.004B5D5C
004B1339  |.  68 645D4B00   PUSH videospl.004B5D64
004B133E  |.  B9 545D4B00   MOV ECX,videospl.004B5D54
004B1343  |.  BA 4C5D4B00   MOV EDX,videospl.004B5D4C
004B1348  |.  A1 485D4B00   MOV EAX,DWORD PTR DS:[4B5D48]
004B134D  |.  E8 E6F4FFFF   CALL videospl.004B0838             ;  rsa_de( )
004B1352  |.  A1 F43E4B00   MOV EAX,DWORD PTR DS:[4B3EF4]
004B1357  |.  8B15 645D4B00 MOV EDX,DWORD PTR DS:[4B5D64]
004B135D  |.  E8 2E2EF5FF   CALL videospl.00404190
004B1362  |.  B8 4C5D4B00   MOV EAX,videospl.004B5D4C
004B1367  |.  E8 E0D2FFFF   CALL videospl.004AE64C
004B136C  |.  B8 545D4B00   MOV EAX,videospl.004B5D54
004B1371  |.  E8 D6D2FFFF   CALL videospl.004AE64C
004B1376  |.  B8 5C5D4B00   MOV EAX,videospl.004B5D5C
004B137B  |.  E8 CCD2FFFF   CALL videospl.004AE64C
004B1380  |>  A1 543E4B00   MOV EAX,DWORD PTR DS:[4B3E54]
004B1385  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
004B1387  |.  8B15 F43E4B00 MOV EDX,DWORD PTR DS:[4B3EF4]      ;  videospl.004B5CD8
004B138D  |.  8B12          MOV EDX,DWORD PTR DS:[EDX]
004B138F  |.  E8 B431F5FF   CALL videospl.00404548             ;  rsa 的结果跟用户名比较
004B1394  |.  75 2D         JNZ SHORT videospl.004B13C3
004B1396  |.  A1 A0424B00   MOV EAX,DWORD PTR DS:[4B42A0]
004B139B  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
004B139D  |.  8B80 44030000 MOV EAX,DWORD PTR DS:[EAX+344]
004B13A3  |.  33D2          XOR EDX,EDX
004B13A5  |.  8B08          MOV ECX,DWORD PTR DS:[EAX]
004B13A7  |.  FF51 64       CALL DWORD PTR DS:[ECX+64]
004B13AA  |.  A1 A0424B00   MOV EAX,DWORD PTR DS:[4B42A0]
004B13AF  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
004B13B1  |.  8B80 50030000 MOV EAX,DWORD PTR DS:[EAX+350]
004B13B7  |.  33D2          XOR EDX,EDX
004B13B9  |.  8B08          MOV ECX,DWORD PTR DS:[EAX]
004B13BB  |.  FF51 64       CALL DWORD PTR DS:[ECX+64]
004B13BE  |.  E9 0D020000   JMP videospl.004B15D0
004B13C3  |>  8D4D D8       LEA ECX,DWORD PTR SS:[EBP-28]
004B13C6  |.  BA 98164B00   MOV EDX,videospl.004B1698          ;  ASCII "UserDate"
004B13CB  |.  8BC3          MOV EAX,EBX
004B13CD  |.  E8 2E7FF8FF   CALL videospl.00439300

004B12BC CALL videospl.004ADFE0 的跟进代码:

004AE03E  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
004AE041  |.  E8 B663F5FF   CALL videospl.004043FC             ;  strlen(regcode),作为下面循环次数
004AE046  |.  8BD8          MOV EBX,EAX
004AE048  |.  85DB          TEST EBX,EBX
004AE04A  |.  7E 20         JLE SHORT videospl.004AE06C
004AE04C  |.  BE 01000000   MOV ESI,1
004AE051  |>  8D45 F8       /LEA EAX,DWORD PTR SS:[EBP-8]
004AE054  |.  8B55 FC       |MOV EDX,DWORD PTR SS:[EBP-4]      ;  read regcode
004AE057  |.  0FB65432 FF   |MOVZX EDX,BYTE PTR DS:[EDX+ESI-1] ;  regcode[i]
004AE05C  |.  8B9495 F4FBFF>|MOV EDX,DWORD PTR SS:[EBP+EDX*4-4>;  根据regcode[i]查替换表得6位的二进制字符串
004AE063  |.  E8 9C63F5FF   |CALL videospl.00404404            ;  strcat( )
004AE068  |.  46            |INC ESI                           ;  i + 1
004AE069  |.  4B            |DEC EBX                           ;  循环次数减 1
004AE06A  |.^ 75 E5         \JNZ SHORT videospl.004AE051

替换表在堆栈窗口可以看到:

0012FBEC   01165088  ASCII "111110"        ; +
0012FBF0   00000000
0012FBF4   00000000
0012FBF8   00000000
0012FBFC   00000000
0012FC00   01164FC0  ASCII "110100"        ; 0
0012FC04   01164FD4  ASCII "110101"        ; 1
0012FC08   01164FE8  ASCII "110110"        ; 2
0012FC0C   01164FFC  ASCII "110111"        ; 3
0012FC10   01165010  ASCII "111000"        ; 4
0012FC14   01165024  ASCII "111001"        ; 5
0012FC18   01165038  ASCII "111010"        ; 6
0012FC1C   0116504C  ASCII "111011"        ; 7
0012FC20   01165060  ASCII "111100"        ; 8
0012FC24   01165074  ASCII "111101"        ; 9
0012FC28   00000000
0012FC2C   00000000
0012FC30   00000000
0012FC34   0116509C  ASCII "111111"        ; =
0012FC38   00000000
0012FC3C   00000000
0012FC40   00000000
0012FC44   01160234  ASCII "000001"        ; A
0012FC48   0115DAF0  ASCII "000011"        ; B
0012FC4C   01161F28  ASCII "000101"        ; C
0012FC50   01164C3C  ASCII "000111"        ; D
………………
………………  依次加 2
………………
0012FCA0   01164F5C  ASCII "101111"        ; X
0012FCA4   01164F84  ASCII "110001"        ; Y
0012FCA8   01164FAC  ASCII "110011"        ; Z
0012FCAC   00000000
0012FCB0   00000000
0012FCB4   00000000
0012FCB8   00000000
0012FCBC   00000000
0012FCC0   00000000
0012FCC4   01162F88  ASCII "000000"        ; a
0012FCC8   01149CFC  ASCII "000010"        ; b
0012FCCC   01161F14  ASCII "000100"        ; c
0012FCD0   01164C28  ASCII "000110"        ; d
0012FCD4   01164C50  ASCII "001000"        ; e
………………
………………  依次加 2
………………
0012FD20   01164F48  ASCII "101110"        ; x
0012FD24   01164F70  ASCII "110000"        ; y
0012FD28   01164F98  ASCII "110010"        ; z

004AE06C  |>  8BC7          MOV EAX,EDI
004AE06E  |.  E8 C960F5FF   CALL videospl.0040413C
004AE073  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]
004AE076  |.  E8 8163F5FF   CALL videospl.004043FC             ;  strcat( ) 结果的长度
004AE07B  |.  85C0          TEST EAX,EAX
004AE07D  |.  79 03         JNS SHORT videospl.004AE082
004AE07F  |.  83C0 07       ADD EAX,7                          ;  if(strlen()==0) strlen()=7
004AE082  |>  C1F8 03       SAR EAX,3                          ;  strlen()/8 作为下面的循环次数
004AE085  |.  8BD8          MOV EBX,EAX
004AE087  |.  85DB          TEST EBX,EBX
004AE089  |.  7E 57         JLE SHORT videospl.004AE0E2
004AE08B  |>  8D85 F0FBFFFF /LEA EAX,DWORD PTR SS:[EBP-410]
004AE091  |.  50            |PUSH EAX
004AE092  |.  B9 08000000   |MOV ECX,8
004AE097  |.  BA 01000000   |MOV EDX,1
004AE09C  |.  8B45 F8       |MOV EAX,DWORD PTR SS:[EBP-8]      ;  char *pstr 指针最初指向上面strcat( )的结果
004AE09F  |.  E8 B865F5FF   |CALL videospl.0040465C            ;  从 pstr 指针处取 8 个字符
004AE0A4  |.  8B95 F0FBFFFF |MOV EDX,DWORD PTR SS:[EBP-410]
004AE0AA  |.  8D45 F7       |LEA EAX,DWORD PTR SS:[EBP-9]
004AE0AD  |.  E8 AAFBFFFF   |CALL videospl.004ADC5C            ;  转成数值,得到一个byte
004AE0B2  |.  8D85 ECFBFFFF |LEA EAX,DWORD PTR SS:[EBP-414]
004AE0B8  |.  8A55 F7       |MOV DL,BYTE PTR SS:[EBP-9]
004AE0BB  |.  E8 6462F5FF   |CALL videospl.00404324
004AE0C0  |.  8B95 ECFBFFFF |MOV EDX,DWORD PTR SS:[EBP-414]
004AE0C6  |.  8BC7          |MOV EAX,EDI
004AE0C8  |.  E8 3763F5FF   |CALL videospl.00404404            ;  将每轮循环中得到的 byte 拼成字节串
004AE0CD  |.  8D45 F8       |LEA EAX,DWORD PTR SS:[EBP-8]
004AE0D0  |.  B9 08000000   |MOV ECX,8
004AE0D5  |.  BA 01000000   |MOV EDX,1
004AE0DA  |.  E8 BD65F5FF   |CALL videospl.0040469C            ;  pstr + 8
004AE0DF  |.  4B            |DEC EBX
004AE0E0  |.^ 75 A9         \JNZ SHORT videospl.004AE08B
004AE0E2  |>  33C0          XOR EAX,EAX
004AE0E4  |.  5A            POP EDX
004AE0E5  |.  59            POP ECX
004AE0E6  |.  59            POP ECX

程序首先将注册码中的每一个字符替换成'0'、'1'组成的六位字符串,然后每八个转成一个byte,连接后作待加密信息。
比如,输入假码:9876543321abcd
程序首先查表替换成:"111101 111100 111011 111010 111000 111001 110111 110110 110101 000000 000010 000100 000110"
然后每八个分组:"11110111 11001110 11111010 11100011 10011101 11110110 11010100 00000000 10000100 000110"
十六进制就是:F7 CE FA E7 8D F6 D4 00 84 最后还多一些不足 8 位的就舍去,这个进行 rsa 计算结果等于 username就通过。

如果要作注册机就必须多模数 n 因式分解,再看看n:
10进制:64339699515705192068194993623307081615062638322012232511872724556480843761749970481781239168889774406854078190595474311516630418546131048058995412744169522448609743655131377088569993438211545658975497514074789487215208702967896731510271633140995521267487600450311206985573
HEX:
79C99D3C3FAF7FF633A11AC06DB700D5B0A93ED27F641C66A9DCEFBE9E679ACB0EE67791C742313BD7A71A10028AFB28661757BF2816DBF1CC000076247DCD371179C831E10887F4AC34C96C5448C83702668432FEA31B5DC6C938D8EAB27B68A7B5065787A02632C3817B7C9E71DFDF65
rsa_tools II 测试数据达到903位,因式分解式不可能了。程序只能爆破,程序有四处地方拿 rsa 结果跟 username 比较:
1、启动程序时;2、打开关于对话框时;3、打开注册对话框时;4、关闭程序时;5、打开视频文件及添加水印时;
如果一一修改比较麻烦,程序并不进行多次的 rsa 运算,rsa会拖掉程序的运行速度,每次比较都是调用的同一个rsa的运算结果,我们就在第一次rsa运算后,比较前修改rsa的运算结果


找到这个地方修改:
004B1387  |.  8B15 F43E4B00 MOV EDX,DWORD PTR DS:[4B3EF4]      ;  videospl.004B5CD8
004B138D  |.  8B12          MOV EDX,DWORD PTR DS:[EDX]
004B138F  |.  E8 B431F5FF   CALL videospl.00404548             ;  rsa 的结果跟用户名比较,patch
004B1394  |.  75 2D         JNZ SHORT videospl.004B13C3
004B1396  |.  A1 A0424B00   MOV EAX,DWORD PTR DS:[4B42A0]

以上代码改为:

004B1387   .  8B15 F43E4B00 MOV EDX,DWORD PTR DS:[4B3EF4]      ;  videospl.004B5CD8
004B138D   .  8B12          MOV EDX,DWORD PTR DS:[EDX]
004B138F   .  E9 6C090000   JMP videospl.004B1D00              ;  patch,不用比了,直接跳到自己的代码
004B1394   .  75 2D         JNZ SHORT videospl.004B13C3
004B1396   >  A1 A0424B00   MOV EAX,DWORD PTR DS:[4B42A0]

………………

004B1D00   > \60            PUSHAD                              ;  保护现场
004B1D01   .  8B48 FC       MOV ECX,DWORD PTR DS:[EAX-4]
004B1D04   .  894A FC       MOV DWORD PTR DS:[EDX-4],ECX        ;  取用户名长度
004B1D07   .  85C9          TEST ECX,ECX
004B1D09   .  74 0A         JE SHORT videospl.004B1D15
004B1D0B   .  8BFA          MOV EDI,EDX                         ;  usename
004B1D0D   .  8BF0          MOV ESI,EAX                         ;  rsa_result
004B1D0F   .  FC            CLD
004B1D10   .  F3:A4         REP MOVS BYTE PTR ES:[EDI],BYTE PTR>;  字符串传送
004B1D12   .  C607 00       MOV BYTE PTR DS:[EDI],0             ;  字符串结束标志
004B1D15   >  61            POPAD                               ;  恢复现场
004B1D16   .^ E9 7BF6FFFF   JMP videospl.004B1396               ;  跳回去执行原来的代码,不好意思,来比较都省了,看下堆栈,没有问题,^_^

最后不要忘记在程序文件夹中建立一个文件 xxxx.ini,xxxx跟程序文件名相同,里面写上自己的名字和任意注册码:
[Options]
User=rdsnow[BCG][PYG][D.4s]
Pass=98764321abcd
测试程序,变成了注册版,剪接的视频也没有了水印,看来是完美爆破了,看到论坛上有用替换模数 n 的方法破解,但是反正要改程序,我就直接爆了。
--------------------------------------------------------------------------------
【破解心得】

同样是使用 rsa 加密程序,但是两个程序都有缺陷
第一个程序被写出了注册机模是因为数太短,现在256位大数的因式分解用时不到1小时,失去了使用rsa的意义。
第二个程序虽然用了 rsa1024,但是却在程序的校验上做的不够,让人随意修改他的代码,关键代码要着重保护。

--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年04月07日 18:24:48


[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!

收藏
免费 7
支持
分享
最新回复 (15)
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
2
看不懂
2006-4-11 16:13
0
雪    币: 133
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
顶了
2006-4-11 16:15
0
雪    币: 2506
活跃值: (1030)
能力值: (RANK:990 )
在线值:
发帖
回帖
粉丝
4
我说呢,上次在搞RSA就是这两个吧?支持
2006-4-11 17:06
0
雪    币: 1022
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
支持。
2006-4-11 17:17
0
雪    币: 225
活跃值: (1251)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不错,我就喜欢有密码学算法的(出MD5,sha之外)
2006-4-11 19:21
0
雪    币: 235
活跃值: (40)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
7
支持,强
2006-4-11 19:31
0
雪    币: 230
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
1024或者2048什么的可以考虑替换
2006-4-11 19:44
0
雪    币: 443
活跃值: (200)
能力值: ( LV9,RANK:1140 )
在线值:
发帖
回帖
粉丝
9
强就一个字,学习!
2006-4-11 21:11
0
雪    币: 267
活跃值: (44)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
10
强,支持一下!
2006-4-11 22:02
0
雪    币: 222
活跃值: (40)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
11
强就一个字,我要说N次,支持
2006-4-11 22:43
0
雪    币: 50
活跃值: (145)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
12
强,好文一篇
2006-4-12 00:01
0
雪    币: 234
活跃值: (370)
能力值: ( LV9,RANK:530 )
在线值:
发帖
回帖
粉丝
13
顶了
2006-4-12 08:28
0
雪    币: 242
活跃值: (163)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
14
rsa要好好学下的,这个很好
2006-4-12 09:24
0
雪    币: 389
活跃值: (912)
能力值: ( LV9,RANK:770 )
在线值:
发帖
回帖
粉丝
15
支持一下
2006-4-12 16:49
0
雪    币: 279
活跃值: (160)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
16
不错。学习+收藏
2006-4-12 22:43
0
游客
登录 | 注册 方可回帖
返回
//