【文章标题】: VOA单词通1.3注册算法分析(简单,适合新手)
【文章作者】: icow
【软件名称】: VOA单词通1.3
【软件大小】: 1.25M
【下载地址】: 华军软件园
【加壳方式】: 无壳
【保护方式】: 注册码
【编写语言】: Borland Delphi
【使用工具】: OD,WINDASM8.93+
【操作平台】: WIN98
【软件介绍】: 美国之音特别英语单词通
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
最近想练练听力,在华军软件园闲逛,看到这个软件,关于慢速英语基本单词学习的,有点意思就下了。
软件无壳,注册算法很简单,用了BASE64,非常适合新新手练兵。熟手就免了,不想浪费你们时间。。。
破解过程:
运行软件,点选项按钮进入可看到注册窗口,随便输入123456789,点注册,提示“注册失败”。WINDASM载入VOAWORDS.exe,字符串参考找“注册失败”,得到地址:00482291。
关闭WINDASM,Ollydbg载入VOAWORDS.EXE,来到00482291,往上翻,来到地址00482224,在这里F2设断点。随便输入1234567890,点注册断下:
00482224 /. 55 push ebp
00482225 |. 8BEC mov ebp, esp
00482227 |. 6A 00 push 0
00482229 |. 6A 00 push 0
0048222B |. 53 push ebx
0048222C |. 8BD8 mov ebx, eax
0048222E |. 33C0 xor eax, eax
00482230 |. 55 push ebp
00482231 |. 68 CE224800 push 004822CE
00482236 |. 64:FF30 push dword ptr fs:[eax]
00482239 |. 64:8920 mov fs:[eax], esp
0048223C |. 8D55 FC lea edx, [ebp-4]
0048223F |. 8B83 60030000 mov eax, [ebx+360]
00482245 |. E8 1E0BFCFF call 00442D68 ;取输入的伪注册码
0048224A |. 8B55 FC mov edx, [ebp-4]
0048224D |. 8BC3 mov eax, ebx
0048224F |. E8 2CFFFFFF call 00482180 ;关键CALL,F7跟进
00482254 |. 84C0 test al, al
00482256 |. 74 2A je short 00482282 ;AL为0则跳走,注册失败。
00482258 |. 8D55 F8 lea edx, [ebp-8]
0048225B |. 8B83 60030000 mov eax, [ebx+360]
00482261 |. E8 020BFCFF call 00442D68
00482266 |. 8B55 F8 mov edx, [ebp-8]
00482269 |. A1 50474800 mov eax, [484750]
0048226E |. 8B00 mov eax, [eax]
00482270 |. E8 BBEDFFFF call 00481030
00482275 |. 33D2 xor edx, edx
00482277 |. 8B83 64030000 mov eax, [ebx+364]
0048227D |. 8B08 mov ecx, [eax]
0048227F |. FF51 64 call [ecx+64]
00482282 |> 8B83 64030000 mov eax, [ebx+364]
00482288 |. 8B10 mov edx, [eax]
0048228A |. FF52 50 call [edx+50]
0048228D |. 84C0 test al, al
0048228F |. 74 12 je short 004822A3
00482291 |. BA E4224800 mov edx, 004822E4;“注册失败”
00482296 |. 8B83 68030000 mov eax, [ebx+368]
0048229C |. E8 F70AFCFF call 00442D98
004822A1 |. EB 10 jmp short 004822B3
004822A3 |> BA F8224800 mov edx, 004822F8;“注册成功”
004822A8 |. 8B83 68030000 mov eax, [ebx+368]
004822AE |. E8 E50AFCFF call 00442D98
004822B3 |> 33C0 xor eax, eax
004822B5 |. 5A pop edx
004822B6 |. 59 pop ecx
004822B7 |. 59 pop ecx
004822B8 |. 64:8910 mov fs:[eax], edx
004822BB |. 68 D5224800 push 004822D5
004822C0 |> 8D45 F8 lea eax, [ebp-8]
004822C3 |. BA 02000000 mov edx, 2
004822C8 |. E8 D724F8FF call 004047A4
004822CD \. C3 retn
004822CE .^ E9 B91EF8FF jmp 0040418C
004822D3 .^ EB EB jmp short 004822C0
004822D5 . 5B pop ebx
004822D6 . 59 pop ecx
004822D7 . 59 pop ecx
004822D8 . 5D pop ebp
004822D9 . C3 retn
从上面可知关健CALL 00482180是注册关键。
00482180 /$ 55 PUSH EBP
00482181 |. 8BEC MOV EBP,ESP
00482183 |. 33C9 XOR ECX,ECX
00482185 |. 51 PUSH ECX
00482186 |. 51 PUSH ECX
00482187 |. 51 PUSH ECX
00482188 |. 51 PUSH ECX
00482189 |. 53 PUSH EBX
0048218A |. 56 PUSH ESI
0048218B |. 8955 FC MOV DWORD PTR SS:[EBP-4],EDX ;伪注册码
0048218E |. 8BF0 MOV ESI,EAX
00482190 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
00482193 |. E8 982AF8FF CALL VOAWORDS.00404C30
00482198 |. 33C0 XOR EAX,EAX
0048219A |. 55 PUSH EBP
0048219B |. 68 12224800 PUSH VOAWORDS.00482212
004821A0 |. 64:FF30 PUSH DWORD PTR FS:[EAX]
004821A3 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
004821A6 |. 33DB XOR EBX,EBX
004821A8 |. 837D FC 00 CMP DWORD PTR SS:[EBP-4],0
004821AC |. 74 49 JE SHORT VOAWORDS.004821F7
004821AE |. 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8]
004821B1 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4];伪注册码
004821B4 |. E8 AB2EFEFF CALL VOAWORDS.00465064 ;BASE64解码函数
004821B9 |. 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8]
004821BC |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
004821BF |. E8 5426F8FF CALL VOAWORDS.00404818
004821C4 |. 8D4D F4 LEA ECX,DWORD PTR SS:[EBP-C]
004821C7 |. 66:BA D5DD MOV DX,0DDD5 ;0DDD5,初始密钥
004821CB |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4];指向BASE64解码输出BUFF1
004821CE |. E8 892FFEFF CALL VOAWORDS.0046515C;关键CALL,对上面BASE64解码进行加密。
004821D3 |. 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C]
004821D6 |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
004821D9 |. E8 3A26F8FF CALL VOAWORDS.00404818
004821DE |. 8D55 F0 LEA EDX,DWORD PTR SS:[EBP-10]
004821E1 |. 8BC6 MOV EAX,ESI
004821E3 |. E8 0CFFFFFF CALL VOAWORDS.004820F4;取机器码
004821E8 |. 8B55 F0 MOV EDX,DWORD PTR SS:[EBP-10];指向机器码
004821EB |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4];指向加密输出BUF2
004821EE |. E8 9929F8FF CALL VOAWORDS.00404B8C;比较
004821F3 |. 75 02 JNZ SHORT VOAWORDS.004821F7;不相等则跳出,注册失败。
004821F5 |. B3 01 MOV BL,1
004821F7 |> 33C0 XOR EAX,EAX
004821F9 |. 5A POP EDX
004821FA |. 59 POP ECX
004821FB |. 59 POP ECX
004821FC |. 64:8910 MOV DWORD PTR FS:[EAX],EDX
004821FF |. 68 19224800 PUSH VOAWORDS.00482219
00482204 |> 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10]
00482207 |. BA 04000000 MOV EDX,4
0048220C |. E8 9325F8FF CALL VOAWORDS.004047A4
00482211 \. C3 RETN
BASE64解码函数
00465064 $ 55 PUSH EBP
00465065 . 8BEC MOV EBP,ESP
00465067 . 83C4 F4 ADD ESP,-0C
0046506A . 8955 F8 MOV DWORD PTR SS:[EBP-8],EDX
0046506D . 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
00465070 . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
00465073 . E8 D0F9F9FF CALL VOAWORDS.00404A48;取注册码长度Len
00465078 . 85C0 TEST EAX,EAX
0046507A . 79 03 JNS SHORT VOAWORDS.0046507F
0046507C . 83C0 03 ADD EAX,3
0046507F > C1F8 02 SAR EAX,2;Len/4
00465082 . 8D1440 LEA EDX,DWORD PTR DS:[EAX+EAX*2];(len/4)*3
00465085 . 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00465088 . E8 3FFDF9FF CALL VOAWORDS.00404DCC;申请内存作为输出BUF1
0046508D . 33C0 XOR EAX,EAX
0046508F . 8945 F4 MOV DWORD PTR SS:[EBP-C],EAX
00465092 . 56 PUSH ESI
00465093 . 57 PUSH EDI
00465094 . 53 PUSH EBX
00465095 . 8B75 FC MOV ESI,DWORD PTR SS:[EBP-4];ESI指向伪注册码
00465098 . 8B7D F8 MOV EDI,DWORD PTR SS:[EBP-8];EDI指向输出BUF1
0046509B . 8B3F MOV EDI,DWORD PTR DS:[EDI]
0046509D . 09F6 OR ESI,ESI
0046509F . 0F84 A5000000 JE VOAWORDS.0046514A
004650A5 . 8B4E FC MOV ECX,DWORD PTR DS:[ESI-4]
004650A8 . C1E9 02 SHR ECX,2;伪注册码长度/4
004650AB . E3 5F JECXZ SHORT VOAWORDS.0046510C
004650AD . FC CLD
004650AE . EB 07 JMP SHORT VOAWORDS.004650B7
004650B0 > 49 DEC ECX
004650B1 . 0F84 93000000 JE VOAWORDS.0046514A;ECX为0则跳出循环
004650B7 > AD LODS DWORD PTR DS:[ESI];取伪注册码前四位个字节置于EAX
004650B8 . 32DB XOR BL,BL
004650BA . 31D2 XOR EDX,EDX
004650BC . E8 4D000000 CALL VOAWORDS.0046510E;对第一个字节AL查表,结果置于DL
004650C1 . C1E2 06 SHL EDX,6;左移六位
004650C4 . C1E8 08 SHR EAX,8;右移八位,将第二个字节送入AL
004650C7 . E8 42000000 CALL VOAWORDS.0046510E;对第二个字节AL查表,结果置于DL
004650CC . C1E2 06 SHL EDX,6
004650CF . C1E8 08 SHR EAX,8;右移八位,将第三个字节送入AL
004650D2 . E8 37000000 CALL VOAWORDS.0046510E;对第三个字节AL查表,结果置于DL
004650D7 . C1E2 06 SHL EDX,6
004650DA . C1E8 08 SHR EAX,8;右移八位,将第三个字节送入AL
004650DD . E8 2C000000 CALL VOAWORDS.0046510E;对第四个字节AL查表,结果置于DL
004650E2 . 08DB OR BL,BL
004650E4 .^74 CA JE SHORT VOAWORDS.004650B0
004650E6 . FECB DEC BL
004650E8 . 08DB OR BL,BL
004650EA .^74 C4 JE SHORT VOAWORDS.004650B0
004650EC . 89D0 MOV EAX,EDX
004650EE . 80FB 02 CMP BL,2
004650F1 . 7C 0B JL SHORT VOAWORDS.004650FE
004650F3 . C1C0 08 ROL EAX,8
004650F6 . 0FC8 BSWAP EAX;1和4,2和3字节对调
004650F8 . 66:AB STOS WORD PTR ES:[EDI];存入两个字节到[EDI]
004650FA . 8345 F4 02 ADD DWORD PTR SS:[EBP-C],2
004650FE > 80FB 02 CMP BL,2
00465101 .^74 AD JE SHORT VOAWORDS.004650B0
00465103 . C1E8 10 SHR EAX,10
00465106 . AA STOS BYTE PTR ES:[EDI];存入单字节到[EDI]
00465107 . FF45 F4 INC DWORD PTR SS:[EBP-C]
0046510A .^EB A4 JMP SHORT VOAWORDS.004650B0
BASE64的用到的CALL 46510E
0046510E /$ 3C 61 CMP AL,61
00465110 |. 7C 08 JL SHORT VOAWORDS.0046511A;小于61则转下一个处理。
00465112 |. 3C 7A CMP AL,7A
00465114 |. 7F 33 JG SHORT VOAWORDS.00465149;大于7A则无操作退出函数
00465116 |. 2C 47 SUB AL,47;小写字母(ASCII码:61~7A)则减去0x47
00465118 |. EB 2B JMP SHORT VOAWORDS.00465145
0046511A |> 3C 41 CMP AL,41 ; Switch (cases 2B..5A)
0046511C |. 7C 08 JL SHORT VOAWORDS.00465126 ;小于41则转下一个处理
0046511E |. 3C 5A CMP AL,5A
00465120 |. 7F 27 JG SHORT VOAWORDS.00465149;大于5A则无操作退出函数
00465122 |. 2C 41 SUB AL,41;大写字母(ASCII码:41~5A)则减去0x41
00465124 |. EB 1F JMP SHORT VOAWORDS.00465145
00465126 |> 3C 3D CMP AL,3D
00465128 |. 75 01 JNZ SHORT VOAWORDS.0046512B;若为‘=’则无操作退出
0046512A |. C3 RETN ; Case 3D ('=') of switch 0046511A
0046512B |> 3C 39 CMP AL,39
0046512D |. 7F 1A JG SHORT VOAWORDS.00465149;大于39则转下一个处理
0046512F |. 3C 30 CMP AL,30
00465131 |. 7C 04 JL SHORT VOAWORDS.00465137;小于30则转下一个处理
00465133 |. 04 04 ADD AL,4;数字(ASCII码:30~39)则加上4
00465135 |. EB 0E JMP SHORT VOAWORDS.00465145
00465137 |> 3C 2F CMP AL,2F
00465139 |. 75 04 JNZ SHORT VOAWORDS.0046513F
0046513B |. B0 3F MOV AL,3F ; ‘/’则用3F代替
0046513D |. EB 06 JMP SHORT VOAWORDS.00465145
0046513F |> 3C 2B CMP AL,2B
00465141 |. 75 06 JNZ SHORT VOAWORDS.00465149
00465143 |. B0 3E MOV AL,3E ; ‘+’则用3E代替
00465145 |> 08C2 OR DL,AL ; Cases 30 ('0'),31 ('1'),32 ('2'),33 ('3'),34 ('4'),35 ('5'),36 ('6'),37 ('7'),38 ('8'),39 ('9'),41 ('A'),42 ('B'),43 ('C'),44 ('D'),45 ('E'),46 ('F'),47 ('G'),48 ('H'),49 ('I'),4A ('J')... of switch 0046511A
00465147 |. FEC3 INC BL
00465149 \> C3 RETN ; Default case of switch 0046511A
看到上面这个函数完全可以确定CALL 00465064是BASE64解码函数。
CALL 0046515C 加密CALL
0046515C /$ 53 PUSH EBX
0046515D |. 56 PUSH ESI
0046515E |. 57 PUSH EDI
0046515F |. 55 PUSH EBP
00465160 |. 83C4 F8 ADD ESP,-8
00465163 |. 890C24 MOV DWORD PTR SS:[ESP],ECX
00465166 |. 8BF2 MOV ESI,EDX
00465168 |. 8BE8 MOV EBP,EAX;指向BASE64解码输出BUF1
0046516A |. 8BC5 MOV EAX,EBP
0046516C |. E8 D7F8F9FF CALL VOAWORDS.00404A48;取长度
00465171 |. 8BD0 MOV EDX,EAX
00465173 |. 8B0424 MOV EAX,DWORD PTR SS:[ESP]
00465176 |. E8 51FCF9FF CALL VOAWORDS.00404DCC;申请内存作为输出BUF2
0046517B |. 8BC5 MOV EAX,EBP
0046517D |. E8 C6F8F9FF CALL VOAWORDS.00404A48
00465182 |. 84C0 TEST AL,AL
00465184 |. 76 41 JBE SHORT VOAWORDS.004651C7
00465186 |. 884424 04 MOV BYTE PTR SS:[ESP+4],AL;BUF1长度
0046518A |. B3 01 MOV BL,1
0046518C |> 8B0424 /MOV EAX,DWORD PTR SS:[ESP];EAX指向输出BUF2
0046518F |. E8 04FBF9FF |CALL VOAWORDS.00404C98
00465194 |. 8BFB |MOV EDI,EBX
00465196 |. 81E7 FF000000 |AND EDI,0FF
0046519C |. 8A543D FF |MOV DL,BYTE PTR SS:[EBP+EDI-1];取BUF1中第EDI个字节送入DL
004651A0 |. 0FB7CE |MOVZX ECX,SI密钥扩充送入ECX
004651A3 |. C1E9 08 |SHR ECX,8;右移八位
004651A6 |. 32D1 |XOR DL,CL;密钥(字)高字节与D异或L
004651A8 |. 885438 FF |MOV BYTE PTR DS:[EAX+EDI-1],DL;结果送入BUF2
004651AC |. 33C0 |XOR EAX,EAX
004651AE |. 8A443D FF |MOV AL,BYTE PTR SS:[EBP+EDI-1];取BUF1中第EDI个字节送入AL
004651B2 |. 66:03F0 |ADD SI,AX;AL与密钥相加
004651B5 |. 66:69C6 6DCE |IMUL AX,SI,0CE6D;乘0CE6D送入AX
004651BA |. 66:05 BF58 |ADD AX,58BF;加
004651BE |. 8BF0 |MOV ESI,EAX;AX送入SI
004651C0 |. 43 |INC EBX
004651C1 |. FE4C24 04 |DEC BYTE PTR SS:[ESP+4]
004651C5 |.^75 C5 \JNZ SHORT VOAWORDS.0046518C
004651C7 |> 59 POP ECX
004651C8 |. 5A POP EDX
004651C9 |. 5D POP EBP
004651CA |. 5F POP EDI
004651CB |. 5E POP ESI
004651CC |. 5B POP EBX
004651CD \. C3 RETN
算法流程总结:
1。对输入的注册码(A~Z,a~z,0~9,+,/,=)进行BASE64解码,得到结果BUF1;
2。对BUF1进行加密(CALL46515C),得到结果BUF2;
3。BUF2=机器码则注册成功。
附注册机代码,在DEV C++4上测试通过。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//base64编码的实现
int Base64Enc(char *buf, unsigned char*text,int size)
{
static char *base64_encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int buflen = 0;
while(size>0)
{
*buf++ = base64_encoding[ (text[0] >> 2 ) & 0x3f];
if(size>2)
{
*buf++ = base64_encoding[((text[0] & 3) << 4) | (text[1] >> 4)];
*buf++ = base64_encoding[((text[1] & 0xF) << 2) | (text[2] >> 6)];
*buf++ = base64_encoding[text[2] & 0x3F];
}
else
{
switch(size)
{
case 1:
*buf++ = base64_encoding[(text[0] & 3) << 4 ];
*buf++ = '=';
*buf++ = '=';
break;
case 2:
*buf++ = base64_encoding[((text[0] & 3) << 4) | (text[1] >> 4)];
*buf++ = base64_encoding[((text[1] & 0x0F) << 2) | (text[2] >> 6)];
*buf++ = '=';
break;
}
}
text +=3;
size -=3;
buflen +=4;
}
*buf = 0;
return buflen;
}
void RegCodeCHG(unsigned char* buf,int Len,unsigned short ikey)
{
for(int i=0;i<Len;i++)
{
buf[i]^=(unsigned char)(ikey>>8);
ikey+=buf[i];
ikey*=0xCE6D;
ikey+=0x58BF;
}
}
int main(int argc, char *argv[])
{
char regCode[255];
unsigned char macCode[255];
if( argc != 2 )
{
printf("Usage:VoaReg MachineCode\n");
system("pause");
return 0;
}
int macLen=strlen(argv[1]);
for(int i=0;i<macLen;i++)
{
macCode[i]=(unsigned char)argv[1][i];
}
RegCodeCHG(macCode,macLen,0xDDD5);
int regLen=Base64Enc(regCode,macCode,macLen);
printf("\nRegCode:");
for(int i=0;i<regLen;i++)
{
printf("%c",regCode[i]);
}
printf("\n");
system("pause");
return 0;
}
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2006年06月01日 23:37:49
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)