首页
社区
课程
招聘
[原创]MagicISO的逆向过程及算法破解
发表于: 2015-7-22 16:22 10208

[原创]MagicISO的逆向过程及算法破解

2015-7-22 16:22
10208
004AF18C PUSH ECX                        ; /Arg2,序列号
004AF18D MOV EAX,DWORD PTR SS:[EBP-8]    ; |
004AF190 PUSH EAX                        ; |Arg1,用户名
004AF191 CALL test.0047B0B0              ; \创建保存用户名和序列号的注册表键值
0047B2B2 PUSH EAX                                 ; /BufSize,用户名长度
0047B2B3 PUSH EBX                                 ; |Buffer,用户名地址
0047B2B4 PUSH 1                                   ; |ValueType = REG_SZ
0047B2B6 PUSH 0                                   ; |Reserved = 0
0047B2B8 PUSH test.0070063D                       ; |ValueName = "RegUserName"
0047B2BD MOV EAX,DWORD PTR SS:[EBP-40]            ; |
0047B2C0 PUSH EAX                                 ; |hKey
0047B2C1 CALL <JMP.&ADVAPI32.RegSetValueExA>      ; \RegSetValueExA
0047B697 PUSH EDX                                 ; /读取出来的用户名的长度
0047B698 MOV ECX,DWORD PTR SS:[EBP-8]             ; |
0047B69B LEA EAX,DWORD PTR SS:[EBP-38]            ; |
0047B69E PUSH ECX                                 ; |读取出来的用户名存储在此地址中
0047B69F PUSH EAX                                 ; |pValueType
0047B6A0 PUSH 0                                   ; |Reserved = NULL
0047B6A2 PUSH test.00700693                       ; |ValueName = "RegUserName"
0047B6A7 MOV EDX,DWORD PTR SS:[EBP-34]            ; |
0047B6AA PUSH EDX                                 ; |hKey
0047B6AB CALL <JMP.&ADVAPI32.RegQueryValueExA>    ; \RegQueryValueExA
0047BA9E   /TEST EAX,EAX
0047BAA0  |JNZ SHORT test.0047BAC1
0047BAA2  |MOV EAX,DWORD PTR SS:[EBP-4]
0047BAA5  |INC DWORD PTR SS:[EBP-4]
0047BAA8  |MOV EDX,DWORD PTR SS:[EBP+8]
0047BAAB  |MOV CL,BYTE PTR DS:[EDX+EAX]               ;依次取序列号每个字符
0047BAAE  |PUSH ECX
0047BAAF  |CALL test.0047BA00                         ;返回每个字符在base64码表中的位置
0047BAB4  |MOVSX ESI,BYTE PTR DS:[EAX+755D40]         ;取各个字符的对应的码值
0047BABB  |MOV EAX,6                                  ;设定循环6次,每次取最低一位值
0047BAC0  |POP ECX                                      
0047BAC1  |MOV ECX,EBX
0047BAC3  |MOV EDX,ESI
0047BAC5  |AND DL,1                                    ;取码值的最第一位值
0047BAC8  |AND ECX,7                                   ;判断循环是否够8位,够就组下一个8位
0047BACB  |SHL DL,CL                                   ;设定位置
0047BACD  |MOV ECX,EBX
0047BACF  |MOV EDI,DWORD PTR SS:[EBP+10]
0047BAD2  |SHR ECX,3
0047BAD5  |INC EBX                                     
0047BAD6  |SHR ESI,1                                   ;码值向右移动一位,
0047BAD8  |DEC EAX
0047BAD9  |OR BYTE PTR DS:[EDI+ECX],DL                 ;依次向内存中写入处理好的每一位的值
0047BADC  |CMP EBX,DWORD PTR SS:[EBP-8]
0047BADF   \JB SHORT test.0047BA9E
006B4AE6  PUSH ECX                                 ; /解码后的大小
006B4AE7  MOV EAX,DWORD PTR SS:[EBP-14]            ; |
006B4AEA  PUSH EAX                                 ; |解码后的地址
006B4AEB  MOV EDX,DWORD PTR SS:[EBP+C]             ; |
006B4AEE  PUSH EDX                                 ; |待解码长度
006B4AEF  MOV ECX,DWORD PTR SS:[EBP+8]             ; |
006B4AF2  PUSH ECX                                 ; |待解码地址
006B4AF3  MOV EAX,DWORD PTR SS:[EBP-8]             ; |
006B4AF6  PUSH EAX                                 ; |N 和E存储的地方
006B4AF7  CALL test.0069489C                       ; \test.0069489C

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 3
支持
分享
最新回复 (8)
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
看看能不能回复
信息
2015-7-22 18:04
0
雪    币: 262
活跃值: (183)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
思路很清晰
2015-7-22 21:44
0
雪    币: 764
活跃值: (147)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
!Very nice!
2015-7-23 00:10
0
雪    币: 7145
活跃值: (1150)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
分析得不错,学习了
2015-7-23 14:43
0
雪    币: 11
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
有点高深,多谢分享

请问下 我发的一款软件能否帮忙破解下呀,多谢
2015-7-23 17:28
0
雪    币: 627
活跃值: (663)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
7
恭喜楼主,基本搞定了。

关于你最后那个疑问,解释如下:
1024位的RSA,Modulus为0x80字节,加密/解密数据块也必须是0x80字节。如果数据长度超过0x80字节,按Block Cipher(分组加密/解密)处理。本例“用户名”长度基本不会超过0x80字节,就一个数据块。

Keygen过程:
1. 构造0x80字节数据块
[FONT="Courier"]/*
    License Format
    00, RegUserName, 00, 20, ...
*/[/FONT]
即这个数据块的开始部分为:'\0',用户名字符串,'\0';剩余部分用“空格”0x20填充(原程序是用空格填充,也可用其他字符填充,都没有关系)。
按这个格式,解密后用户名比较就是正确的。
2. RSA加密构造的数据块
3. 将此加密后的数据块Base64编码为RegSerialKey(“注册码”)

用我在 http://bbs.pediy.com/showpost.php?p=1376562&postcount=5 里提供的RegUserName/RegSerialKey,跟一下仅替换了N的主程序就清楚了。
2015-7-24 10:04
0
雪    币: 313
活跃值: (599)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
其实虚拟镜像文件可以解压缩安装的,但楼主为此也是够拼的
2015-7-26 18:41
0
雪    币: 41
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
根据楼主的分析,更换了N与e,接合M大神的分析,成功完成了注册机。
小结:一是如何定位 N e 位置;二是要分析透Base64是怎么变化的。
2015-12-15 17:55
0
游客
登录 | 注册 方可回帖
返回
//