【文章标题】source insight 3.50.0076分析
【文章作者】lacoucou
【软件名称】source insight version 3.50.0076 - Feb 19, 2015
【软件大小】6 MB 左右
【原版下载】http://www.sourceinsight.com/down35.html
【保护方式】序列号
【软件简介】主要就是看代码了
【作者声明】本文仅供研究学习,本人对因这篇文章而导致的一切后果,不承担任何法律责任。本文中的不足之处请各位多多指教。
【分析过程】
1.用错误字符串找到关键函数。过程就不说了。不过这次用ODv2.0搜索的感觉挺好用!!
关键函数:
00448E94 /$ 55 PUSH EBP ; 注册
00448E95 |. 8BEC MOV EBP,ESP
00448E97 |. 83EC 0C SUB ESP,0C
00448E9A |. C745 FC 7C5A5 MOV DWORD PTR SS:[LOCAL.1],OFFSET 005E5A
00448EA1 |. 8365 F8 00 AND DWORD PTR SS:[LOCAL.2],00000000
00448EA5 |. EB 07 JMP SHORT 00448EAE
00448EA7 |> 8B45 F8 /MOV EAX,DWORD PTR SS:[LOCAL.2]
00448EAA |. 40 |INC EAX
00448EAB |. 8945 F8 |MOV DWORD PTR SS:[LOCAL.2],EAX
00448EAE |> 837D F8 04 |CMP DWORD PTR SS:[LOCAL.2],4
00448EB2 |. 0F8D 5B010000 |JGE 00449013
00448EB8 |. 8025 7C5A5E00 |AND BYTE PTR DS:[5E5A7C],00
00448EBF |. 8D45 FC |LEA EAX,[LOCAL.1]
00448EC2 |. 50 |PUSH EAX ; /Arg3 => OFFSET LOCAL.1
00448EC3 |. 68 64010000 |PUSH 164 ; |Arg2 = 164
00448EC8 |. 68 F0D15300 |PUSH OFFSET 0053D1F0 ; |Arg1 = Insight3.53D1F0
00448ECD |. E8 9097FBFF |CALL 00402662 ; \Insight3.00402662
00448ED2 |. 8945 F4 |MOV DWORD PTR SS:[LOCAL.3],EAX
00448ED5 |. 837D F4 02 |CMP DWORD PTR SS:[LOCAL.3],2
00448ED9 |. 74 11 |JE SHORT 00448EEC
00448EDB |. 837D F4 01 |CMP DWORD PTR SS:[LOCAL.3],1
00448EDF |. 75 27 |JNE SHORT 00448F08
00448EE1 |. 0FB605 7C5A5E |MOVZX EAX,BYTE PTR DS:[5E5A7C]
00448EE8 |. 85C0 |TEST EAX,EAX
00448EEA |. 75 1C |JNZ SHORT 00448F08
00448EEC |> 68 78EC5300 |PUSH OFFSET 0053EC78 ; /Format = "You must enter a valid serial number to continue. Do you want to try again?"
00448EF1 |. E8 8AEEFBFF |CALL 00407D80 ; \Insight3.00407D80
00448EF6 |. 59 |POP ECX
00448EF7 |. 85C0 |TEST EAX,EAX
00448EF9 |. 75 07 |JNZ SHORT 00448F02
00448EFB |. 33C0 |XOR EAX,EAX
00448EFD |. E9 13010000 |JMP 00449015
00448F02 |> 8365 F8 00 |AND DWORD PTR SS:[LOCAL.2],00000000
00448F06 |.^ EB 9F |JMP SHORT 00448EA7
00448F08 |> 837D F4 15 |CMP DWORD PTR SS:[LOCAL.3],15
00448F0C |. 75 20 |JNE SHORT 00448F2E
00448F0E |. 68 C8EC5300 |PUSH OFFSET 0053ECC8 ; /Format = "Your Internet browser will now open and navigate to the Source Dynamics web site."
00448F13 |. E8 78F0FBFF |CALL 00407F90 ; \Insight3.00407F90
00448F18 |. 59 |POP ECX
00448F19 |. 6A 01 |PUSH 1 ; /Arg2 = 1
00448F1B |. 68 1CED5300 |PUSH OFFSET 0053ED1C ; |Arg1 = ASCII "http://www.sourceinsight.com/buyit.htm"
00448F20 |. E8 99020000 |CALL 004491BE ; \Insight3.004491BE
00448F25 |. 8365 F8 00 |AND DWORD PTR SS:[LOCAL.2],00000000
00448F29 |.^ E9 79FFFFFF |JMP 00448EA7
00448F2E |> 837D F4 14 |CMP DWORD PTR SS:[LOCAL.3],14
00448F32 |. 75 51 |JNE SHORT 00448F85
00448F34 |. 8025 7C5A5E00 |AND BYTE PTR DS:[5E5A7C],00
00448F3B |. 837D 08 00 |CMP DWORD PTR SS:[ARG.1],0
00448F3F |. 74 18 |JE SHORT 00448F59
00448F41 |. 68 44ED5300 |PUSH OFFSET 0053ED44 ; /Format = "You have indicated that you want to use a Trial License, which is good for 30 days. Is that correct?"
00448F46 |. E8 35EEFBFF |CALL 00407D80 ; \Insight3.00407D80
00448F4B |. 59 |POP ECX
00448F4C |. 85C0 |TEST EAX,EAX
00448F4E |. 75 09 |JNZ SHORT 00448F59
00448F50 |. 8365 F8 00 |AND DWORD PTR SS:[LOCAL.2],00000000
00448F54 |.^ E9 4EFFFFFF |JMP 00448EA7
00448F59 |> 68 7C5A5E00 |PUSH OFFSET 005E5A7C ; /Arg3 = Insight3.5E5A7C
00448F5E |. 68 50D05B00 |PUSH OFFSET 005BD050 ; |Arg2 = ASCII "SerialNumber"
00448F63 |. FF35 BC925C00 |PUSH DWORD PTR DS:[5C92BC] ; |Arg1 = 0
00448F69 |. E8 07AEFEFF |CALL 00433D75 ; \Insight3.00433D75
00448F6E |. C705 7C5D5E00 |MOV DWORD PTR DS:[5E5D7C],1
00448F78 |. E8 7BB9FFFF |CALL 004448F8 ; [Insight3.004448F8
00448F7D |. 6A 01 |PUSH 1
00448F7F |. 58 |POP EAX
00448F80 |. E9 90000000 |JMP 00449015
00448F85 |> 68 7C5A5E00 |PUSH OFFSET 005E5A7C ; /Arg1 = Insight3.5E5A7C
00448F8A |. E8 B33BFFFF |CALL 0043CB42 ; \Insight3.0043CB42
00448F8F |. 68 7C5A5E00 |PUSH OFFSET 005E5A7C ; /Arg1 = Insight3.5E5A7C
00448F94 |. E8 05570D00 |CALL 0051E69E ; \Insight3.0051E69E
00448F99 |. 59 |POP ECX
00448F9A |. 68 7C5A5E00 |PUSH OFFSET 005E5A7C ; /Arg1 = Insight3.5E5A7C
00448F9F |. E8 59030000 |CALL 004492FD ; \Insight3.004492FD
00448FA4 |. 85C0 |TEST EAX,EAX ; eax必须为1
00448FA6 |. 74 50 |JZ SHORT 00448FF8
00448FA8 |. 68 7C5A5E00 |PUSH OFFSET 005E5A7C ; /Arg3 = Insight3.5E5A7C
00448FAD |. 68 50D05B00 |PUSH OFFSET 005BD050 ; |Arg2 = ASCII "SerialNumber"
00448FB2 |. FF35 BC925C00 |PUSH DWORD PTR DS:[5C92BC] ; |Arg1 = 0
00448FB8 |. E8 B8ADFEFF |CALL 00433D75 ; \Insight3.00433D75
00448FBD |. 85C0 |TEST EAX,EAX
00448FBF |. 75 1B |JNZ SHORT 00448FDC
00448FC1 |. 68 ACED5300 |PUSH OFFSET 0053EDAC ; /Format = "You need permission to modify the HKEY_LOCAL_MACHINE registry hive.
Please run Source Insight again while logged in as an Administrator or equivalent user."
00448FC6 |. E8 93EEFBFF |CALL 00407E5E ; \Insight3.00407E5E
00448FCB |. 59 |POP ECX
00448FCC |. 68 E8030000 |PUSH 3E8 ; /Time = 1000. ms
00448FD1 |. FF15 E4925200 |CALL DWORD PTR DS:[<&KERNEL32.Sleep>] ; \KERNEL32.Sleep
00448FD7 |.^ E9 CBFEFFFF |JMP 00448EA7
00448FDC |> 8325 645A5E00 |AND DWORD PTR DS:[5E5A64],00000000
00448FE3 |. E8 10B9FFFF |CALL 004448F8 ; [Insight3.004448F8
00448FE8 |. 68 4CEE5300 |PUSH OFFSET 0053EE4C ; /Format = "Thank you for registering Source Insight!"
00448FED |. E8 9EEFFBFF |CALL 00407F90 ; \Insight3.00407F90
00448FF2 |. 59 |POP ECX
00448FF3 |. 6A 01 |PUSH 1
00448FF5 |. 58 |POP EAX
00448FF6 |. EB 1D |JMP SHORT 00449015
00448FF8 |> 68 78EE5300 |PUSH OFFSET 0053EE78 ; /Format = "You typed an invalid serial number."
00448FFD |. E8 5CEEFBFF |CALL 00407E5E ; \Insight3.00407E5E
00449002 |. 59 |POP ECX
00449003 |. 68 E8030000 |PUSH 3E8 ; /Time = 1000. ms
00449008 |. FF15 E4925200 |CALL DWORD PTR DS:[<&KERNEL32.Sleep>] ; \KERNEL32.Sleep
0044900E |.^ E9 94FEFFFF \JMP 00448EA7
00449013 |> 33C0 XOR EAX,EAX
00449015 |> C9 LEAVE
00449016 \. C2 0400 RETN 4
这个函数OD已经注释的很明白了,就不说了。
验证注册码的函数是 sub_004492FD
地址 HEX 数据 指令 注释
004492FD /$ 55 PUSH EBP ; 验证算法?
004492FE |. 8BEC MOV EBP,ESP
00449300 |. FF75 08 PUSH DWORD PTR SS:[ARG.1] ; /Arg1 => [ARG.1]
00449303 |. E8 11FFFFFF CALL IsEquel_ES3US ; \Insight3.IsEquel_ES3US, 验证第一段是否是ES3US
00449308 |. 85C0 TEST EAX,EAX
0044930A |. 74 0A JZ SHORT 00449316
0044930C |. FF75 08 PUSH DWORD PTR SS:[ARG.1] ; /Arg1 => [ARG.1]
0044930F |. E8 E2000000 CALL 004493F6 ; \Insight3.004493F6, 可能是混淆算法
00449314 |. EB 08 JMP SHORT 0044931E
00449316 |> FF75 08 PUSH DWORD PTR SS:[ARG.1] ; /Arg1 => [ARG.1]
00449319 |. E8 04000000 CALL 00449322 ; \Insight3.00449322, 真正验证注册码的算法
0044931E |> 5D POP EBP
0044931F \. C2 0400 RETN 4
这个函数是一个简单的双分支结构。
第一个函数用来判断注册码前5个字节是否是ES3US,是的话返回1,不是返回0
返回1进入第二个函数:sub_004493F6
返回0进入第三个函数:sub_00449322
先来说说sub_004493F6这个巨坑的函数:
地址 HEX 数据 指令 注释
004493F6 /$ 55 PUSH EBP ; Insight3.004493F6(guessed Arg1
004493F7 |. 8BEC MOV EBP,ESP
004493F9 |. 81EC 08010000 SUB ESP,108
004493FF |. 68 60EF5300 PUSH OFFSET 0053EF60 ; /Arg1 = ASCII "ES3US"
00449404 |. E8 D73B0D00 CALL strlen ; \Insight3.strlen
00449409 |. 59 POP ECX
0044940A |. 50 PUSH EAX ; /Arg3
0044940B |. 68 68EF5300 PUSH OFFSET 0053EF68 ; |Arg2 = ASCII "ES3US"
00449410 |. FF75 08 PUSH DWORD PTR SS:[ARG.1] ; |Arg1 => [ARG.1]
00449413 |. E8 2EB2FCFF CALL memcmp ; \Insight3.memcmp
00449418 |. 85C0 TEST EAX,EAX
0044941A |. 75 04 JNZ SHORT 00449420
0044941C |. 33C0 XOR EAX,EAX
0044941E |. EB 53 JMP SHORT 00449473
00449420 |> 8D45 FC LEA EAX,[LOCAL.1]
00449423 |. 50 PUSH EAX ; /Arg3 => OFFSET LOCAL.1, 1
00449424 |. 8D85 F8FEFFFF LEA EAX,[LOCAL.66] ; |
0044942A |. 50 PUSH EAX ; |Arg2 => OFFSET LOCAL.66, 0
0044942B |. FF75 08 PUSH DWORD PTR SS:[ARG.1] ; |Arg1 => [ARG.1]
0044942E |. E8 11FEFFFF CALL PraseSerialNumber ; \Insight3.PraseSerialNumber, 检查注册码是否是三段式类似es3us-xxxxxx-yyyyy xxxxxx段必须为六位 将这段拷到参数2的缓冲区 yyyyy段必须是5位 将这个字符串转为数字放入参数3中
00449433 |. 85C0 TEST EAX,EAX
00449435 |. 74 04 JZ SHORT 0044943B
00449437 |. 33C0 XOR EAX,EAX
00449439 |. EB 38 JMP SHORT 00449473
0044943B |> FFB5 F8FEFFFF PUSH DWORD PTR SS:[LOCAL.6 ; /Arg2 => [LOCAL.66]
00449441 |. 8D85 F8FEFFFF LEA EAX,[LOCAL.66] ; |
00449447 |. 50 PUSH EAX ; |Arg1 => OFFSET LOCAL.66
00449448 |. E8 72FAFDFF CALL 00428EBF ; \Insight3.00428EBF
0044944D |. 85C0 TEST EAX,EAX ; 不能为0
0044944F |. 74 04 JZ SHORT 00449455
00449451 |. 33C0 XOR EAX,EAX
00449453 |. EB 1E JMP SHORT 00449473
00449455 |> 8D85 F8FEFFFF LEA EAX,[LOCAL.66]
0044945B |. 50 PUSH EAX ; /Arg1 => OFFSET LOCAL.66
0044945C |. E8 C0B00A00 CALL 004F4521 ; \Insight3.004F4521
00449461 |. 8945 F8 MOV DWORD PTR SS:[LOCAL.2]
00449464 |. 8B45 FC MOV EAX,DWORD PTR SS:[LOCA
00449467 |. 3B45 F8 CMP EAX,DWORD PTR SS:[LOCA
0044946A |. 74 04 JE SHORT 00449470
0044946C |. 33C0 XOR EAX,EAX
0044946E |. EB 03 JMP SHORT 00449473
00449470 |> 6A 01 PUSH 1
00449472 |. 58 POP EAX
00449473 |> C9 LEAVE
00449474 \. C2 0400 RETN 4
这个函数主要流程。
1.先判断注册码的前五个字节是不是"ES3US" 不是就返回0 是就继续
2.接下来这个被我命名为PraseSerialNumber 参数有三个
参数1.我们的注册码 【in】
参数2.一个字符串缓冲区 【out】
参数3.整形缓冲区 [out]
根据这个函数的内容,我猜测注册码大概是ES3US-XXXXXX-YYYYY这样的形式。用‘-’把注册码分成三段,第一段是固定的形式,第二段是一个6位的字符串,第三段是一个5为的字符串。满足这样的格式,就会返回1,并且把中间的六位拷贝到参数2的缓冲区,把后五位利用atoi函数转换成整形并把值放在参数3里边。
贴下代码:
CPU Disasm
地址 HEX 数据 指令 注释
00449244 PraseSerialNumber /$ 55 PUSH EBP ; Insight3.PraseSerialNumber(guessed Arg1,Arg2,Arg3
00449245 |. 8BEC MOV EBP,ESP
00449247 |. 83EC 10 SUB ESP,10
0044924A |. 56 PUSH ESI
0044924B |. 6A 2D PUSH 2D ; /Arg2 = 2D
0044924D |. FF75 08 PUSH DWORD PTR SS:[ARG.1] ; |Arg1 => [ARG.1]
00449250 |. E8 9B430D00 CALL strchr ; \Insight3.strchr, char *strchr(char* _Str,int _Ch)
00449255 |. 59 POP ECX
00449256 |. 59 POP ECX
00449257 |. 8945 FC MOV DWORD PTR SS:[LOCAL.1]
0044925A |. 837D FC 00 CMP DWORD PTR SS:[LOCAL.1] ; 比较是否有-
0044925E |. 75 07 JNE SHORT 00449267
00449260 |. 33C0 XOR EAX,EAX
00449262 |. E9 91000000 JMP 004492F8
00449267 |> 8B75 FC MOV ESI,DWORD PTR SS:[LOCA
0044926A |. 2B75 08 SUB ESI,DWORD PTR SS:[ARG. ; 计算第一个‘-’之前字符串长度
0044926D |. 68 50815A00 PUSH OFFSET 005A8150 ; /Arg1 = ASCII "SI3US"
00449272 |. E8 693D0D00 CALL strlen ; \Insight3.strlen
00449277 |. 59 POP ECX
00449278 |. 3BF0 CMP ESI,EAX ; 比较第一串是否等于 si3us
0044927A |. 74 04 JE SHORT 00449280
0044927C |. 33C0 XOR EAX,EAX
0044927E |. EB 78 JMP SHORT 004492F8
00449280 |> 8B45 FC MOV EAX,DWORD PTR SS:[LOCA
00449283 |. 40 INC EAX ; 跳过-
00449284 |. 8945 FC MOV DWORD PTR SS:[LOCAL.1]
00449287 |. 8B45 FC MOV EAX,DWORD PTR SS:[LOCA
0044928A |. 8945 F4 MOV DWORD PTR SS:[LOCAL.3]
0044928D |. 6A 2D PUSH 2D ; /Arg2 = 2D
0044928F |. FF75 FC PUSH DWORD PTR SS:[LOCAL.1 ; |Arg1 => [LOCAL.1]
00449292 |. E8 59430D00 CALL strchr ; \Insight3.strchr, 找第二个‘-’
00449297 |. 59 POP ECX
00449298 |. 59 POP ECX
00449299 |. 8945 F0 MOV DWORD PTR SS:[LOCAL.4]
0044929C |. 837D F0 00 CMP DWORD PTR SS:[LOCAL.4]
004492A0 |. 75 04 JNE SHORT 004492A6
004492A2 |. 33C0 XOR EAX,EAX
004492A4 |. EB 52 JMP SHORT 004492F8
004492A6 |> 8B45 F0 MOV EAX,DWORD PTR SS:[LOCA
004492A9 |. 8020 00 AND BYTE PTR DS:[EAX],00 ; 清除2d('-')
004492AC |. 8B45 F0 MOV EAX,DWORD PTR SS:[LOCA ; es3us-xxx1-xxx2
004492AF |. 2B45 F4 SUB EAX,DWORD PTR SS:[LOCA
004492B2 |. 83F8 06 CMP EAX,6 ; 比较xxx1的长度是否是6位
004492B5 |. 74 04 JE SHORT 004492BB
004492B7 |. 33C0 XOR EAX,EAX
004492B9 |. EB 3D JMP SHORT 004492F8
004492BB |> FF75 F4 PUSH DWORD PTR SS:[LOCAL.3
004492BE |. FF75 0C PUSH DWORD PTR SS:[ARG.2]
004492C1 |. E8 0A3E0D00 CALL strcpy ; strcpy(arg.2,xxx1) 把中间一段拷到参数2的缓冲区
004492C6 |. 59 POP ECX
004492C7 |. 59 POP ECX
004492C8 |. 8B45 F0 MOV EAX,DWORD PTR SS:[LOCA
004492CB |. 40 INC EAX
004492CC |. 8945 F8 MOV DWORD PTR SS:[LOCAL.2]
004492CF |. FF75 F8 PUSH DWORD PTR SS:[LOCAL.2 ; /Arg1 => [LOCAL.2]
004492D2 |. E8 093D0D00 CALL strlen ; \Insight3.strlen
004492D7 |. 59 POP ECX
004492D8 |. 83F8 05 CMP EAX,5 ; 看xxx2段是否是五位
004492DB |. 74 04 JE SHORT 004492E1
004492DD |. 33C0 XOR EAX,EAX
004492DF |. EB 17 JMP SHORT 004492F8
004492E1 |> FF75 F8 PUSH DWORD PTR SS:[LOCAL.2 ; /Arg1 => [LOCAL.2]
004492E4 |. E8 E9420D00 CALL atoi ; \Insight3.atoi
004492E9 |. 59 POP ECX
004492EA |. 8B4D 10 MOV ECX,DWORD PTR SS:[ARG.
004492ED |. 8901 MOV DWORD PTR DS:[ECX],EAX
004492EF |. 8B45 F0 MOV EAX,DWORD PTR SS:[LOCA
004492F2 |. C600 2D MOV BYTE PTR DS:[EAX],2D
004492F5 |. 6A 01 PUSH 1
004492F7 |. 58 POP EAX
004492F8 |> 5E POP ESI
004492F9 |. C9 LEAVE
004492FA \. C2 0C00 RETN 0C
当然这个算法逗比的地方就在下边,如果注册码满足ES3US-XXXXXX-YYYYY的话,这里就直接跳走了。
3.不过还是看下下边的两个函数。
Sub_00428EBF 这个让人摸不着头脑。IDA出来是下边这样参数1是注册码中间一段字符串的前4位转int 参数2是中间那段
BOOL __stdcall sub_428EBF(int a1, unsigned __int8 a2)
{
while ( *(_BYTE *)a1 == a2 && *(_BYTE *)a1 )
++a1;
return *(_BYTE *)a1 == 0;
}
下一个的函数:
CPU Disasm
地址 HEX 数据 指令 注释
004F4521 /$ 55 PUSH EBP ; Insight3.004F4521(guessed Arg1
004F4522 |. 8BEC MOV EBP,ESP
004F4524 |. 83EC 10 SUB ESP,10
004F4527 |. 56 PUSH ESI
004F4528 |. FF75 08 PUSH DWORD PTR SS:[ARG.1] ; /Arg1 => [ARG.1]
004F452B |. E8 A2900200 CALL atoi ; \Insight3.atoi
004F4530 |. 59 POP ECX
004F4531 |. 8945 F4 MOV DWORD PTR SS:[LOCAL.3],EAX
004F4534 |. C745 F0 7F000 MOV DWORD PTR SS:[LOCAL.4],7F
004F453B |. 8B45 F4 MOV EAX,DWORD PTR SS:[LOCAL.3]
004F453E |. 8945 FC MOV DWORD PTR SS:[LOCAL.1],EAX
004F4541 |. 8B45 08 MOV EAX,DWORD PTR SS:[ARG.1]
004F4544 |. 8945 F8 MOV DWORD PTR SS:[LOCAL.2],EAX
004F4547 |. EB 07 JMP SHORT 004F4550
004F4549 |> 8B45 F8 /MOV EAX,DWORD PTR SS:[LOCAL.2]
004F454C |. 40 |INC EAX
004F454D |. 8945 F8 |MOV DWORD PTR SS:[LOCAL.2],EAX
004F4550 |> 8B45 F8 |MOV EAX,DWORD PTR SS:[LOCAL.2]
004F4553 |. 0FB600 |MOVZX EAX,BYTE PTR DS:[EAX]
004F4556 |. 85C0 |TEST EAX,EAX
004F4558 |. 74 24 |JZ SHORT 004F457E
004F455A |. 8B4D FC |MOV ECX,DWORD PTR SS:[LOCAL.1]
004F455D |. C1E1 04 |SHL ECX,4
004F4560 |. 8B45 F8 |MOV EAX,DWORD PTR SS:[LOCAL.2]
004F4563 |. 0FB630 |MOVZX ESI,BYTE PTR DS:[EAX]
004F4566 |. 8B45 F8 |MOV EAX,DWORD PTR SS:[LOCAL.2]
004F4569 |. 0FB600 |MOVZX EAX,BYTE PTR DS:[EAX]
004F456C |. 99 |CDQ
004F456D |. F77D F0 |IDIV DWORD PTR SS:[LOCAL.4]
004F4570 |. 030C95 80815A |ADD ECX,DWORD PTR DS:[EDX*4+5A81
004F4577 |. 03F1 |ADD ESI,ECX
004F4579 |. 8975 FC |MOV DWORD PTR SS:[LOCAL.1],ESI
004F457C |.^ EB CB \JMP SHORT 004F4549
004F457E |> 8B45 FC MOV EAX,DWORD PTR SS:[LOCAL.1]
004F4581 |. 33D2 XOR EDX,EDX
004F4583 |. B9 A0860100 MOV ECX,186A0
004F4588 |. F7F1 DIV ECX
004F458A |. 8BC2 MOV EAX,EDX
004F458C |. 5E POP ESI
004F458D |. C9 LEAVE
004F458E \. C2 0400 RETN 4
还原成C代码:
//注册码样式 es3us-123456-777777 根据中间一段的字符串生成第三段的数值 返回1才行
int CSource_insight_kengenDlg::CalaSeg3(char *pSeg2)
{
int nSeg2 = atoi(pSeg2);
char *pSz=pSeg2;
DWORD* dwAry=(DWORD*)data; //data是一个全局int数组总共127个元素在虚拟地址5a8180处 文件1a8180处
while(*pSz!=0)
{
nSeg2=dwAry[*pSz%127]+16*nSeg2+*pSz;
pSz++;
}
return nSeg2 % 0x186A0u;
}
函数的最后就是比较PraseSerialNumber的第三个参数和CalaSeg3返回的结果是否相等。相等返回1就成功了。
不过这个函数逻辑比较奇葩不知到怎么才能产生这种结果。
如果注册码是ES3US-XXXXXX-YYYYY的话PraseSerialNumber返回之后就结束了。
把注册码改成ES3US-XXXXXX-YYYYYY(6个Y)就要CalaSeg3返回的结果为1才能成功,是在不知道怎么拼凑,就先放放吧。
下边再说真正验证注册码的函数。
sub_00449322
CPU Disasm
地址 HEX 数据 指令 注释
00449322 /$ 55 PUSH EBP ; Insight3.00449322(guessed Arg1
00449323 |. 8BEC MOV EBP,ESP
00449325 |. 81EC 10010000 SUB ESP,110
0044932B |. 68 50815A00 PUSH OFFSET 005A8150 ; /Arg1 = ASCII "SI3US"
00449330 |. E8 AB3C0D00 CALL strlen ; \Insight3.strlen
00449335 |. 59 POP ECX
00449336 |. 50 PUSH EAX ; /Arg3
00449337 |. 68 50815A00 PUSH OFFSET 005A8150 ; |Arg2 = ASCII "SI3US"
0044933C |. FF75 08 PUSH DWORD PTR SS:[ARG.1] ; |Arg1 => [ARG.1]
0044933F |. E8 02B3FCFF CALL memcmp ; \Insight3.memcmp
00449344 |. 85C0 TEST EAX,EAX
00449346 |. 75 07 JNZ SHORT 0044934F
00449348 |. 33C0 XOR EAX,EAX
0044934A |. E9 A3000000 JMP 004493F2
0044934F |> 8D45 FC LEA EAX,[LOCAL.1]
00449352 |. 50 PUSH EAX ; /Arg3 => OFFSET LOCAL.1
00449353 |. 8D85 F8FEFFFF LEA EAX,[LOCAL.66] ; |
00449359 |. 50 PUSH EAX ; |Arg2 => OFFSET LOCAL.66
0044935A |. FF75 08 PUSH DWORD PTR SS:[ARG.1] ; |Arg1 => [ARG.1]
0044935D |. E8 E2FEFFFF CALL PraseSerialNumber ; \Insight3.PraseSerialNumber
00449362 |. 85C0 TEST EAX,EAX
00449364 |. 75 07 JNZ SHORT 0044936D
00449366 |. 33C0 XOR EAX,EAX
00449368 |. E9 85000000 JMP 004493F2
0044936D |> FFB5 F8FEFFFF PUSH DWORD PTR SS:[LOCAL.66] ; /Arg2 => [LOCAL.66]
00449373 |. 8D85 F8FEFFFF LEA EAX,[LOCAL.66] ; |
00449379 |. 50 PUSH EAX ; |Arg1 => OFFSET LOCAL.66
0044937A |. E8 40FBFDFF CALL 00428EBF ; \Insight3.00428EBF
0044937F |. 85C0 TEST EAX,EAX
00449381 |. 74 04 JZ SHORT 00449387
00449383 |. 33C0 XOR EAX,EAX
00449385 |. EB 6B JMP SHORT 004493F2
00449387 |> 8D85 F8FEFFFF LEA EAX,[LOCAL.66]
0044938D |. 50 PUSH EAX ; /Arg1 => OFFSET LOCAL.66
0044938E |. E8 3F420D00 CALL atoi ; \Insight3.atoi
00449393 |. 59 POP ECX
00449394 |. 8985 F0FEFFFF MOV DWORD PTR SS:[LOCAL.68],EAX
0044939A |. 83A5 F4FEFFFF AND DWORD PTR SS:[LOCAL.67],00000000
004493A1 |. EB 0D JMP SHORT 004493B0
004493A3 |> 8B85 F4FEFFFF /MOV EAX,DWORD PTR SS:[EBP-10C]
004493A9 |. 40 |INC EAX
004493AA |. 8985 F4FEFFFF |MOV DWORD PTR SS:[EBP-10C],EAX
004493B0 |> 83BD F4FEFFFF |CMP DWORD PTR SS:[EBP-10C],1E ; 30
004493B7 |. 73 1B |JAE SHORT 004493D4
004493B9 |. 8B85 F4FEFFFF |MOV EAX,DWORD PTR SS:[EBP-10C] ; i=[ebp-10c]
004493BF |. 8B8D F0FEFFFF |MOV ECX,DWORD PTR SS:[EBP-110]
004493C5 |. 3B0C85 28C653 |CMP ECX,DWORD PTR DS:[EAX*4+53C628] ; ASCII "90"
004493CC |.^ 75 04 |JNE SHORT 004493D2
004493CE |. 33C0 |XOR EAX,EAX
004493D0 |. EB 20 |JMP SHORT 004493F2
004493D2 |>^ EB CF \JMP SHORT 004493A3 ; 检查中间一段是否在全局数组中
004493D4 |> 8D85 F8FEFFFF LEA EAX,[EBP-108]
004493DA |. 50 PUSH EAX ; /Arg1
004493DB |. E8 B1B10A00 CALL 004F4591 ; \Insight3.004F4591
004493E0 |. 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
004493E3 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
004493E6 |. 3B45 F8 CMP EAX,DWORD PTR SS:[EBP-8]
004493E9 |. 74 04 JE SHORT 004493EF
004493EB |. 33C0 XOR EAX,EAX
004493ED |. EB 03 JMP SHORT 004493F2
004493EF |> 6A 01 PUSH 1
004493F1 |. 58 POP EAX
004493F2 |> C9 LEAVE
004493F3 \. C2 0400 RETN 4
个人感觉这个就正常多了:
1.首先判断注册码前边是不是"SI3US"。
2.然后调用PraseSerialNumber
根据这个函数的内容,我猜测注册码大概是ES3US-XXXXXX-YYYYY这样的形式。用‘-’把注册码分成三段,第一段是固定的形式,第二段是一个6位的字符串,第三段是一个5为的字符串。满足这样的格式,就会返回1,并且把中间的六位拷贝到参数2的缓冲区,把后五位利用atoi函数转换成整形并把值放在参数3里边。
3.接着检查XXXXX是不是111111 222222 123456这样的字符串对照算法中的循环部分。
4.Sub_004F4591是跟据XXXXXX算出一个值。
CPU Disasm
地址 HEX 数据 指令 注释
004F4591 /$ 55 PUSH EBP ; Insight3.004F4591(guessed Arg1
004F4592 |. 8BEC MOV EBP,ESP
004F4594 |. 83EC 10 SUB ESP,10
004F4597 |. FF75 08 PUSH DWORD PTR SS:[ARG.1] ; /Arg1 => [ARG.1]
004F459A |. E8 33900200 CALL atoi ; \Insight3.atoi
004F459F |. 59 POP ECX
004F45A0 |. 8945 F0 MOV DWORD PTR SS:[LOCAL.4],EAX
004F45A3 |. 8B45 F0 MOV EAX,DWORD PTR SS:[LOCAL.4]
004F45A6 |. 8945 FC MOV DWORD PTR SS:[LOCAL.1],EAX
004F45A9 |. 8365 F4 00 AND DWORD PTR SS:[LOCAL.3],00000000
004F45AD |. 8B45 08 MOV EAX,DWORD PTR SS:[ARG.1]
004F45B0 |. 8945 F8 MOV DWORD PTR SS:[LOCAL.2],EAX
004F45B3 |. EB 07 JMP SHORT 004F45BC
004F45B5 |> 8B45 F8 /MOV EAX,DWORD PTR SS:[LOCAL.2]
004F45B8 |. 40 |INC EAX
004F45B9 |. 8945 F8 |MOV DWORD PTR SS:[LOCAL.2],EAX
004F45BC |> 8B45 F8 |MOV EAX,DWORD PTR SS:[LOCAL.2]
004F45BF |. 0FB600 |MOVZX EAX,BYTE PTR DS:[EAX]
004F45C2 |. 85C0 |TEST EAX,EAX
004F45C4 |. 74 2C |JZ SHORT 004F45F2
004F45C6 |. 8B45 F8 |MOV EAX,DWORD PTR SS:[LOCAL.2]
004F45C9 |. 0FB600 |MOVZX EAX,BYTE PTR DS:[EAX]
004F45CC |. 8B4D F4 |MOV ECX,DWORD PTR SS:[LOCAL.3]
004F45CF |. 33048D 58815A |XOR EAX,DWORD PTR DS:[ECX*4+5A8158]
004F45D6 |. 8B4D FC |MOV ECX,DWORD PTR SS:[LOCAL.1]
004F45D9 |. 8D0488 |LEA EAX,[ECX*4+EAX]
004F45DC |. 8945 FC |MOV DWORD PTR SS:[LOCAL.1],EAX
004F45DF |. 8B45 F4 |MOV EAX,DWORD PTR SS:[LOCAL.3]
004F45E2 |. 40 |INC EAX
004F45E3 |. 8945 F4 |MOV DWORD PTR SS:[LOCAL.3],EAX
004F45E6 |. 837D F4 0A |CMP DWORD PTR SS:[LOCAL.3],0A
004F45EA |.^ 75 04 |JNE SHORT 004F45F0
004F45EC |. 8365 F4 00 |AND DWORD PTR SS:[LOCAL.3],00000000
004F45F0 |>^ EB C3 \JMP SHORT 004F45B5
004F45F2 |> 8B45 FC MOV EAX,DWORD PTR SS:[LOCAL.1]
004F45F5 |. 33D2 XOR EDX,EDX
004F45F7 |. B9 A0860100 MOV ECX,186A0
004F45FC |. F7F1 DIV ECX
004F45FE |. 8BC2 MOV EAX,EDX
004F4600 |. C9 LEAVE
004F4601 \. C2 0400 RETN 4
还原出来的等价代码。
int CalcSegRight(char *pSeg2)
{
//数组在5a8158处 程序中是全局数组
int ary[10]={0x96,0x95,0x10,0x23,0x07,0x15,0x08,0x03,0x10,0x11};
int nSeg2 = atoi(pSeg2);
char *pSz=pSeg2;
int i=0;
while(*pSz!=0)
{
nSeg2=(ary[i]^*pSz)+4*nSeg2;
i++;
if (i==10)
{
i=0;
}
pSz++;
}
return nSeg2 % 0x186A0u;
}
最后比较CalcSegRight计算的结果是否等于YYYYY转成整形后的数值,等于就返回1,不等于就返回0.
注册码验证成功就会把注册码保存在:
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SourceDynamics\Source Insight\3.0\Install]
中。
注册机算法;
利用随机数生成中间的一段,然后调用CalcSegRight计算出第三段。
void CSource_insight_kengenDlg::Right()
{
int ary[6]={0x96,0x95,0x10,0x23,0x07,0x15};
char szBuf[128]={0};
//第二段随机生成
DWORD dwSeg2=GetTickCount()*rand() %0xF4240;
sprintf(szBuf,"%06u",dwSeg2);
int nSeg3=CalcSegRight(szBuf);
memset(szBuf,0,sizeof(szBuf));
wsprintf(szBuf,"SI3US-%06u-%05d",dwSeg2,nSeg3);
SetDlgItemText(IDC_EDIT_SER,szBuf);
}
int CSource_insight_kengenDlg::CalcSegRight(char *pSeg2)
{
//数组在5a8158处
int ary[10]={0x96,0x95,0x10,0x23,0x07,0x15,0x08,0x03,0x10,0x11};
int nSeg2 = atoi(pSeg2);
char *pSz=pSeg2;
int i=0;
while(*pSz!=0)
{
nSeg2=(ary[i]^*pSz)+4*nSeg2;
i++;
if (i==10)
{
i=0;
}
pSz++;
}
return nSeg2 % 0x186A0u;
}
下边把源代码放上来:
Source_insight_kengen.zip
[课程]FART 脱壳王!加量不加价!FART作者讲授!