FastStone Image Viewer是一款老牌看图软件,附带编辑/转换图片功能,软件针对个人用户免费,适用于Windows,官方下载:https://www.faststone.org/FSViewerDetail.htm
出于兴趣,本文以最新版本v7.5为例,使用IDA和Windbg分析注册算法并实现KeyGen。Just for fun:)
首先查看FSViewer.exe,区段/导入表比较完整,没加壳,资源发现RCData,可能是Delphi/BC++开发。PE头里DllCharacteristics是0(无IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE),不支持ASLR(后面用IDA/Windbg不用ReBase,直接定位,方便分析)。
接下来开始分析注册码判断方式,本文从输入框跟踪用户名引用入手(以前写的《AudioSrv音频服务故障》有说如何找窗口处理过程)。首先运行程序到注册窗口,Windbg附加,输入假码,查看栈回溯。观察之后没有太明显的地方,查看注册框Edit句柄,bp GetWindowTextW条件断点未断下,随后bp NtUserMessageCall拦截WM_GETTEXT,断点命中,查看对应参数获取到用户名,ba r1下内存访问断点,跟踪用户名拷贝,尝试设置多次断点验证,最后定位到关键函数sub_72F248。
IDA加载完毕,Shift+F5打开signature,应用bcb5rt(CBuilder 5 runtime),识别到3000多个函数。sub_72F248函数代码如下:
首先检查注册码是否满足23位,由4组5个大写字母组成,中间横杠分隔,校验时会过滤掉分隔符,最后拆分成8位/8位/4位,(如:ABCDE-FGHIJ-KLMNO-PQRST => ABCDEFG HIJKLMN OPQR),下面观察两个关键函数。
由此可知满足其中一种条件即可注册成功,注意函数第四个参数有0和1,具体区别稍后说明。接下来分析sub_72E770和sub_72EBFC这两个函数。
注:使用Windbg调试查看参数及返回值,有些简单的字符串处理,观察数据就能看出来,做个标记即可,就不浪费时间分析了。
sub_72E770函数:
发现sub_71FB90函数由3处调用,跟进该函数:
上面的obj->init()由常量特征可知是SHA1和SHA512,对应的hash长度也分别是0x14(160位) 和 0x40(512位)
获取密钥位数
接下来则是密钥扩展,首先看448位的情况,跟踪下面的函数发现Blowfish的Pbox和Sbox,密钥扩展算法以及密钥长度448都满足标准Blowfish。
继续看128位的情况, 此时没有特征Box,但是128位密钥/操作长度是word以及shl ecx,9 shr edi,7基本可以确定是IDEA。(后面从虚表里也找到了输出算法名的函数,应该是某加密库)。
加密函数:
跟进ebx+54h加密函数
esi+7Ch加密封装函数,初始明文都是8个00(Blowfish和IDEA分组块都是8字节)
最后CODE:0072EA7C
到此第一个注册码验证函数sub_72E770大致分析完,现在来看第二个验证函数sub_72EBFC。
函数2和函数1使用的对象和加密函数基本一致,此处不再赘述,直接上代码。
在线运行KeyGen
最后贴出关键代码,完整代码见附件。
消息参数:
0x000D
(
13
) WM_GETTEXT
函数原型:
NtStatus (
*
NtUserMessageCall)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOLEAN bAnsi);
调试前注意函数调用约定,EAX
=
param1,EDX
=
param2,ECX
=
param3,其它参数栈传递。(ADC)
https:
/
/
en.wikipedia.org
/
wiki
/
X86_calling_conventions
消息参数:
0x000D
(
13
) WM_GETTEXT
函数原型:
NtStatus (
*
NtUserMessageCall)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOLEAN bAnsi);
调试前注意函数调用约定,EAX
=
param1,EDX
=
param2,ECX
=
param3,其它参数栈传递。(ADC)
https:
/
/
en.wikipedia.org
/
wiki
/
X86_calling_conventions
CODE:
0072F282
call @Controls@TControl@GetText$qqrv ; Controls::TControl::GetText(void)
CODE:
0072F287
mov eax, [ebp
+
var_18]
CODE:
0072F28A
lea edx, [ebp
+
name] ; 用户名
CODE:
0072F28D
call @Sysutils@Trim$qqrx17System@AnsiString ; Sysutils::Trim(System::AnsiString)
CODE:
0072F292
lea edx, [ebp
+
var_20]
CODE:
0072F295
mov eax, [esi
+
308h
]
CODE:
0072F29B
call @Controls@TControl@GetText$qqrv ; Controls::TControl::GetText(void)
CODE:
0072F2A0
mov eax, [ebp
+
var_20]
CODE:
0072F2A3
lea edx, [ebp
+
var_1C]
CODE:
0072F2A6
call @Sysutils@Trim$qqrx17System@AnsiString ; Sysutils::Trim(System::AnsiString)
CODE:
0072F2AB
mov eax, [ebp
+
var_1C] ; 注册码
CODE:
0072F2AE
lea edx, [ebp
+
regcode]
CODE:
0072F2B1
call @Sysutils@UpperCase$qqrx17System@AnsiString ; Sysutils::UpperCase(System::AnsiString)
CODE:
0072F2B6
lea eax, [ebp
+
var_10] ; 字符串变量
=
'' clear
CODE:
0072F2B9
call @System@@LStrClr$qqrr17System@AnsiString ; System::__linkproc__ LStrClr(System::AnsiString &)
CODE:
0072F2BE
mov eax, [ebp
+
regcode]
CODE:
0072F2C1
call strlen ; CBuilder
5
runtime
....
CODE:
0072F2FC
mov eax, [ebp
+
var_10]
CODE:
0072F2FF
call strlen ; CBuilder
5
runtime
CODE:
0072F304
cmp
eax,
5
;
5
个一组
CODE:
0072F307
jz short loc_72F323
CODE:
0072F309
mov eax, [ebp
+
var_10]
CODE:
0072F30C
call strlen ; CBuilder
5
runtime
CODE:
0072F311
cmp
eax,
0Bh
CODE:
0072F314
jz short loc_72F323
CODE:
0072F316
mov eax, [ebp
+
var_10]
CODE:
0072F319
call strlen ; CBuilder
5
runtime
CODE:
0072F31E
cmp
eax,
11h
CODE:
0072F321
jnz short loc_72F330
....
CODE:
0072F326
mov edx, offset dword_72F70C ; strcat(regcode,
'-'
)
CODE:
0072F32B
call @System@@LStrCat$qqrv ; System::__linkproc__ LStrCat(void)
CODE:
0072F282
call @Controls@TControl@GetText$qqrv ; Controls::TControl::GetText(void)
CODE:
0072F287
mov eax, [ebp
+
var_18]
CODE:
0072F28A
lea edx, [ebp
+
name] ; 用户名
CODE:
0072F28D
call @Sysutils@Trim$qqrx17System@AnsiString ; Sysutils::Trim(System::AnsiString)
CODE:
0072F292
lea edx, [ebp
+
var_20]
CODE:
0072F295
mov eax, [esi
+
308h
]
CODE:
0072F29B
call @Controls@TControl@GetText$qqrv ; Controls::TControl::GetText(void)
CODE:
0072F2A0
mov eax, [ebp
+
var_20]
CODE:
0072F2A3
lea edx, [ebp
+
var_1C]
CODE:
0072F2A6
call @Sysutils@Trim$qqrx17System@AnsiString ; Sysutils::Trim(System::AnsiString)
CODE:
0072F2AB
mov eax, [ebp
+
var_1C] ; 注册码
CODE:
0072F2AE
lea edx, [ebp
+
regcode]
CODE:
0072F2B1
call @Sysutils@UpperCase$qqrx17System@AnsiString ; Sysutils::UpperCase(System::AnsiString)
CODE:
0072F2B6
lea eax, [ebp
+
var_10] ; 字符串变量
=
'' clear
CODE:
0072F2B9
call @System@@LStrClr$qqrr17System@AnsiString ; System::__linkproc__ LStrClr(System::AnsiString &)
CODE:
0072F2BE
mov eax, [ebp
+
regcode]
CODE:
0072F2C1
call strlen ; CBuilder
5
runtime
....
CODE:
0072F2FC
mov eax, [ebp
+
var_10]
CODE:
0072F2FF
call strlen ; CBuilder
5
runtime
CODE:
0072F304
cmp
eax,
5
;
5
个一组
CODE:
0072F307
jz short loc_72F323
CODE:
0072F309
mov eax, [ebp
+
var_10]
CODE:
0072F30C
call strlen ; CBuilder
5
runtime
CODE:
0072F311
cmp
eax,
0Bh
CODE:
0072F314
jz short loc_72F323
CODE:
0072F316
mov eax, [ebp
+
var_10]
CODE:
0072F319
call strlen ; CBuilder
5
runtime
CODE:
0072F31E
cmp
eax,
11h
CODE:
0072F321
jnz short loc_72F330
....
CODE:
0072F326
mov edx, offset dword_72F70C ; strcat(regcode,
'-'
)
CODE:
0072F32B
call @System@@LStrCat$qqrv ; System::__linkproc__ LStrCat(void)
if
( sub_72E770((
int
)v3, name, code,
0
) && sub_72EBFC((
int
)v3, name, code,
0
)
|| sub_72E770((
int
)v3, name, code,
1
) && sub_72EBFC((
int
)v3, name, code,
1
) ) {
/
/
成功
}
else
{
/
/
失败
}
if
( sub_72E770((
int
)v3, name, code,
0
) && sub_72EBFC((
int
)v3, name, code,
0
)
|| sub_72E770((
int
)v3, name, code,
1
) && sub_72EBFC((
int
)v3, name, code,
1
) ) {
/
/
成功
}
else
{
/
/
失败
}
System::__linkproc__ LStrAddRef(a2);
System::__linkproc__ LStrAddRef(v50);
...
/
/
大小写转换,StrTrim,StrCat等操作
Sysutils::UpperCase(v51, (_BYTE
*
*
)&username);
Sysutils::Trim(v50, &v42);
Sysutils::UpperCase(v42, (_BYTE
*
*
)&v43);
...
System::__linkproc__ LStrCat(&v47, v37);
...
/
/
调试可知,这个函数是字符串拼接
sub_405004(
&v35,
3
,
v12,
"me4T6cBLV"
,
v48,
"CpCwxrvCJZ30pKLu8Svxjhnhut437glCpofVssnFeBh2G0ekUq4VcxFintMix52vL0iJNbdtWqHPyeumkDUC+4AaoSX+xpl56Esonk4="
);
/
/
sub_71FB90 需要重点关注
sub_71FB90(
*
(_BYTE
*
*
)(v52
+
788
), v35, (
int
)off_722720);
/
/
调用
1
/
/
参数
4
便是上面说的
0
和
1
,区别在于连接的字符串不同,生成注册码时选一种即可。
if
( a4 )
{
pop_window(&v32, v48);
v20
=
v32;
v19
=
*
(void
*
*
)(
*
off_98A548[
0
]
+
0x7A8
);
pop_window(&v31, v47);
v18
=
v31;
System::__linkproc__ WStrCatN(&v33,
3
);
/
/
连接字符串
System::__linkproc__ LStrFromWStr(&v34, v33);
/
/
unicode
字符转换
sub_71FB90(
*
(_BYTE
*
*
)(v52
+
784
), v34, (
int
)off_723D50);
/
/
调用
2
}
else
{
pop_window(&v28, v48);
v20
=
v28;
v19
=
*
(void
*
*
)(
*
off_98A548[
0
]
+
0x7A4
);
pop_window(&v27, v47);
v18
=
v27;
System::__linkproc__ WStrCatN(&v29,
3
);
/
/
连接字符串
System::__linkproc__ LStrFromWStr(&v30, v29);
/
/
unicode
字符转换
sub_71FB90(
*
(_BYTE
*
*
)(v52
+
784
), v30, (
int
)off_723D50);
/
/
调用
3
}
System::__linkproc__ LStrAddRef(a2);
System::__linkproc__ LStrAddRef(v50);
...
/
/
大小写转换,StrTrim,StrCat等操作
Sysutils::UpperCase(v51, (_BYTE
*
*
)&username);
Sysutils::Trim(v50, &v42);
Sysutils::UpperCase(v42, (_BYTE
*
*
)&v43);
...
System::__linkproc__ LStrCat(&v47, v37);
...
/
/
调试可知,这个函数是字符串拼接
sub_405004(
&v35,
3
,
v12,
"me4T6cBLV"
,
v48,
"CpCwxrvCJZ30pKLu8Svxjhnhut437glCpofVssnFeBh2G0ekUq4VcxFintMix52vL0iJNbdtWqHPyeumkDUC+4AaoSX+xpl56Esonk4="
);
/
/
sub_71FB90 需要重点关注
sub_71FB90(
*
(_BYTE
*
*
)(v52
+
788
), v35, (
int
)off_722720);
/
/
调用
1
/
/
参数
4
便是上面说的
0
和
1
,区别在于连接的字符串不同,生成注册码时选一种即可。
if
( a4 )
{
pop_window(&v32, v48);
v20
=
v32;
v19
=
*
(void
*
*
)(
*
off_98A548[
0
]
+
0x7A8
);
pop_window(&v31, v47);
v18
=
v31;
System::__linkproc__ WStrCatN(&v33,
3
);
/
/
连接字符串
System::__linkproc__ LStrFromWStr(&v34, v33);
/
/
unicode
字符转换
sub_71FB90(
*
(_BYTE
*
*
)(v52
+
784
), v34, (
int
)off_723D50);
/
/
调用
2
}
else
{
pop_window(&v28, v48);
v20
=
v28;
v19
=
*
(void
*
*
)(
*
off_98A548[
0
]
+
0x7A4
);
pop_window(&v27, v47);
v18
=
v27;
System::__linkproc__ WStrCatN(&v29,
3
);
/
/
连接字符串
System::__linkproc__ LStrFromWStr(&v30, v29);
/
/
unicode
字符转换
sub_71FB90(
*
(_BYTE
*
*
)(v52
+
784
), v30, (
int
)off_723D50);
/
/
调用
3
}
CODE:
0071FBE3
call dword ptr [edx
+
40h
] ; edx是虚表,
hash
初始化,obj
-
>init()
=
> sha
*
_init
CODE:
0071FBE6
mov edx, [ebp
+
var_4]
CODE:
0071FBE9
mov eax, edi
CODE:
0071FBEB
call sub_71FA88
CODE:
0071FBF0
mov edx, esi
CODE:
0071FBF2
mov eax, edi
CODE:
0071FBF4
mov ecx, [eax]
CODE:
0071FBF6
call dword ptr [ecx
+
44h
] ; 计算
hash
值,obj
-
>final()
=
> sha
*
_final
CODE:
0071FBF9
mov eax, edi
CODE:
0071FBFB
call sub_403E2C
CODE:
0071FC00
mov eax, ebx
CODE:
0071FC02
mov edx, [eax]
CODE:
0071FC04
call dword ptr [edx
+
38h
] ; 获取
hash
值位数,obj
-
>hash_bits()
=
> sha
*
_bits
CODE:
0071FC07
mov edi, eax
CODE:
0071FC09
mov eax, [ebp
+
var_8] ; 参数
1
CODE:
0071FC0C
call dword ptr [eax
+
38h
] ; 由此可知,参数
1
也是也是虚表,obj2
-
>key_bits(),返回其函数长度
0xA0
(
160
)
CODE:
0071FC0F
cmp
edi, eax ;
hash
值位数是否大于等于key_bits(
160
)
CODE:
0071FC11
jge short loc_71FC29
CODE:
0071FC13
push
0
CODE:
0071FC15
mov eax, ebx
CODE:
0071FC17
mov edx, [eax]
CODE:
0071FC19
call dword ptr [edx
+
38h
] ; sha1
hash
值作为输入
CODE:
0071FC1C
mov ecx, eax
CODE:
0071FC1E
mov edx, esi
CODE:
0071FC20
mov eax, ebx
CODE:
0071FC22
mov ebx, [eax]
CODE:
0071FC24
call dword ptr [ebx
+
40h
] ;密钥初始化
CODE:
0071FC27
jmp short loc_71FC3C
CODE:
0071FC29
;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
CODE:
0071FC29
CODE:
0071FC29
loc_71FC29: ; CODE XREF: sub_71FB90
+
81
↑j
CODE:
0071FC29
push
0
CODE:
0071FC2B
mov eax, [ebp
+
var_8]
CODE:
0071FC2E
call dword ptr [eax
+
38h
] ;sha512
hash
值作为输入
CODE:
0071FC31
mov ecx, eax
CODE:
0071FC33
mov edx, esi
CODE:
0071FC35
mov eax, ebx
CODE:
0071FC37
mov ebx, [eax]
CODE:
0071FC39
call dword ptr [ebx
+
40h
] ; 密钥初始化
CODE:
0071FC3C
CODE:
0071FC3C
loc_71FC3C: ; CODE XREF: sub_71FB90
+
97
↑j
CODE:
0071FC3C
mov eax, [ebp
+
var_8]
CODE:
0071FC3F
call dword ptr [eax
+
38h
]
CODE:
0071FBE3
call dword ptr [edx
+
40h
] ; edx是虚表,
hash
初始化,obj
-
>init()
=
> sha
*
_init
CODE:
0071FBE6
mov edx, [ebp
+
var_4]
CODE:
0071FBE9
mov eax, edi
CODE:
0071FBEB
call sub_71FA88
CODE:
0071FBF0
mov edx, esi
CODE:
0071FBF2
mov eax, edi
CODE:
0071FBF4
mov ecx, [eax]
CODE:
0071FBF6
call dword ptr [ecx
+
44h
] ; 计算
hash
值,obj
-
>final()
=
> sha
*
_final
CODE:
0071FBF9
mov eax, edi
CODE:
0071FBFB
call sub_403E2C
CODE:
0071FC00
mov eax, ebx
CODE:
0071FC02
mov edx, [eax]
CODE:
0071FC04
call dword ptr [edx
+
38h
] ; 获取
hash
值位数,obj
-
>hash_bits()
=
> sha
*
_bits
CODE:
0071FC07
mov edi, eax
CODE:
0071FC09
mov eax, [ebp
+
var_8] ; 参数
1
CODE:
0071FC0C
call dword ptr [eax
+
38h
] ; 由此可知,参数
1
也是也是虚表,obj2
-
>key_bits(),返回其函数长度
0xA0
(
160
)
CODE:
0071FC0F
cmp
edi, eax ;
hash
值位数是否大于等于key_bits(
160
)
CODE:
0071FC11
jge short loc_71FC29
CODE:
0071FC13
push
0
CODE:
0071FC15
mov eax, ebx
CODE:
0071FC17
mov edx, [eax]
CODE:
0071FC19
call dword ptr [edx
+
38h
] ; sha1
hash
值作为输入
CODE:
0071FC1C
mov ecx, eax
CODE:
0071FC1E
mov edx, esi
CODE:
0071FC20
mov eax, ebx
CODE:
0071FC22
mov ebx, [eax]
CODE:
0071FC24
call dword ptr [ebx
+
40h
] ;密钥初始化
CODE:
0071FC27
jmp short loc_71FC3C
CODE:
0071FC29
;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
CODE:
0071FC29
CODE:
0071FC29
loc_71FC29: ; CODE XREF: sub_71FB90
+
81
↑j
CODE:
0071FC29
push
0
CODE:
0071FC2B
mov eax, [ebp
+
var_8]
CODE:
0071FC2E
call dword ptr [eax
+
38h
] ;sha512
hash
值作为输入
CODE:
0071FC31
mov ecx, eax
CODE:
0071FC33
mov edx, esi
CODE:
0071FC35
mov eax, ebx
CODE:
0071FC37
mov ebx, [eax]
CODE:
0071FC39
call dword ptr [ebx
+
40h
] ; 密钥初始化
CODE:
0071FC3C
CODE:
0071FC3C
loc_71FC3C: ; CODE XREF: sub_71FB90
+
97
↑j
CODE:
0071FC3C
mov eax, [ebp
+
var_8]
CODE:
0071FC3F
call dword ptr [eax
+
38h
]
CODE:
00723A04
sha1_init proc near ; DATA XREF: CODE:
00722760
↑o
CODE:
0
0723A04
push ebx
CODE:
00723A05
mov ebx, eax
CODE:
00723A07
mov eax, ebx
CODE:
00723A09
mov edx, [eax]
CODE:
00723A0B
call dword ptr [edx
+
48h
]
CODE:
00723A0E
mov dword ptr [ebx
+
40h
],
67452301h
CODE:
00723A15
mov dword ptr [ebx
+
44h
],
0EFCDAB89h
CODE:
00723A1C
mov dword ptr [ebx
+
48h
],
98BADCFEh
CODE:
00723A23
mov dword ptr [ebx
+
4Ch
],
10325476h
CODE:
00723A2A
mov dword ptr [ebx
+
50h
],
0C3D2E1F0h
CODE:
00723A31
mov byte ptr [ebx
+
30h
],
1
CODE:
00723A35
pop ebx
CODE:
00723A36
retn
CODE:
00723A36
sha1_init end
CODE:
0072E14C
sha512_init proc near ; DATA XREF: CODE:
00723D90
↑o
CODE:
0072E14C
push ebx
CODE:
0072E14D
mov ebx, eax
CODE:
0072E14F
mov eax, ebx
CODE:
0072E151
mov edx, [eax]
CODE:
0072E153
call dword ptr [edx
+
48h
]
CODE:
0072E156
mov dword ptr [ebx
+
50h
],
0F3BCC908h
CODE:
0072E15D
mov dword ptr [ebx
+
54h
],
6A09E667h
CODE:
0072E164
mov dword ptr [ebx
+
58h
],
84CAA73Bh
CODE:
0072E16B
mov dword ptr [ebx
+
5Ch
],
0BB67AE85h
CODE:
0072E172
mov dword ptr [ebx
+
60h
],
0FE94F82Bh
CODE:
0072E179
mov dword ptr [ebx
+
64h
],
3C6EF372h
CODE:
0072E180
mov dword ptr [ebx
+
68h
],
5F1D36F1h
CODE:
0072E187
mov dword ptr [ebx
+
6Ch
],
0A54FF53Ah
CODE:
0072E18E
mov dword ptr [ebx
+
70h
],
0ADE682D1h
CODE:
0072E195
mov dword ptr [ebx
+
74h
],
510E527Fh
CODE:
0072E19C
mov dword ptr [ebx
+
78h
],
2B3E6C1Fh
CODE:
0072E1A3
mov dword ptr [ebx
+
7Ch
],
9B05688Ch
CODE:
0072E1AA
mov dword ptr [ebx
+
80h
],
0FB41BD6Bh
CODE:
0072E1B4
mov dword ptr [ebx
+
84h
],
1F83D9ABh
CODE:
0072E1BE
mov dword ptr [ebx
+
88h
],
137E2179h
CODE:
0072E1C8
mov dword ptr [ebx
+
8Ch
],
5BE0CD19h
CODE:
0072E1D2
mov byte ptr [ebx
+
30h
],
1
CODE:
0072E1D6
pop ebx
CODE:
0072E1D7
retn
CODE:
0072E1D7
sha512_init endp
CODE:
00723A04
sha1_init proc near ; DATA XREF: CODE:
00722760
↑o
CODE:
0
0723A04
push ebx
CODE:
00723A05
mov ebx, eax
CODE:
00723A07
mov eax, ebx
CODE:
00723A09
mov edx, [eax]
CODE:
00723A0B
call dword ptr [edx
+
48h
]
CODE:
00723A0E
mov dword ptr [ebx
+
40h
],
67452301h
CODE:
00723A15
mov dword ptr [ebx
+
44h
],
0EFCDAB89h
CODE:
00723A1C
mov dword ptr [ebx
+
48h
],
98BADCFEh
CODE:
00723A23
mov dword ptr [ebx
+
4Ch
],
10325476h
CODE:
00723A2A
mov dword ptr [ebx
+
50h
],
0C3D2E1F0h
CODE:
00723A31
mov byte ptr [ebx
+
30h
],
1
CODE:
00723A35
pop ebx
CODE:
00723A36
retn
CODE:
00723A36
sha1_init end
CODE:
0072E14C
sha512_init proc near ; DATA XREF: CODE:
00723D90
↑o
CODE:
0072E14C
push ebx
CODE:
0072E14D
mov ebx, eax
CODE:
0072E14F
mov eax, ebx
CODE:
0072E151
mov edx, [eax]
CODE:
0072E153
call dword ptr [edx
+
48h
]
CODE:
0072E156
mov dword ptr [ebx
+
50h
],
0F3BCC908h
CODE:
0072E15D
mov dword ptr [ebx
+
54h
],
6A09E667h
CODE:
0072E164
mov dword ptr [ebx
+
58h
],
84CAA73Bh
CODE:
0072E16B
mov dword ptr [ebx
+
5Ch
],
0BB67AE85h
CODE:
0072E172
mov dword ptr [ebx
+
60h
],
0FE94F82Bh
CODE:
0072E179
mov dword ptr [ebx
+
64h
],
3C6EF372h
CODE:
0072E180
mov dword ptr [ebx
+
68h
],
5F1D36F1h
CODE:
0072E187
mov dword ptr [ebx
+
6Ch
],
0A54FF53Ah
CODE:
0072E18E
mov dword ptr [ebx
+
70h
],
0ADE682D1h
CODE:
0072E195
mov dword ptr [ebx
+
74h
],
510E527Fh
CODE:
0072E19C
mov dword ptr [ebx
+
78h
],
2B3E6C1Fh
CODE:
0072E1A3
mov dword ptr [ebx
+
7Ch
],
9B05688Ch
CODE:
0072E1AA
mov dword ptr [ebx
+
80h
],
0FB41BD6Bh
CODE:
0072E1B4
mov dword ptr [ebx
+
84h
],
1F83D9ABh
CODE:
0072E1BE
mov dword ptr [ebx
+
88h
],
137E2179h
CODE:
0072E1C8
mov dword ptr [ebx
+
8Ch
],
5BE0CD19h
CODE:
0072E1D2
mov byte ptr [ebx
+
30h
],
1
CODE:
0072E1D6
pop ebx
CODE:
0072E1D7
retn
CODE:
0072E1D7
sha512_init endp
CODE:
0071FC0C
call dword ptr [eax
+
38h
] ; 这里获取密钥位数,可知有
448
位和
128
位
CODE:
0071FC0C
call dword ptr [eax
+
38h
] ; 这里获取密钥位数,可知有
448
位和
128
位
0071fc24
ff5340 call dword ptr [ebx
+
40h
] ds:
002b
:
00721d28
=
00720244
....子函数....
00720264
8b4dfc
mov ecx,dword ptr [ebp
-
4
]
00720267
8bc3
mov eax,ebx
00720269
8b38
mov edi,dword ptr [eax]
0072026b
ff575c call dword ptr [edi
+
5Ch
] ds:
002b
:
00720d7c
=
00720f18
/
/
密钥扩展
....子函数....
CODE:
00720F30
lea edx, [esi
+
48h
]
CODE:
00720F33
mov eax, offset unk_987C04 ; Blowfish P
-
Box
CODE:
00720F38
mov ecx,
1000h
;
4
*
8
*
32
=
1024
=
0x1000
CODE:
00720F3D
call memcpy_xxx
CODE:
00720F42
lea edx, [esi
+
1048h
]
CODE:
00720F48
mov eax,
987BBCh
; Blowfish S
-
Box
CODE:
00720F4D
mov ecx,
48h
;
18
*
4
=
72
=
0x48
CODE:
00720F52
call memcpy_xxx
P
-
Box
0
:
000
> dd
00987bbc
00987bbc
243f6a88
85a308d3
13198a2e
03707344
00987bcc
a4093822
299f31d0
082efa98
ec4e6c89
00987bdc
452821e6
38d01377
be5466cf
34e90c6c
00987bec
c0ac29b7 c97c50dd
3f84d5b5
b5470917
00987bfc
9216d5d9
8979fb1b
S
-
Box
0
:
000
> dd
00987c04
00987c04
d1310ba6
98dfb5ac
2ffd72db
d01adfb7
00987c14
b8e1afed
6a267e96
ba7c9045 f12c7f99
00987c24
24a19947
b3916cf7
0801f2e2
858efc16
00987c34
636920d8
71574e69
a458fea3 f4933d7e
00987c44
0d95748f
728eb658
718bcd58
82154aee
00987c54
7b54a41d
c25a59b5
9c30d539
2af26013
00987c64
c5d1b023
286085f0
ca417918 b8db38ef
00987c74
8e79dcb0
603a180e
6c9e0e8b
b01e8a3e
....
0071fc24
ff5340 call dword ptr [ebx
+
40h
] ds:
002b
:
00721d28
=
00720244
....子函数....
00720264
8b4dfc
mov ecx,dword ptr [ebp
-
4
]
00720267
8bc3
mov eax,ebx
00720269
8b38
mov edi,dword ptr [eax]
0072026b
ff575c call dword ptr [edi
+
5Ch
] ds:
002b
:
00720d7c
=
00720f18
/
/
密钥扩展
....子函数....
CODE:
00720F30
lea edx, [esi
+
48h
]
CODE:
00720F33
mov eax, offset unk_987C04 ; Blowfish P
-
Box
CODE:
00720F38
mov ecx,
1000h
;
4
*
8
*
32
=
1024
=
0x1000
CODE:
00720F3D
call memcpy_xxx
CODE:
00720F42
lea edx, [esi
+
1048h
]
CODE:
00720F48
mov eax,
987BBCh
; Blowfish S
-
Box
CODE:
00720F4D
mov ecx,
48h
;
18
*
4
=
72
=
0x48
CODE:
00720F52
call memcpy_xxx
P
-
Box
0
:
000
> dd
00987bbc
00987bbc
243f6a88
85a308d3
13198a2e
03707344
00987bcc
a4093822
299f31d0
082efa98
ec4e6c89
00987bdc
452821e6
38d01377
be5466cf
34e90c6c
00987bec
c0ac29b7 c97c50dd
3f84d5b5
b5470917
00987bfc
9216d5d9
8979fb1b
S
-
Box
0
:
000
> dd
00987c04
00987c04
d1310ba6
98dfb5ac
2ffd72db
d01adfb7
00987c14
b8e1afed
6a267e96
ba7c9045 f12c7f99
00987c24
24a19947
b3916cf7
0801f2e2
858efc16
00987c34
636920d8
71574e69
a458fea3 f4933d7e
00987c44
0d95748f
728eb658
718bcd58
82154aee
00987c54
7b54a41d
c25a59b5
9c30d539
2af26013
00987c64
c5d1b023
286085f0
ca417918 b8db38ef
00987c74
8e79dcb0
603a180e
6c9e0e8b
b01e8a3e
....
0071fc24
ff5340 call dword ptr [ebx
+
40h
] ds:
002b
:
00721d28
=
00720244
....子函数....
00720262
8bd7
mov edx,edi
00720264
8b4dfc
mov ecx,dword ptr [ebp
-
4
]
00720267
8bc3
mov eax,ebx
00720269
8b38
mov edi,dword ptr [eax]
0072026b
ff575c call dword ptr [edi
+
5Ch
] ds:
002b
:
00721d44
=
00721f94
/
/
密钥扩展
...子函数....
00721fe0
8bc6
mov eax,esi
00721fe2
48
dec eax
00721fe3
c1e003 shl eax,
3
00721fe6
668b4c434a
mov cx,word ptr [ebx
+
eax
*
2
+
4Ah
]
00721feb
c1e109 shl ecx,
9
00721fee
0fb77c434c
movzx edi,word ptr [ebx
+
eax
*
2
+
4Ch
]
00721ff3
c1ef07 shr edi,
7
00721ff6
660bcf
or
cx,di
00721ff9
8bd6
mov edx,esi
00721ffb
c1e203 shl edx,
3
00721ffe
66894c5348
mov word ptr [ebx
+
edx
*
2
+
48h
],cx
00722003
668b4c434c
mov cx,word ptr [ebx
+
eax
*
2
+
4Ch
]
00722008
c1e109 shl ecx,
9
0072200b
0fb77c434e
movzx edi,word ptr [ebx
+
eax
*
2
+
4Eh
]
00722010
c1ef07 shr edi,
7
00722013
660bcf
or
cx,di
00722016
66894c534a
mov word ptr [ebx
+
edx
*
2
+
4Ah
],cx
0072201b
668b4c434e
mov cx,word ptr [ebx
+
eax
*
2
+
4Eh
]
00722020
c1e109 shl ecx,
9
00722023
0fb77c4350
movzx edi,word ptr [ebx
+
eax
*
2
+
50h
]
00722028
c1ef07 shr edi,
7
0072202b
660bcf
or
cx,di
0072202e
66894c534c
mov word ptr [ebx
+
edx
*
2
+
4Ch
],cx
00722033
668b4c4350
mov cx,word ptr [ebx
+
eax
*
2
+
50h
]
00722038
c1e109 shl ecx,
9
0072203b
0fb77c4352
movzx edi,word ptr [ebx
+
eax
*
2
+
52h
]
00722040
c1ef07 shr edi,
7
00722043
660bcf
or
cx,di
00722046
66894c534e
mov word ptr [ebx
+
edx
*
2
+
4Eh
],cx
0072204b
668b4c4352
mov cx,word ptr [ebx
+
eax
*
2
+
52h
]
0071fc24
ff5340 call dword ptr [ebx
+
40h
] ds:
002b
:
00721d28
=
00720244
....子函数....
00720262
8bd7
mov edx,edi
00720264
8b4dfc
mov ecx,dword ptr [ebp
-
4
]
00720267
8bc3
mov eax,ebx
00720269
8b38
mov edi,dword ptr [eax]
0072026b
ff575c call dword ptr [edi
+
5Ch
] ds:
002b
:
00721d44
=
00721f94
/
/
密钥扩展
...子函数....
00721fe0
8bc6
mov eax,esi
00721fe2
48
dec eax
00721fe3
c1e003 shl eax,
3
00721fe6
668b4c434a
mov cx,word ptr [ebx
+
eax
*
2
+
4Ah
]
00721feb
c1e109 shl ecx,
9
00721fee
0fb77c434c
movzx edi,word ptr [ebx
+
eax
*
2
+
4Ch
]
00721ff3
c1ef07 shr edi,
7
00721ff6
660bcf
or
cx,di
00721ff9
8bd6
mov edx,esi
00721ffb
c1e203 shl edx,
3
00721ffe
66894c5348
mov word ptr [ebx
+
edx
*
2
+
48h
],cx
00722003
668b4c434c
mov cx,word ptr [ebx
+
eax
*
2
+
4Ch
]
00722008
c1e109 shl ecx,
9
0072200b
0fb77c434e
movzx edi,word ptr [ebx
+
eax
*
2
+
4Eh
]
00722010
c1ef07 shr edi,
7
00722013
660bcf
or
cx,di
00722016
66894c534a
mov word ptr [ebx
+
edx
*
2
+
4Ah
],cx
0072201b
668b4c434e
mov cx,word ptr [ebx
+
eax
*
2
+
4Eh
]
00722020
c1e109 shl ecx,
9
00722023
0fb77c4350
movzx edi,word ptr [ebx
+
eax
*
2
+
50h
]
00722028
c1ef07 shr edi,
7
0072202b
660bcf
or
cx,di
0072202e
66894c534c
mov word ptr [ebx
+
edx
*
2
+
4Ch
],cx
00722033
668b4c4350
mov cx,word ptr [ebx
+
eax
*
2
+
50h
]
00722038
c1e109 shl ecx,
9
0072203b
0fb77c4352
movzx edi,word ptr [ebx
+
eax
*
2
+
52h
]
00722040
c1ef07 shr edi,
7
00722043
660bcf
or
cx,di
00722046
66894c534e
mov word ptr [ebx
+
edx
*
2
+
4Eh
],cx
0072204b
668b4c4352
mov cx,word ptr [ebx
+
eax
*
2
+
52h
]
CODE:
0072EA41
mov eax, [ebp
+
var_4]
CODE:
0072EA44
mov eax, [eax
+
314h
]
CODE:
0072EA4A
mov edx, [ebp
+
var_18]
CODE:
0072EA4D
mov ebx, [eax]
CODE:
0072EA4F
call dword ptr [ebx
+
54h
] ; Blowfish
CODE:
0072EA52
lea ecx, [ebp
+
var_6C]
CODE:
0072EA55
mov eax, [ebp
+
var_4]
CODE:
0072EA58
mov eax, [eax
+
310h
]
CODE:
0072EA5E
mov edx, [ebp
+
var_20]
CODE:
0072EA61
mov ebx, [eax]
CODE:
0072EA63
call dword ptr [ebx
+
54h
] ; IDEA
CODE:
0072EA41
mov eax, [ebp
+
var_4]
CODE:
0072EA44
mov eax, [eax
+
314h
]
CODE:
0072EA4A
mov edx, [ebp
+
var_18]
CODE:
0072EA4D
mov ebx, [eax]
CODE:
0072EA4F
call dword ptr [ebx
+
54h
] ; Blowfish
CODE:
0072EA52
lea ecx, [ebp
+
var_6C]
CODE:
0072EA55
mov eax, [ebp
+
var_4]
CODE:
0072EA58
mov eax, [eax
+
310h
]
CODE:
0072EA5E
mov edx, [ebp
+
var_20]
CODE:
0072EA61
mov ebx, [eax]
CODE:
0072EA63
call dword ptr [ebx
+
54h
] ; IDEA
CODE:
0071FEFE
call dword ptr [esi
+
7Ch
] ;加密封装函数
CODE:
0071FF01
lea edx, [ebp
+
var_4]
CODE:
0071FF04
mov eax, [ebx]
CODE:
0071FF06
call sub_71F2E4 ;Base64
CODE:
0071FEFE
call dword ptr [esi
+
7Ch
] ;加密封装函数
CODE:
0071FF01
lea edx, [ebp
+
var_4]
CODE:
0071FF04
mov eax, [ebx]
CODE:
0071FF06
call sub_71F2E4 ;Base64
CODE:
00720602
mov [ebp
+
var_8], edx
CODE:
00720605
mov esi, [ebp
+
var_4] ;明文(例如:用户名和注册码交叉组成的第一段数据)
CODE:
00720608
mov eax, [ebp
+
arg_0] ;明文长度
CODE:
0072060B
test eax, eax
CODE:
0072060D
jbe short loc_720647
CODE:
0072060F
mov [ebp
+
var_14], eax
CODE:
00720612
CODE:
00720612
loc_720612: ; CODE XREF: sub_7205D8
+
6D
↓j
CODE:
00720612
lea ecx, [ebp
+
var_10]
CODE:
00720615
lea edx, [ebx
+
40h
]
CODE:
00720618
mov eax, ebx
CODE:
0072061A
mov edi, [eax]
CODE:
0072061C
call dword ptr [edi
+
6Ch
] ;Blowfish
/
IDEA加密明文
CODE:
0072061F
mov eax, [ebp
+
var_8]
CODE:
00720622
mov al, [eax] ; 取加密后的首字节
CODE:
00720624
xor al, [ebp
+
var_10] ; 异或明文
CODE:
00720627
mov [esi], al ; 结果暂存
CODE:
00720629
lea edx, [ebx
+
40h
]
CODE:
0072062C
lea eax, [ebx
+
41h
]
CODE:
0072062F
mov ecx,
7
CODE:
00720634
call memcpy_xxx ; 左移
1
个字节
CODE:
00720639
mov al, [esi] ; 取出暂存字节
CODE:
0072063B
mov [ebx
+
47h
], al ;将暂存字节替换最右边的数据
CODE:
0072063E
inc [ebp
+
var_8]
CODE:
00720641
inc esi
CODE:
00720642
dec [ebp
+
var_14]
CODE:
00720645
jnz short loc_720612 ;循环处理明文
CODE:
00720602
mov [ebp
+
var_8], edx
CODE:
00720605
mov esi, [ebp
+
var_4] ;明文(例如:用户名和注册码交叉组成的第一段数据)
CODE:
00720608
mov eax, [ebp
+
arg_0] ;明文长度
CODE:
0072060B
test eax, eax
CODE:
0072060D
jbe short loc_720647
CODE:
0072060F
mov [ebp
+
var_14], eax
CODE:
00720612
CODE:
00720612
loc_720612: ; CODE XREF: sub_7205D8
+
6D
↓j
CODE:
00720612
lea ecx, [ebp
+
var_10]
CODE:
00720615
lea edx, [ebx
+
40h
]
CODE:
00720618
mov eax, ebx
CODE:
0072061A
mov edi, [eax]
CODE:
0072061C
call dword ptr [edi
+
6Ch
] ;Blowfish
/
IDEA加密明文
CODE:
0072061F
mov eax, [ebp
+
var_8]
CODE:
00720622
mov al, [eax] ; 取加密后的首字节
CODE:
00720624
xor al, [ebp
+
var_10] ; 异或明文
CODE:
00720627
mov [esi], al ; 结果暂存
CODE:
00720629
lea edx, [ebx
+
40h
]
CODE:
0072062C
lea eax, [ebx
+
41h
]
CODE:
0072062F
mov ecx,
7
CODE:
00720634
call memcpy_xxx ; 左移
1
个字节
CODE:
00720639
mov al, [esi] ; 取出暂存字节
CODE:
0072063B
mov [ebx
+
47h
], al ;将暂存字节替换最右边的数据
CODE:
0072063E
inc [ebp
+
var_8]
CODE:
00720641
inc esi
CODE:
00720642
dec [ebp
+
var_14]
CODE:
00720645
jnz short loc_720612 ;循环处理明文
CODE:
0072EA7C
v13
=
strlen(v45);
if
( v13 >
0
)
{
v14
=
1
;
do
{
/
/
第二段注册码,取最终Base64的大写字符,
8
个
if
(
*
(_BYTE
*
)(v45
+
v14
-
1
) >
=
0x41u
&&
*
(_BYTE
*
)(v45
+
v14
-
1
) <
=
0x5Au
&& strlen(v44) <
8
)
{
v15
=
*
(_BYTE
*
)(v45
+
v14
-
1
);
unknown_libname_17((
int
)&v25);
System::__linkproc__ LStrCat(&v44, v25);
}
+
+
v14;
-
-
v13;
}
while
( v13 );
}
System::__linkproc__ LStrCopy(v43,
9
,
8
, (
int
)&v24);
System::__linkproc__ LStrCmp(v44, v24);
/
/
检查第二段注册码是否合法
if
( v16 )
v49
=
1
;
/
/
验证通过
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-12-26 22:28
被BlackINT3编辑
,原因: 更新失效链接