【标题】Picture to Icon V1.918 注册算法分析
【作者】forever[RCT]
【语言】BC
【保护】aspack,注册码
【难度】简单
【简介】能将图片或屏幕的一部分转化为ICON图标,调整图标大小以及从资源库中提取icon。支持BMP, JPEG, GIF, CUR, WMF。
【下载】http://www6.skycn.com/soft/27005.html
【正文】
这篇帖子没什么技术含量,纯为练手所作。:)
peid查看aspack加壳。用UnAspack脱壳,发现不能运行。不过没关系,ida能分析就成。我主要是想用ida导出个map文件,这样在od中好分析。
用od加载程序,跟过壳的代码后用LoadMapEx加载从ida中导出的map文件。然后尝试着在注册窗口随便输入点什么,有提示了:
Your registration code is invalid. 呵呵,这个正是我想要的。在od中搜索字符串"Your",共有一次,双击这个字符串,来到CPU窗口。
见图:
向上翻,直到来到这里:
这个4210F0的call就是关键了,这里要下个断点。再次输入用户名和密码后来到下面:
004210F0 > 55 PUSH EBP ; sub_4210F0
004210F1 8BEC MOV EBP,ESP
004210F3 81C4 74FFFFFF ADD ESP,-8C
004210F9 56 PUSH ESI
004210FA 57 PUSH EDI
004210FB B8 C0285100 MOV EAX,<stru_5128C0>
00421100 E8 7B760C00 CALL <@__InitExceptBlockLDTC>
00421105 C745 F8 0100000>MOV DWORD PTR SS:[EBP-8],1
0042110C 8D55 08 LEA EDX,DWORD PTR SS:[EBP+8]
0042110F 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8]
00421112 E8 DD260D00 CALL <System::AnsiString::AnsiString(Sys>
00421117 FF45 F8 INC DWORD PTR SS:[EBP-8]
0042111A 66:C745 EC 0800 MOV WORD PTR SS:[EBP-14],8
00421120 C645 DB 00 MOV BYTE PTR SS:[EBP-25],0
00421124 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8]
00421127 E8 704AFEFF CALL <System::AnsiString::Length(void)>
0042112C 83F8 2C CMP EAX,2C ; 注册码长度是否44位
0042112F 0F85 3E020000 JNZ <loc_421373>
00421135 BE D6245100 MOV ESI,<a1z1h2a0n0g8y9a> ; ASCII "1z1h+2a0n-0g8y*9a1n|"
0042113A 8D7D 88 LEA EDI,DWORD PTR SS:[EBP-78]
0042113D B9 05000000 MOV ECX,5
00421142 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>
00421144 A4 MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
00421145 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8]
00421148 E8 2B10FEFF CALL <System::AnsiString::c_str(void)>
0042114D 0FBE50 28 MOVSX EDX,BYTE PTR DS:[EAX+28] ; 第41位是否等于50h
00421151 83FA 50 CMP EDX,50
00421154 74 23 JE SHORT <loc_421179>
00421156 33C0 XOR EAX,EAX
00421158 50 PUSH EAX
00421159 FF4D F8 DEC DWORD PTR SS:[EBP-8]
0042115C 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8]
0042115F BA 02000000 MOV EDX,2
00421164 E8 0B270D00 CALL <System::AnsiString::~AnsiString(vo>
00421169 58 POP EAX
0042116A 8B55 DC MOV EDX,DWORD PTR SS:[EBP-24]
0042116D 64:8915 0000000>MOV DWORD PTR FS:[0],EDX
00421174 E9 19020000 JMP <loc_421392>
00421179 > 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8] ; loc_421179
0042117C E8 F70FFEFF CALL <System::AnsiString::c_str(void)>
00421181 0FBE50 29 MOVSX EDX,BYTE PTR DS:[EAX+29]
00421185 83FA 32 CMP EDX,32 ; 第42位是否等于32h
00421188 74 23 JE SHORT <loc_4211AD>
0042118A 33C0 XOR EAX,EAX
0042118C 50 PUSH EAX
0042118D FF4D F8 DEC DWORD PTR SS:[EBP-8]
00421190 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8]
00421193 BA 02000000 MOV EDX,2
00421198 E8 D7260D00 CALL <System::AnsiString::~AnsiString(vo>
0042119D 58 POP EAX
0042119E 8B55 DC MOV EDX,DWORD PTR SS:[EBP-24]
004211A1 64:8915 0000000>MOV DWORD PTR FS:[0],EDX
004211A8 E9 E5010000 JMP <loc_421392>
004211AD > 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8] ; loc_4211AD
004211B0 E8 C30FFEFF CALL <System::AnsiString::c_str(void)>
004211B5 0FBE50 2A MOVSX EDX,BYTE PTR DS:[EAX+2A]
004211B9 83FA 49 CMP EDX,49 ; 第43位是否等于49h
004211BC 74 23 JE SHORT <loc_4211E1>
004211BE 33C0 XOR EAX,EAX
004211C0 50 PUSH EAX
004211C1 FF4D F8 DEC DWORD PTR SS:[EBP-8]
004211C4 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8]
004211C7 BA 02000000 MOV EDX,2
004211CC E8 A3260D00 CALL <System::AnsiString::~AnsiString(vo>
004211D1 58 POP EAX
004211D2 8B55 DC MOV EDX,DWORD PTR SS:[EBP-24]
004211D5 64:8915 0000000>MOV DWORD PTR FS:[0],EDX
004211DC E9 B1010000 JMP <loc_421392>
004211E1 > 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8] ; loc_4211E1
004211E4 E8 8F0FFEFF CALL <System::AnsiString::c_str(void)>
004211E9 0FBE50 2B MOVSX EDX,BYTE PTR DS:[EAX+2B]
004211ED 83FA 31 CMP EDX,31 ; 第44位是否等于31h
004211F0 74 23 JE SHORT <loc_421215>
004211F2 33C0 XOR EAX,EAX
004211F4 50 PUSH EAX
004211F5 FF4D F8 DEC DWORD PTR SS:[EBP-8]
004211F8 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8]
004211FB BA 02000000 MOV EDX,2
00421200 E8 6F260D00 CALL <System::AnsiString::~AnsiString(vo>
00421205 58 POP EAX
00421206 8B55 DC MOV EDX,DWORD PTR SS:[EBP-24]
00421209 64:8915 0000000>MOV DWORD PTR FS:[0],EDX
00421210 E9 7D010000 JMP <loc_421392>
00421215 > 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8] ; loc_421215
00421218 E8 5B0FFEFF CALL <System::AnsiString::c_str(void)>
0042121D 50 PUSH EAX
0042121E 8D55 A0 LEA EDX,DWORD PTR SS:[EBP-60]
00421221 52 PUSH EDX
00421222 E8 B5720C00 CALL <_strcpy>
00421227 83C4 08 ADD ESP,8
0042122A 0FBE4D A1 MOVSX ECX,BYTE PTR SS:[EBP-5F]
0042122E 83F9 30 CMP ECX,30 ; 第2位是否等于30h
00421231 0F85 3C010000 JNZ <loc_421373>
00421237 C645 A1 23 MOV BYTE PTR SS:[EBP-5F],23 ; 第2位替换成'#'
0042123B C645 DB 01 MOV BYTE PTR SS:[EBP-25],1
0042123F C745 D4 0200000>MOV DWORD PTR SS:[EBP-2C],2 ; 初始化索引
00421246 > 8B45 D4 MOV EAX,DWORD PTR SS:[EBP-2C]
00421249 0FBE5405 88 MOVSX EDX,BYTE PTR SS:[EBP+EAX-78] ; 取常量字符串中一个字符,位置3开始
0042124E 8B4D D4 MOV ECX,DWORD PTR SS:[EBP-2C]
00421251 0FBE440D 9F MOVSX EAX,BYTE PTR SS:[EBP+ECX-61] ; 取注册码中一个字符,位置2开始
00421256 03D0 ADD EDX,EAX ; 相加
00421258 8B4D D4 MOV ECX,DWORD PTR SS:[EBP-2C]
0042125B 0FBE440D A0 MOVSX EAX,BYTE PTR SS:[EBP+ECX-60] ; 取注册码中一个字符,位置3开始
00421260 33D0 XOR EDX,EAX ; 异或
00421262 8B4D D4 MOV ECX,DWORD PTR SS:[EBP-2C]
00421265 0FBE440D 88 MOVSX EAX,BYTE PTR SS:[EBP+ECX-78] ; 取常量字符串中一个字符,位置3开始
0042126A 33D0 XOR EDX,EAX ; 异或
0042126C 52 PUSH EDX
0042126D E8 26010000 CALL <sub_421398>
00421272 59 POP ECX
00421273 B9 1A000000 MOV ECX,1A
00421278 99 CDQ
00421279 F7F9 IDIV ECX ; 除以26
0042127B 83C2 41 ADD EDX,41 ; 加上'A'
0042127E 8B45 D4 MOV EAX,DWORD PTR SS:[EBP-2C]
00421281 0FBE4C05 A9 MOVSX ECX,BYTE PTR SS:[EBP+EAX-57] ; 和第12个字符开始比较
00421286 3BD1 CMP EDX,ECX
00421288 74 06 JE SHORT <loc_421290>
0042128A C645 DB 00 MOV BYTE PTR SS:[EBP-25],0
0042128E EB 09 JMP SHORT <loc_421299>
00421290 > FF45 D4 INC DWORD PTR SS:[EBP-2C] ; 索引加1
00421293 837D D4 0A CMP DWORD PTR SS:[EBP-2C],0A ; 循环10次
00421297 ^ 7C AD JL SHORT <loc_421246>
00421299 > 807D DB 00 CMP BYTE PTR SS:[EBP-25],0 ; loc_421299
0042129D 0F84 C3000000 JE <loc_421366>
004212A3 C745 D0 1800000>MOV DWORD PTR SS:[EBP-30],18
004212AA 66:C745 EC 0800 MOV WORD PTR SS:[EBP-14],8
004212B0 837D D0 28 CMP DWORD PTR SS:[EBP-30],28
004212B4 7D 4B JGE SHORT <loc_421301>
004212B6 > 8B55 D0 MOV EDX,DWORD PTR SS:[EBP-30] ; loc_4212B6
004212B9 0FBE4415 89 MOVSX EAX,BYTE PTR SS:[EBP+EDX-77] ; 取注册码中一个字符,第2个字符开始
004212BE B9 06000000 MOV ECX,6
004212C3 99 CDQ
004212C4 F7F9 IDIV ECX
004212C6 8BCA MOV ECX,EDX ; 模6
004212C8 8B45 D0 MOV EAX,DWORD PTR SS:[EBP-30]
004212CB 0FBE5405 8A MOVSX EDX,BYTE PTR SS:[EBP+EAX-76] ; 取注册码中一个字符,第3个字符开始
004212D0 D3E2 SHL EDX,CL ; 逻辑左移
004212D2 8B45 D0 MOV EAX,DWORD PTR SS:[EBP-30]
004212D5 0FBE4C05 8B MOVSX ECX,BYTE PTR SS:[EBP+EAX-75] ; 取注册码中一个字符,第4个字符开始
004212DA 0BD1 OR EDX,ECX ; 或
004212DC 52 PUSH EDX
004212DD E8 B6000000 CALL <sub_421398>
004212E2 59 POP ECX
004212E3 B9 1A000000 MOV ECX,1A
004212E8 99 CDQ
004212E9 F7F9 IDIV ECX ; 模26
004212EB 80C2 61 ADD DL,61 ; 加上'a'
004212EE 8B45 D0 MOV EAX,DWORD PTR SS:[EBP-30]
004212F1 889405 5CFFFFFF MOV BYTE PTR SS:[EBP+EAX-A4],DL ; 保存结果
004212F8 FF45 D0 INC DWORD PTR SS:[EBP-30]
004212FB 837D D0 28 CMP DWORD PTR SS:[EBP-30],28
004212FF ^ 7C B5 JL SHORT <loc_4212B6>
00421301 > C645 84 5A MOV BYTE PTR SS:[EBP-7C],5A ; loc_421301
00421305 C645 85 59 MOV BYTE PTR SS:[EBP-7B],59
00421309 C745 CC 1800000>MOV DWORD PTR SS:[EBP-34],18
00421310 66:C745 EC 0800 MOV WORD PTR SS:[EBP-14],8
00421316 837D CC 28 CMP DWORD PTR SS:[EBP-34],28
0042131A 7D 4A JGE SHORT <loc_421366>
0042131C > 8B55 CC MOV EDX,DWORD PTR SS:[EBP-34] ; loc_42131C
0042131F 0FBE8415 5CFFFF>MOVSX EAX,BYTE PTR SS:[EBP+EDX-A4] ; 上面保存的结果中取一个字符,第一个开始
00421327 C1E0 04 SHL EAX,4 ; 逻辑左移4位
0042132A 8B55 CC MOV EDX,DWORD PTR SS:[EBP-34]
0042132D 0FBE8C15 5DFFFF>MOVSX ECX,BYTE PTR SS:[EBP+EDX-A3] ; 上面保存的结果中取一个字符,第二个开始
00421335 D1F9 SAR ECX,1 ; 逻辑右移1位
00421337 33C1 XOR EAX,ECX ; 异或
00421339 50 PUSH EAX
0042133A E8 59000000 CALL <sub_421398>
0042133F 59 POP ECX
00421340 B9 1A000000 MOV ECX,1A
00421345 99 CDQ
00421346 F7F9 IDIV ECX ; 模26
00421348 83C2 41 ADD EDX,41 ; 加上'A'
0042134B 8B45 CC MOV EAX,DWORD PTR SS:[EBP-34]
0042134E 0FBE4405 A0 MOVSX EAX,BYTE PTR SS:[EBP+EAX-60] ; 取注册码中一个字符,第25个字符开始
00421353 3BD0 CMP EDX,EAX
00421355 74 06 JE SHORT <loc_42135D>
00421357 C645 DB 00 MOV BYTE PTR SS:[EBP-25],0
0042135B EB 09 JMP SHORT <loc_421366>
0042135D > FF45 CC INC DWORD PTR SS:[EBP-34] ; loc_42135D
00421360 837D CC 28 CMP DWORD PTR SS:[EBP-34],28
00421364 ^ 7C B6 JL SHORT <loc_42131C>
00421366 > 0FBE55 AA MOVSX EDX,BYTE PTR SS:[EBP-56] ; 取注册码第11个字符
0042136A 83FA 59 CMP EDX,59
0042136D 74 04 JE SHORT <loc_421373>
0042136F C645 DB 00 MOV BYTE PTR SS:[EBP-25],0
00421373 > 8A45 DB MOV AL,BYTE PTR SS:[EBP-25] ; loc_421373
00421376 50 PUSH EAX
00421377 FF4D F8 DEC DWORD PTR SS:[EBP-8]
0042137A 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8]
0042137D BA 02000000 MOV EDX,2
00421382 E8 ED240D00 CALL <System::AnsiString::~AnsiString(vo>
00421387 58 POP EAX
00421388 8B55 DC MOV EDX,DWORD PTR SS:[EBP-24]
0042138B 64:8915 0000000>MOV DWORD PTR FS:[0],EDX
00421392 > 5F POP EDI ; loc_421392
00421393 5E POP ESI
00421394 8BE5 MOV ESP,EBP
00421396 5D POP EBP
00421397 C3 RETN
00421398 > 55 PUSH EBP ; sub_421398
00421399 8BEC MOV EBP,ESP
0042139B 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
0042139E 99 CDQ
0042139F 33C2 XOR EAX,EDX
004213A1 2BC2 SUB EAX,EDX
004213A3 5D POP EBP
004213A4 C3 RETN
先总结一下上面:
int Veriry(unsigned char regcode[44])
{
const unsigned char c,str[] = "1z1h+2a0n-0g8y*9a1n|";
const unsigned char tmpstr[20] = {0};
int i;
if(strlen(regcode) != 44)return;
if(regcode[40] != 'P')return 0;
if(regcode[41] != '2')return 0;
if(regcode[42] != 'I')return 0;
if(regcode[43] != '1')return 0;
if(regcode[1] != '0')return 0;
regcode[1] = '#';
//检查regcode[11]-regcode[18]
for(i = 2; i < 10; i ++)
{
c = ((str[i] + regcode[i-1]) ^ regcode[i] ^ str[i]) % 26 + 'A';
if( c != regcode[i+10])return 0);
}
//生成一个临时字符串
for(i = 24; i < 40; i ++)
{
c = regcode[i-23] % 6;
tmpstr[i-24] = ((regcode[i-22] << c) | regcode[i-21]) % 26 + 'a';
}
tmpstr[i] = 0x5a;
tmpstr[i+1] = 0x59;
//检查regcode[24]-regcode[39]
for(i = 24; i < 40; i ++)
{
c = ((tmpstr[i-24] << 4) ^ (tmpstr[i-23] >> 1)) % 26 + 'A';
if(c != regcode[i])return 0;
}
//检查regcode[10]
if(regcode[10] != 0x59)return 0;
return 1;
}
这并没有完,仔细看第二个图,还有一处验证呢:
00422A4D 0FBE50 17 MOVSX EDX,BYTE PTR DS:[EAX+17] ; 取注册码第24个字符
00422A51 83FA 30 CMP EDX,30
00422A54 7C 16 JL SHORT <loc_422A6C> ; 小于'0'则失败
00422A56 8B45 A4 MOV EAX,DWORD PTR SS:[EBP-5C]
00422A59 05 20030000 ADD EAX,320
00422A5E E8 15F7FDFF CALL <System::AnsiString::c_str(void)>
00422A63 0FBE50 17 MOVSX EDX,BYTE PTR DS:[EAX+17]
00422A67 83FA 39 CMP EDX,39
00422A6A 7E 0F JLE SHORT <loc_422A7B> ; 大于'9'则失败
00422A6C > 8B0D FCAE5100 MOV ECX,DWORD PTR DS:[<off_51AEFC>] ; loc_422A6C
00422A72 8B01 MOV EAX,DWORD PTR DS:[ECX]
00422A74 C680 E4030000 0>MOV BYTE PTR DS:[EAX+3E4],0 ; 置失败标准
因此注册码验证还得加上一句:
(regcode[23] >= '0') && (regcode[23] <= '9')
到这里位置这个软件的注册部分就分析完了。:)
[完]
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课