#逆向分析 160个CrackMe 052
闲来无事,工作上有调整,等待来年安排,日常的学习还是不能松懈,好久没搞2进制了,最近正在刷pwn和CrackMe,看到了一个160集合感觉不错,刷了几周了,做了20多个了吧,也不知道哪个好,随便搞了下,感觉这5星级的还是挺有意思的,故分析发文。
160个CrackMe破解思路合集
环境:win10 x64 chs
工具:x64dbg IDA BinaryNinja
编译器:gcc
那些在xp上好有用的工具都不太兼容win10,魔改版的LoadPE + ImportREC 修复的exe时灵时不灵的。
还好x64dbg仅有的一个插件解决了这个问题。
x64dbg + esp定律找到OEP,使用x64dbg自带的Scylla,三下五除二搞定。
第一种办法就是 IDA根据导入表MessageBox函数,交叉引用找到算法。
第二种就是通过OD或者x64dbg动态调试,弹出对话框后,暂停进程,调用栈回溯,也能找到算法函数。
这里我就不过多赘述。
直接拖入IDA,通过导入表MessageBoxA的交叉引用找到4处引用,2个函数。
第一个函数是MFC封装的MsgBox函数,根据它的交叉引用很快找到了数据处理和比较的地方。
封装的MsgBox
根据MsgBox交叉引用,找到处理函数
代码分析:
获取name和code分别保存
name + strrev(name) + ProductID(项的值) + RegisterOwner(项的值);由于是win10没有注册表项, 最终结果是 name + strrev(name) + strrev(name) + strrev(name) ;
初始化md5的state
name[-1] = 0x80 ;数据对齐64字节,存储len * 8
循环Md5Tramsform
保留state[0] 低16位,关键跳比较的就是state[0]的数据
读取code中的4个UINT
分别对 UINT[0] UINT[1];UINT[1]UINT[2];UINT[2]UINT[3] 运算
比较 UINT[0] 和 state[0] 如果相等则成功;
关键函数Encode函数
代码解读,直接c代码把
简化后的Encode
简化后其实就2步骤,根据低32位还原高32位;然后循环右移1位
Decode代码可得
验证结果
几组组NS供验证:
helloworld : 7db37660 ae4c5d05 d2783eea 1d6514f2
pediy.com : b3f21c39 e8ca4483 4146d6f6 5644545b
int
__thiscall sub_4100A8(_DWORD *
this
,
LPCSTR
lpText,
LPCSTR
lpCaption,
UINT
uType)
{
const
CHAR
*v4;
HWND
v6;
v4 = lpCaption;
if
( !lpCaption )
v4 = (
const
CHAR
*)*((_DWORD *)AfxGetModuleState() + 4);
if
(
this
)
v6 = (
HWND
)
this
[7];
else
v6 = 0;
return
MessageBoxA(v6, lpText, v4, uType);
}
int
__thiscall sub_4100A8(_DWORD *
this
,
LPCSTR
lpText,
LPCSTR
lpCaption,
UINT
uType)
{
const
CHAR
*v4;
HWND
v6;
v4 = lpCaption;
if
( !lpCaption )
v4 = (
const
CHAR
*)*((_DWORD *)AfxGetModuleState() + 4);
if
(
this
)
v6 = (
HWND
)
this
[7];
else
v6 = 0;
return
MessageBoxA(v6, lpText, v4, uType);
}
UPX0:
00401C20
sub esp,
608h
UPX0:
00401C26
push ebx
UPX0:
00401C27
push ebp
UPX0:
00401C28
push esi
UPX0:
00401C29
mov ebp, ecx
UPX0:
00401C2B
push edi
UPX0:
00401C2C
mov ecx,
7Dh
;
'}'
UPX0:
00401C31
xor eax, eax
UPX0:
00401C33
lea edi, [esp
+
3Ch
]
UPX0:
00401C37
rep stosd
UPX0:
00401C39
mov ecx,
7Dh
;
'}'
UPX0:
00401C3E
lea edi, [esp
+
424h
]
UPX0:
00401C45
rep stosd
UPX0:
00401C47
mov ecx,
7Dh
;
'}'
UPX0:
00401C4C
lea edi, [esp
+
230h
]
UPX0:
00401C53
rep stosd
UPX0:
00401C55
lea eax, [esp
+
3Ch
]
UPX0:
00401C59
push
64h
;
'd'
UPX0:
00401C5B
push eax
UPX0:
00401C5C
lea ecx, [ebp
+
5Ch
]
UPX0:
00401C5F
call MfcGetText ; 获取Name的字符串 name
=
esp
+
3c
UPX0:
00401C64
lea ecx, [esp
+
424h
]
UPX0:
00401C6B
push
64h
;
'd'
UPX0:
00401C6D
push ecx
UPX0:
00401C6E
lea ecx, [ebp
+
0ACh
]
UPX0:
00401C74
call MfcGetText ; 获取Code的字符串存在 esp
+
0x424
UPX0:
00401C79
lea edi, [esp
+
3Ch
]
UPX0:
00401C7D
or
ecx,
0FFFFFFFFh
UPX0:
00401C80
xor eax, eax
UPX0:
00401C82
lea edx, [esp
+
230h
]
UPX0:
00401C89
repne scasb
UPX0:
00401C8B
not
ecx ; 求name长度
UPX0:
00401C8D
sub edi, ecx
UPX0:
00401C8F
mov eax, ecx
UPX0:
00401C91
mov esi, edi
UPX0:
00401C93
mov edi, edx
UPX0:
00401C95
shr ecx,
2
UPX0:
00401C98
rep movsd ; name复制到esp
+
230h
UPX0:
00401C9A
mov ecx, eax
UPX0:
00401C9C
and
ecx,
3
UPX0:
00401C9F
rep movsb
UPX0:
00401CA1
lea ecx, [esp
+
230h
]
UPX0:
00401CA8
push ecx
UPX0:
00401CA9
call __strrev ; 将name反转
UPX0:
00401CAE
lea edi, [esp
+
234h
]
UPX0:
00401CB5
or
ecx,
0FFFFFFFFh
UPX0:
00401CB8
xor eax, eax
UPX0:
00401CBA
add esp,
4
UPX0:
00401CBD
repne scasb
UPX0:
00401CBF
not
ecx ; 求反转后长度
UPX0:
00401CC1
sub edi, ecx
UPX0:
00401CC3
lea edx, [esp
+
3Ch
]
UPX0:
00401CC7
mov esi, edi
UPX0:
00401CC9
mov ebx, ecx
UPX0:
00401CCB
mov edi, edx
UPX0:
00401CCD
or
ecx,
0FFFFFFFFh
UPX0:
00401CD0
repne scasb
UPX0:
00401CD2
mov ecx, ebx
UPX0:
00401CD4
dec edi
UPX0:
00401CD5
shr ecx,
2
UPX0:
00401CD8
rep movsd ; strcat(name,strrev(name))
UPX0:
00401CDA
mov ecx, ebx
UPX0:
00401CDC
lea eax, [esp
+
18h
]
UPX0:
00401CE0
and
ecx,
3
UPX0:
00401CE3
push eax
UPX0:
00401CE4
push offset aSoftwareMicros ;
"SOFTWARE\\Microsoft\\Windows\\CurrentVe"
...
UPX0:
00401CE9
push
80000002h
UPX0:
00401CEE
rep movsb
UPX0:
00401CF0
call ds:RegOpenKeyA ; 打开注册表
UPX0:
00401CF6
mov ebx, ds:RegQueryValueExA ; 查询ProductID
UPX0:
00401CFC
lea ecx, [esp
+
14h
]
UPX0:
00401D00
lea edx, [esp
+
230h
]
UPX0:
00401D07
push ecx
UPX0:
00401D08
mov ecx, [esp
+
1Ch
]
UPX0:
00401D0C
lea eax, [esp
+
14h
]
UPX0:
00401D10
push edx
UPX0:
00401D11
push eax
UPX0:
00401D12
push
0
UPX0:
00401D14
push offset aProductid ;
"ProductID"
UPX0:
00401D19
mov dword ptr [esp
+
24h
],
1
UPX0:
00401D21
mov dword ptr [esp
+
28h
],
100h
UPX0:
00401D29
push ecx
UPX0:
00401D2A
call ebx ; RegQueryValueExA ; 查询ProductID
UPX0:
00401D2C
lea edi, [esp
+
230h
]
UPX0:
00401D33
or
ecx,
0FFFFFFFFh
UPX0:
00401D36
xor eax, eax
UPX0:
00401D38
lea edx, [esp
+
3Ch
]
UPX0:
00401D3C
repne scasb
UPX0:
00401D3E
not
ecx
UPX0:
00401D40
sub edi, ecx
UPX0:
00401D42
mov dword ptr [esp
+
10h
],
1
UPX0:
00401D4A
mov esi, edi
UPX0:
00401D4C
mov edi, edx
UPX0:
00401D4E
mov edx, ecx
UPX0:
00401D50
or
ecx,
0FFFFFFFFh
UPX0:
00401D53
repne scasb
UPX0:
00401D55
mov ecx, edx
UPX0:
00401D57
dec edi
UPX0:
00401D58
shr ecx,
2
UPX0:
00401D5B
rep movsd ; 将查询的字符串strcat到name
UPX0:
00401D5D
mov ecx, edx
UPX0:
00401D5F
lea eax, [esp
+
14h
]
UPX0:
00401D63
and
ecx,
3
UPX0:
00401D66
push eax
UPX0:
00401D67
mov eax, [esp
+
1Ch
]
UPX0:
00401D6B
lea edx, [esp
+
14h
]
UPX0:
00401D6F
rep movsb
UPX0:
00401D71
lea ecx, [esp
+
234h
]
UPX0:
00401D78
mov dword ptr [esp
+
18h
],
100h
UPX0:
00401D80
push ecx
UPX0:
00401D81
push edx
UPX0:
00401D82
push
0
UPX0:
00401D84
push offset aRegisteredowne ;
"RegisteredOwner"
UPX0:
00401D89
push eax
UPX0:
00401D8A
call ebx ; RegQueryValueExA ; 查询RegisteredOwner
UPX0:
00401D8C
lea edi, [esp
+
230h
]
UPX0:
00401D93
or
ecx,
0FFFFFFFFh
UPX0:
00401D96
xor eax, eax
UPX0:
00401D98
lea edx, [esp
+
3Ch
]
UPX0:
00401D9C
repne scasb
UPX0:
00401D9E
not
ecx ; 求注册表查询字符串长度
UPX0:
00401DA0
sub edi, ecx
UPX0:
00401DA2
mov esi, edi
UPX0:
00401DA4
mov ebx, ecx
UPX0:
00401DA6
mov edi, edx
UPX0:
00401DA8
or
ecx,
0FFFFFFFFh
UPX0:
00401DAB
repne scasb
UPX0:
00401DAD
mov ecx, ebx
UPX0:
00401DAF
dec edi
UPX0:
00401DB0
shr ecx,
2
UPX0:
00401DB3
rep movsd
UPX0:
00401DB5
mov ecx, ebx
UPX0:
00401DB7
and
ecx,
3
UPX0:
00401DBA
rep movsb ; 将查询的字符串strcat到name
UPX0:
00401DBC
lea edi, [esp
+
3Ch
] ; 由于win10缺少这几个注册表项,其得到的name
=
name
+
strrev(name)
+
strrev(name)
+
strrev(name)
UPX0:
00401DC0
or
ecx,
0FFFFFFFFh
; 如果xp下应该是 name
+
strrev(name)
+
ProducID(查询得到字符串)
+
RegisterOwner(查询的字符串)
UPX0:
00401DC3
repne scasb
UPX0:
00401DC5
not
ecx ; 求组合后的长度
UPX0:
00401DC7
lea eax, [esp
+
2Ch
]
UPX0:
00401DCB
dec ecx
UPX0:
00401DCC
push eax
UPX0:
00401DCD
mov esi, ecx
UPX0:
00401DCF
call Md5InitState ; 初始化md5的
4
个state
UPX0:
00401DD4
lea edx, [esp
+
esi
+
40h
]
UPX0:
00401DD8
mov ecx,
13h
UPX0:
00401DDD
xor eax, eax
UPX0:
00401DDF
mov edi, edx
UPX0:
00401DE1
rep stosd ; 清空name后面
19
*
4
字节
UPX0:
00401DE3
add esp,
4
UPX0:
00401DE6
inc esi
UPX0:
00401DE7
stosw
UPX0:
00401DE9
mov ecx, esi
UPX0:
00401DEB
stosb
UPX0:
00401DEC
and
ecx,
3Fh
; 对齐数据
64
UPX0:
00401DEF
mov eax,
40h
;
'@'
; 对齐数据
64
UPX0:
00401DF4
sub eax, ecx ; 对齐数据
64
UPX0:
00401DF6
mov byte ptr [edx],
80h
;
'€'
; name最后结尾赋值
0x80
UPX0:
00401DF9
cmp
eax,
7
; 对齐数据
64
UPX0:
00401DFC
jg short loc_401E01
UPX0:
00401DFE
add eax,
40h
;
'@'
; 对齐数据
64
UPX0:
00401E01
UPX0:
00401E01
loc_401E01: ; CODE XREF: UPX0:
00401DFC
↑j
UPX0:
00401E01
add esi, eax
UPX0:
00401E03
lea edi, [esp
+
3Ch
]
UPX0:
00401E07
or
ecx,
0FFFFFFFFh
UPX0:
00401E0A
xor eax, eax
UPX0:
00401E0C
repne scasb
UPX0:
00401E0E
not
ecx
UPX0:
00401E10
dec ecx
UPX0:
00401E11
xor edi, edi
UPX0:
00401E13
shl ecx,
3
; 长度
*
8
UPX0:
00401E16
test esi, esi
UPX0:
00401E18
mov [esp
+
esi
+
34h
], ecx ; 添加长度数据
UPX0:
00401E1C
jle short loc_401E37
UPX0:
00401E1E
UPX0:
00401E1E
loc_401E1E: ; CODE XREF: UPX0:
00401E35
↓j
UPX0:
00401E1E
lea edx, [esp
+
2Ch
]
UPX0:
00401E22
lea eax, [esp
+
edi
+
3Ch
]
UPX0:
00401E26
push edx
UPX0:
00401E27
push eax
UPX0:
00401E28
call Md5Transform ; md5Transform
UPX0:
00401E2D
add edi,
40h
;
'@'
; 递增
64
字节
UPX0:
00401E30
add esp,
8
UPX0:
00401E33
cmp
edi, esi
UPX0:
00401E35
jl short loc_401E1E ;
for
(i
=
0
;i < esi(对齐长度);i
+
=
64
)
UPX0:
00401E37
UPX0:
00401E37
loc_401E37: ; CODE XREF: UPX0:
00401E1C
↑j
UPX0:
00401E37
mov ebx, [esp
+
2Ch
]
UPX0:
00401E3B
lea ecx, [esp
+
28h
]
UPX0:
00401E3F
lea edx, [esp
+
24h
]
UPX0:
00401E43
push ecx
UPX0:
00401E44
lea eax, [esp
+
24h
]
UPX0:
00401E48
push edx
UPX0:
00401E49
lea ecx, [esp
+
24h
]
UPX0:
00401E4D
push eax
UPX0:
00401E4E
push ecx
UPX0:
00401E4F
lea edx, [esp
+
434h
]
UPX0:
00401E56
and
ebx,
0FFFFh
; 将state[
0
]的高位抹去
UPX0:
00401E5C
push offset aLxLxLxLx ;
"%lx%lx%lx%lx"
UPX0:
00401E61
push edx
UPX0:
00401E62
mov [esp
+
44h
], ebx
UPX0:
00401E66
call _sscanf ; 从code字符串中获取
4
个UINT数据
UPX0:
00401E6B
add esp,
18h
UPX0:
00401E6E
cmp
eax,
4
; 不够
4
个就报错
UPX0:
00401E71
jz short loc_401E91
UPX0:
00401E73
push
30h
;
'0'
UPX0:
00401E75
push offset aFailed ;
"Failed"
UPX0:
00401E7A
push offset aHmmmYouDonTEve ;
"... Hmmm, you don't even pass the first"
...
UPX0:
00401E7F
mov ecx, ebp
UPX0:
00401E81
call MfcMsgBox
UPX0:
00401E86
pop edi
UPX0:
00401E87
pop esi
UPX0:
00401E88
pop ebp
UPX0:
00401E89
pop ebx
UPX0:
00401E8A
add esp,
608h
UPX0:
00401E90
retn
UPX0:
00401E91
;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
UPX0:
00401E91
UPX0:
00401E91
loc_401E91: ; CODE XREF: UPX0:
00401E71
↑j
UPX0:
00401E91
xor esi, esi
UPX0:
00401E93
lea edi, [esp
+
1Ch
]
UPX0:
00401E97
UPX0:
00401E97
loc_401E97: ; CODE XREF: UPX0:
00401EB3
↓j
UPX0:
00401E97
mov eax,
0BADC0DEh
;
for
(i
=
0
;i <
3
;i
+
+
)
UPX0:
00401E9C
lea ecx, [esi
+
50h
]
UPX0:
00401E9F
cdq
UPX0:
00401EA0
idiv ecx ; loop_cnt
=
0xbadc0de
/
(i
+
80
)
UPX0:
00401EA2
push eax
UPX0:
00401EA3
push edi
UPX0:
00401EA4
call Encode ; 算法关键:将
4
个UINT做
3
轮ENcode
UPX0:
00401EA9
add esp,
8
UPX0:
00401EAC
inc esi
UPX0:
00401EAD
add edi,
4
UPX0:
00401EB0
cmp
esi,
3
UPX0:
00401EB3
jl short loc_401E97 ;
for
(i
=
0
;i <
3
;i
+
+
)
UPX0:
00401EB5
xor eax, eax
UPX0:
00401EB7
UPX0:
00401EB7
loc_401EB7: ; CODE XREF: UPX0:
00401EC9
↓j
UPX0:
00401EB7
mov edx, [esp
+
eax
+
1Ch
]
UPX0:
00401EBB
mov ecx, [esp
+
eax
+
2Ch
]
UPX0:
00401EBF
cmp
edx, ecx
UPX0:
00401EC1
jnz short loc_401EE9
UPX0:
00401EC3
add eax,
4
UPX0:
00401EC6
cmp
eax,
10h
UPX0:
00401EC9
jl short loc_401EB7
UPX0:
00401ECB
push
40h
;
'@'
UPX0:
00401ECD
push offset aWelcome ;
"Welcome"
UPX0:
00401ED2
push offset aManYouReGoodEn ;
"... Man, you're good enough to join COR"
...
UPX0:
00401ED7
mov ecx, ebp
UPX0:
00401ED9
call MfcMsgBox
UPX0:
00401EDE
pop edi
UPX0:
00401EDF
pop esi
UPX0:
00401EE0
pop ebp
UPX0:
00401EE1
pop ebx
UPX0:
00401EE2
add esp,
608h
UPX0:
00401EE8
retn
UPX0:
00401EE9
;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
UPX0:
00401EE9
UPX0:
00401EE9
loc_401EE9: ; CODE XREF: UPX0:
00401EC1
↑j
UPX0:
00401EE9
push
30h
;
'0'
UPX0:
00401EEB
push offset aFailed ;
"Failed"
UPX0:
00401EF0
push offset aBetterLuckNext ;
"... Better luck next time ..."
UPX0:
00401EF5
mov ecx, ebp
UPX0:
00401EF7
call MfcMsgBox
UPX0:
00401EFC
pop edi
UPX0:
00401EFD
pop esi
UPX0:
00401EFE
pop ebp
UPX0:
00401EFF
pop ebx
UPX0:
00401F00
add esp,
608h
UPX0:
00401F06
retn
UPX0:
00401C20
sub esp,
608h
UPX0:
00401C26
push ebx
UPX0:
00401C27
push ebp
UPX0:
00401C28
push esi
UPX0:
00401C29
mov ebp, ecx
UPX0:
00401C2B
push edi
UPX0:
00401C2C
mov ecx,
7Dh
;
'}'
UPX0:
00401C31
xor eax, eax
UPX0:
00401C33
lea edi, [esp
+
3Ch
]
UPX0:
00401C37
rep stosd
UPX0:
00401C39
mov ecx,
7Dh
;
'}'
UPX0:
00401C3E
lea edi, [esp
+
424h
]
UPX0:
00401C45
rep stosd
UPX0:
00401C47
mov ecx,
7Dh
;
'}'
UPX0:
00401C4C
lea edi, [esp
+
230h
]
UPX0:
00401C53
rep stosd
UPX0:
00401C55
lea eax, [esp
+
3Ch
]
UPX0:
00401C59
push
64h
;
'd'
UPX0:
00401C5B
push eax
UPX0:
00401C5C
lea ecx, [ebp
+
5Ch
]
UPX0:
00401C5F
call MfcGetText ; 获取Name的字符串 name
=
esp
+
3c
UPX0:
00401C64
lea ecx, [esp
+
424h
]
UPX0:
00401C6B
push
64h
;
'd'
UPX0:
00401C6D
push ecx
UPX0:
00401C6E
lea ecx, [ebp
+
0ACh
]
UPX0:
00401C74
call MfcGetText ; 获取Code的字符串存在 esp
+
0x424
UPX0:
00401C79
lea edi, [esp
+
3Ch
]
UPX0:
00401C7D
or
ecx,
0FFFFFFFFh
UPX0:
00401C80
xor eax, eax
UPX0:
00401C82
lea edx, [esp
+
230h
]
UPX0:
00401C89
repne scasb
UPX0:
00401C8B
not
ecx ; 求name长度
UPX0:
00401C8D
sub edi, ecx
UPX0:
00401C8F
mov eax, ecx
UPX0:
00401C91
mov esi, edi
UPX0:
00401C93
mov edi, edx
UPX0:
00401C95
shr ecx,
2
UPX0:
00401C98
rep movsd ; name复制到esp
+
230h
UPX0:
00401C9A
mov ecx, eax
UPX0:
00401C9C
and
ecx,
3
UPX0:
00401C9F
rep movsb
UPX0:
00401CA1
lea ecx, [esp
+
230h
]
UPX0:
00401CA8
push ecx
UPX0:
00401CA9
call __strrev ; 将name反转
UPX0:
00401CAE
lea edi, [esp
+
234h
]
UPX0:
00401CB5
or
ecx,
0FFFFFFFFh
UPX0:
00401CB8
xor eax, eax
UPX0:
00401CBA
add esp,
4
UPX0:
00401CBD
repne scasb
UPX0:
00401CBF
not
ecx ; 求反转后长度
UPX0:
00401CC1
sub edi, ecx
UPX0:
00401CC3
lea edx, [esp
+
3Ch
]
UPX0:
00401CC7
mov esi, edi
UPX0:
00401CC9
mov ebx, ecx
UPX0:
00401CCB
mov edi, edx
UPX0:
00401CCD
or
ecx,
0FFFFFFFFh
UPX0:
00401CD0
repne scasb
UPX0:
00401CD2
mov ecx, ebx
UPX0:
00401CD4
dec edi
UPX0:
00401CD5
shr ecx,
2
UPX0:
00401CD8
rep movsd ; strcat(name,strrev(name))
UPX0:
00401CDA
mov ecx, ebx
UPX0:
00401CDC
lea eax, [esp
+
18h
]
UPX0:
00401CE0
and
ecx,
3
UPX0:
00401CE3
push eax
UPX0:
00401CE4
push offset aSoftwareMicros ;
"SOFTWARE\\Microsoft\\Windows\\CurrentVe"
...
UPX0:
00401CE9
push
80000002h
UPX0:
00401CEE
rep movsb
UPX0:
00401CF0
call ds:RegOpenKeyA ; 打开注册表
UPX0:
00401CF6
mov ebx, ds:RegQueryValueExA ; 查询ProductID
UPX0:
00401CFC
lea ecx, [esp
+
14h
]
UPX0:
00401D00
lea edx, [esp
+
230h
]
UPX0:
00401D07
push ecx
UPX0:
00401D08
mov ecx, [esp
+
1Ch
]
UPX0:
00401D0C
lea eax, [esp
+
14h
]
UPX0:
00401D10
push edx
UPX0:
00401D11
push eax
UPX0:
00401D12
push
0
UPX0:
00401D14
push offset aProductid ;
"ProductID"
UPX0:
00401D19
mov dword ptr [esp
+
24h
],
1
UPX0:
00401D21
mov dword ptr [esp
+
28h
],
100h
UPX0:
00401D29
push ecx
UPX0:
00401D2A
call ebx ; RegQueryValueExA ; 查询ProductID
UPX0:
00401D2C
lea edi, [esp
+
230h
]
UPX0:
00401D33
or
ecx,
0FFFFFFFFh
UPX0:
00401D36
xor eax, eax
UPX0:
00401D38
lea edx, [esp
+
3Ch
]
UPX0:
00401D3C
repne scasb
UPX0:
00401D3E
not
ecx
UPX0:
00401D40
sub edi, ecx
UPX0:
00401D42
mov dword ptr [esp
+
10h
],
1
UPX0:
00401D4A
mov esi, edi
UPX0:
00401D4C
mov edi, edx
UPX0:
00401D4E
mov edx, ecx
UPX0:
00401D50
or
ecx,
0FFFFFFFFh
UPX0:
00401D53
repne scasb
UPX0:
00401D55
mov ecx, edx
UPX0:
00401D57
dec edi
UPX0:
00401D58
shr ecx,
2
UPX0:
00401D5B
rep movsd ; 将查询的字符串strcat到name
UPX0:
00401D5D
mov ecx, edx
UPX0:
00401D5F
lea eax, [esp
+
14h
]
UPX0:
00401D63
and
ecx,
3
UPX0:
00401D66
push eax
UPX0:
00401D67
mov eax, [esp
+
1Ch
]
UPX0:
00401D6B
lea edx, [esp
+
14h
]
UPX0:
00401D6F
rep movsb
UPX0:
00401D71
lea ecx, [esp
+
234h
]
UPX0:
00401D78
mov dword ptr [esp
+
18h
],
100h
UPX0:
00401D80
push ecx
UPX0:
00401D81
push edx
UPX0:
00401D82
push
0
UPX0:
00401D84
push offset aRegisteredowne ;
"RegisteredOwner"
UPX0:
00401D89
push eax
UPX0:
00401D8A
call ebx ; RegQueryValueExA ; 查询RegisteredOwner
UPX0:
00401D8C
lea edi, [esp
+
230h
]
UPX0:
00401D93
or
ecx,
0FFFFFFFFh
UPX0:
00401D96
xor eax, eax
UPX0:
00401D98
lea edx, [esp
+
3Ch
]
UPX0:
00401D9C
repne scasb
UPX0:
00401D9E
not
ecx ; 求注册表查询字符串长度
UPX0:
00401DA0
sub edi, ecx
UPX0:
00401DA2
mov esi, edi
UPX0:
00401DA4
mov ebx, ecx
UPX0:
00401DA6
mov edi, edx
UPX0:
00401DA8
or
ecx,
0FFFFFFFFh
UPX0:
00401DAB
repne scasb
UPX0:
00401DAD
mov ecx, ebx
UPX0:
00401DAF
dec edi
UPX0:
00401DB0
shr ecx,
2
UPX0:
00401DB3
rep movsd
UPX0:
00401DB5
mov ecx, ebx
UPX0:
00401DB7
and
ecx,
3
UPX0:
00401DBA
rep movsb ; 将查询的字符串strcat到name
UPX0:
00401DBC
lea edi, [esp
+
3Ch
] ; 由于win10缺少这几个注册表项,其得到的name
=
name
+
strrev(name)
+
strrev(name)
+
strrev(name)
UPX0:
00401DC0
or
ecx,
0FFFFFFFFh
; 如果xp下应该是 name
+
strrev(name)
+
ProducID(查询得到字符串)
+
RegisterOwner(查询的字符串)
UPX0:
00401DC3
repne scasb
UPX0:
00401DC5
not
ecx ; 求组合后的长度
UPX0:
00401DC7
lea eax, [esp
+
2Ch
]
UPX0:
00401DCB
dec ecx
UPX0:
00401DCC
push eax
UPX0:
00401DCD
mov esi, ecx
UPX0:
00401DCF
call Md5InitState ; 初始化md5的
4
个state
UPX0:
00401DD4
lea edx, [esp
+
esi
+
40h
]
UPX0:
00401DD8
mov ecx,
13h
UPX0:
00401DDD
xor eax, eax
UPX0:
00401DDF
mov edi, edx
UPX0:
00401DE1
rep stosd ; 清空name后面
19
*
4
字节
UPX0:
00401DE3
add esp,
4
UPX0:
00401DE6
inc esi
UPX0:
00401DE7
stosw
UPX0:
00401DE9
mov ecx, esi
UPX0:
00401DEB
stosb
UPX0:
00401DEC
and
ecx,
3Fh
; 对齐数据
64
UPX0:
00401DEF
mov eax,
40h
;
'@'
; 对齐数据
64
UPX0:
00401DF4
sub eax, ecx ; 对齐数据
64
UPX0:
00401DF6
mov byte ptr [edx],
80h
;
'€'
; name最后结尾赋值
0x80
UPX0:
00401DF9
cmp
eax,
7
; 对齐数据
64
UPX0:
00401DFC
jg short loc_401E01
UPX0:
00401DFE
add eax,
40h
;
'@'
; 对齐数据
64
UPX0:
00401E01
UPX0:
00401E01
loc_401E01: ; CODE XREF: UPX0:
00401DFC
↑j
UPX0:
00401E01
add esi, eax
UPX0:
00401E03
lea edi, [esp
+
3Ch
]
UPX0:
00401E07
or
ecx,
0FFFFFFFFh
UPX0:
00401E0A
xor eax, eax
UPX0:
00401E0C
repne scasb
UPX0:
00401E0E
not
ecx
UPX0:
00401E10
dec ecx
UPX0:
00401E11
xor edi, edi
UPX0:
00401E13
shl ecx,
3
; 长度
*
8
UPX0:
00401E16
test esi, esi
UPX0:
00401E18
mov [esp
+
esi
+
34h
], ecx ; 添加长度数据
UPX0:
00401E1C
jle short loc_401E37
UPX0:
00401E1E
UPX0:
00401E1E
loc_401E1E: ; CODE XREF: UPX0:
00401E35
↓j
UPX0:
00401E1E
lea edx, [esp
+
2Ch
]
UPX0:
00401E22
lea eax, [esp
+
edi
+
3Ch
]
UPX0:
00401E26
push edx
UPX0:
00401E27
push eax
UPX0:
00401E28
call Md5Transform ; md5Transform
UPX0:
00401E2D
add edi,
40h
;
'@'
; 递增
64
字节
UPX0:
00401E30
add esp,
8
UPX0:
00401E33
cmp
edi, esi
UPX0:
00401E35
jl short loc_401E1E ;
for
(i
=
0
;i < esi(对齐长度);i
+
=
64
)
UPX0:
00401E37
UPX0:
00401E37
loc_401E37: ; CODE XREF: UPX0:
00401E1C
↑j
UPX0:
00401E37
mov ebx, [esp
+
2Ch
]
UPX0:
00401E3B
lea ecx, [esp
+
28h
]
UPX0:
00401E3F
lea edx, [esp
+
24h
]
UPX0:
00401E43
push ecx
UPX0:
00401E44
lea eax, [esp
+
24h
]
UPX0:
00401E48
push edx
UPX0:
00401E49
lea ecx, [esp
+
24h
]
UPX0:
00401E4D
push eax
UPX0:
00401E4E
push ecx
UPX0:
00401E4F
lea edx, [esp
+
434h
]
UPX0:
00401E56
and
ebx,
0FFFFh
; 将state[
0
]的高位抹去
UPX0:
00401E5C
push offset aLxLxLxLx ;
"%lx%lx%lx%lx"
UPX0:
00401E61
push edx
UPX0:
00401E62
mov [esp
+
44h
], ebx
UPX0:
00401E66
call _sscanf ; 从code字符串中获取
4
个UINT数据
UPX0:
00401E6B
add esp,
18h
UPX0:
00401E6E
cmp
eax,
4
; 不够
4
个就报错
UPX0:
00401E71
jz short loc_401E91
UPX0:
00401E73
push
30h
;
'0'
UPX0:
00401E75
push offset aFailed ;
"Failed"
UPX0:
00401E7A
push offset aHmmmYouDonTEve ;
"... Hmmm, you don't even pass the first"
...
UPX0:
00401E7F
mov ecx, ebp
UPX0:
00401E81
call MfcMsgBox
UPX0:
00401E86
pop edi
UPX0:
00401E87
pop esi
UPX0:
00401E88
pop ebp
UPX0:
00401E89
pop ebx
UPX0:
00401E8A
add esp,
608h
UPX0:
00401E90
retn
UPX0:
00401E91
;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
UPX0:
00401E91
UPX0:
00401E91
loc_401E91: ; CODE XREF: UPX0:
00401E71
↑j
UPX0:
00401E91
xor esi, esi
UPX0:
00401E93
lea edi, [esp
+
1Ch
]
UPX0:
00401E97
UPX0:
00401E97
loc_401E97: ; CODE XREF: UPX0:
00401EB3
↓j
UPX0:
00401E97
mov eax,
0BADC0DEh
;
for
(i
=
0
;i <
3
;i
+
+
)
UPX0:
00401E9C
lea ecx, [esi
+
50h
]
UPX0:
00401E9F
cdq
UPX0:
00401EA0
idiv ecx ; loop_cnt
=
0xbadc0de
/
(i
+
80
)
UPX0:
00401EA2
push eax
UPX0:
00401EA3
push edi
UPX0:
00401EA4
call Encode ; 算法关键:将
4
个UINT做
3
轮ENcode
UPX0:
00401EA9
add esp,
8
UPX0:
00401EAC
inc esi
UPX0:
00401EAD
add edi,
4
UPX0:
00401EB0
cmp
esi,
3
UPX0:
00401EB3
jl short loc_401E97 ;
for
(i
=
0
;i <
3
;i
+
+
)
UPX0:
00401EB5
xor eax, eax
UPX0:
00401EB7
UPX0:
00401EB7
loc_401EB7: ; CODE XREF: UPX0:
00401EC9
↓j
UPX0:
00401EB7
mov edx, [esp
+
eax
+
1Ch
]
UPX0:
00401EBB
mov ecx, [esp
+
eax
+
2Ch
]
UPX0:
00401EBF
cmp
edx, ecx
UPX0:
00401EC1
jnz short loc_401EE9
UPX0:
00401EC3
add eax,
4
UPX0:
00401EC6
cmp
eax,
10h
UPX0:
00401EC9
jl short loc_401EB7
UPX0:
00401ECB
push
40h
;
'@'
UPX0:
00401ECD
push offset aWelcome ;
"Welcome"
UPX0:
00401ED2
push offset aManYouReGoodEn ;
"... Man, you're good enough to join COR"
...
UPX0:
00401ED7
mov ecx, ebp
UPX0:
00401ED9
call MfcMsgBox
UPX0:
00401EDE
pop edi
UPX0:
00401EDF
pop esi
UPX0:
00401EE0
pop ebp
UPX0:
00401EE1
pop ebx
UPX0:
00401EE2
add esp,
608h
UPX0:
00401EE8
retn
UPX0:
00401EE9
;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
UPX0:
00401EE9
UPX0:
00401EE9
loc_401EE9: ; CODE XREF: UPX0:
00401EC1
↑j
UPX0:
00401EE9
push
30h
;
'0'
UPX0:
00401EEB
push offset aFailed ;
"Failed"
UPX0:
00401EF0
push offset aBetterLuckNext ;
"... Better luck next time ..."
UPX0:
00401EF5
mov ecx, ebp
UPX0:
00401EF7
call MfcMsgBox
UPX0:
00401EFC
pop edi
UPX0:
00401EFD
pop esi
UPX0:
00401EFE
pop ebp
UPX0:
00401EFF
pop ebx
UPX0:
00401F00
add esp,
608h
UPX0:
00401F06
retn
UPX0:
00401B90
Encode proc near ; CODE XREF: UPX0:
00401EA4
↓p
UPX0:
00401B90
UPX0:
00401B90
arg_0
=
dword ptr
4
UPX0:
00401B90
arg_4
=
dword ptr
8
UPX0:
00401B90
UPX0:
00401B90
mov eax, [esp
+
arg_0]
UPX0:
00401B94
push ebx
UPX0:
00401B95
mov ebx, [esp
+
4
+
arg_4]
UPX0:
00401B99
push esi
UPX0:
00401B9A
mov esi, [eax]
UPX0:
00401B9C
push edi
UPX0:
00401B9D
mov edi, [eax
+
4
]
UPX0:
00401BA0
test ebx, ebx
UPX0:
00401BA2
jbe short loc_401C15
UPX0:
00401BA4
push ebp ; edi
=
高
32
位UINT
UPX0:
00401BA4
; esi
=
低
32
位UINT
UPX0:
00401BA5
UPX0:
00401BA5
loc_401BA5: ; CODE XREF: Encode
+
7E
↓j
UPX0:
00401BA5
mov ebp, edi ;
for
(i
=
0
;i<loop_cnt;i
+
+
)
UPX0:
00401BA5
; 第一步就是实现
2
个UINT的循环左移
1
位
UPX0:
00401BA7
mov ecx,
1
UPX0:
00401BAC
shr ebp,
1Fh
UPX0:
00401BAF
mov [esp
+
10h
+
arg_4], ebp ; 取高
32
位最高位,保存一下
UPX0:
00401BB3
mov eax, esi
UPX0:
00401BB5
mov edx, edi
UPX0:
00401BB7
xor ebp, ebp
UPX0:
00401BB9
call __allshl ;
2
个UINT实现左移
1
位
UPX0:
00401BBE
mov ecx, [esp
+
10h
+
arg_4] ; 再将保存的的高
32
位的最高一位给低
32
位的最低位,实现循环左移
UPX0:
00401BC2
or
ebp, edx
UPX0:
00401BC4
or
ecx, eax
UPX0:
00401BC6
xor edx, edx
UPX0:
00401BC8
mov esi, ecx ; 循环左移结束
UPX0:
00401BCA
mov ecx,
0Bh
; 后面就是取低
32
位的第
2
13
31
位做亦或
UPX0:
00401BCF
mov eax, esi
UPX0:
00401BD1
mov edi, ebp
UPX0:
00401BD3
and
eax,
4
; 取低
32
位数据
2
位
UPX0:
00401BD6
call __allshl ; 循环做移动
11
位
11
+
2
=
13
位
UPX0:
00401BDB
mov ecx, esi
UPX0:
00401BDD
xor ebp, ebp
UPX0:
00401BDF
and
ecx,
2000h
; 取低
32
位数据
13
位
UPX0:
00401BE5
xor edx, ebp
UPX0:
00401BE7
xor eax, ecx ; 然后 亦或
UPX0:
00401BE9
mov ecx,
12h
; 循环做移动
18
位
13
+
18
=
31
位
UPX0:
00401BEE
call __allshl
UPX0:
00401BF3
mov ecx, esi
UPX0:
00401BF5
xor edx, ebp
UPX0:
00401BF7
and
ecx,
80000000h
; 取低
32
位数据
31
位
UPX0:
00401BFD
xor eax, ecx ; eax
=
eax ^
31
位的值
UPX0:
00401BFF
mov ecx,
1
UPX0:
00401C04
call __allshl ; 左移动一位将,亦或结果存入edx
UPX0:
00401C09
xor esi, eax ; eax 不管是
0
还是
0x8000000
左移
1
位后总是
0
UPX0:
00401C0B
xor edi, edx ; 高
32
位的最后一位和亦或结果做亦或
UPX0:
00401C0D
dec ebx
UPX0:
00401C0E
jnz short loc_401BA5 ;
for
(i
=
0
;i<loop_cnt;i
+
+
)
UPX0:
00401C0E
; 第一步就是实现
2
个UINT的循环左移
1
位
UPX0:
00401C10
mov eax, [esp
+
10h
+
arg_0]
UPX0:
00401C14
pop ebp
UPX0:
00401C15
UPX0:
00401C15
loc_401C15: ; CODE XREF: Encode
+
12
↑j
UPX0:
00401C15
mov [eax], esi
UPX0:
00401C17
mov [eax
+
4
], edi
UPX0:
00401C1A
pop edi
UPX0:
00401C1B
pop esi
UPX0:
00401C1C
pop ebx
UPX0:
00401C1D
retn
UPX0:
00401C1D
Encode endp
UPX0:
00401B90
Encode proc near ; CODE XREF: UPX0:
00401EA4
↓p
UPX0:
00401B90
UPX0:
00401B90
arg_0
=
dword ptr
4
UPX0:
00401B90
arg_4
=
dword ptr
8
UPX0:
00401B90
UPX0:
00401B90
mov eax, [esp
+
arg_0]
UPX0:
00401B94
push ebx
UPX0:
00401B95
mov ebx, [esp
+
4
+
arg_4]
UPX0:
00401B99
push esi
UPX0:
00401B9A
mov esi, [eax]
UPX0:
00401B9C
push edi
UPX0:
00401B9D
mov edi, [eax
+
4
]
UPX0:
00401BA0
test ebx, ebx
UPX0:
00401BA2
jbe short loc_401C15
UPX0:
00401BA4
push ebp ; edi
=
高
32
位UINT
UPX0:
00401BA4
; esi
=
低
32
位UINT
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!