-
-
[原创]看雪 2022·KCTF 春季赛 > 第五题 危机四伏 by 心学
-
发表于: 2022-6-12 21:16 13062
-
日期:2022-06-12
CTF:htg
题目:看雪 2022·KCTF 春季赛 > 第五题 危机四伏
工具:IDA、Windbg
要点:C++异常处理机制、32与64bit代码切换、代码混淆
【C++反汇编与逆向分析技术揭秘】
在X64系统下的进程有32位和64位两种工作模式,这两种工作模式的区别在于CS寄存器。32模式时,CS=0x23;64位模式时,CS=0x33。
这两种工作模式可以进行切换,一般通过retf指令。retf指令等效于2条汇编指令pop ip、pop cs。
如果此时栈中有0x33,则会将0x33弹出到CS寄存器中,实现32位程序切换到64位代码的过程。反之,如果栈中有0x23,将0x23弹出到CS寄存器,则实现64位程序切换到32位代码的过程。
识别32位、64位工作模式切换的两个标志:
(1)出现retf、0x23或0x33。
(2)使用类似call fword的远处调用,譬如call fword ptr [ebp-0xC]。
无法F5转换C伪代码
建立主函数的异常处理结构体
运行调试后,出现了异常,无法继续进行。
分析模式切换的代码,搞清楚32转64,64转32的执行机制,以及代码切换位置
##############################################################
定位关键的位置,找出运行成功前的所有分支判断
【起始阶段】全局变量初始值
【数据分析】初始值
【第一阶段】解密
bp 00401E94; ecx 存储 解密地址
bp 00401E99; 使用 IDC 执行
////////////////////////////////////////////【ecx 修改】begin
////////////////////////////////////////////
【第一阶段】全局变量
bp 00401F0D;
////////////////////////////////////////////
////////////////////////////////////////////
【数据分析】第一阶段执行之后
////////////////////////////////////////////
////////////////////////////////////////////
【第二阶段】解密
bp 00401F9C; ecx 存储 解密地址
bp 00401FA1;
////////////////////////////////////////////【ecx 修改】begin
////////////////////////////////////////////
【第二阶段】全局变量
bp 00401FF9;
////////////////////////////////////////////
////////////////////////////////////////////
【数据分析】第二阶段执行之后
////////////////////////////////////////////
////////////////////////////////////////////
【第三阶段】解密
bp 004020CE; ecx 存储 解密地址
bp 004020D3;
////////////////////////////////////////////【ecx 修改】begin
////////////////////////////////////////////
////////////////////////////////////////////
【第三阶段】全局变量
bp 00402194;
////////////////////////////////////////////
【数据分析】第三阶段执行之后
对dump出来的三处代码,分别进行分析,去除混淆,理清主要的加密机制
回顾代码,理清题目的主体结构。
(未完待续)
(未完待续)
.rdata:
00427050
FuncInfo1 FuncInfo <
19930522h
,
19h
, offset stru_427078,
0Ch
, offset stru_427140,\
.rdata:
00427050
; DATA XREF: .text:
0041C000
↑o
.rdata:
00427050
0
,
0
,
0
,
1
>
#############################
.rdata:
00427140
stru_427140 TryBlockMapEntry <
1
,
1
,
2
,
2
, offset stru_427230> __msRttiDscr <
9
,
00892A20
,
0
,
401D04h
>
.rdata:
00427140
; DATA XREF: .rdata:FuncInfo1↑o
.rdata:
00427140
TryBlockMapEntry <
7
,
7
,
8
,
1
, offset stru_427230.nFlag
+
20h
> __msRttiDscr <
0
,
00892A10
,
0FFFFFD10h
,
401F6Eh
>
.rdata:
00427140
TryBlockMapEntry <
9
,
9
,
0Ah
,
1
, offset stru_427230.nFlag
+
30h
> __msRttiDscr <
9
,
00892A20
,
0
,
401FEEh
>
.rdata:
00427140
TryBlockMapEntry <
0Dh
,
0Dh
,
0Eh
,
1
, offset stru_427230.nFlag
+
40h
> __msRttiDscr <
9
,
00892A20
,
0
,
4020D8h
>
.rdata:
00427140
TryBlockMapEntry <
0Bh
,
0Bh
,
0Eh
,
1
, offset stru_427230.nFlag
+
50h
> __msRttiDscr <
0
,
008929FC
,
0FFFFFCC8h
,
402089h
>
.rdata:
00427140
TryBlockMapEntry <
13h
,
13h
,
14h
,
1
, offset stru_427230.nFlag
+
60h
> __msRttiDscr <
9
,
00892A20
,
0
,
402211h
>
.rdata:
00427140
TryBlockMapEntry <
11h
,
11h
,
14h
,
1
, offset stru_427230.nFlag
+
70h
> __msRttiDscr <
0
,
00892A3C
,
0FFFFFD4Fh
,
4021D2h
>
.rdata:
00427140
TryBlockMapEntry <
17h
,
17h
,
18h
,
2
, offset stru_427230.nFlag
+
80h
> __msRttiDscr <
9
,
00892A20
,
0
,
402321h
>
.rdata:
00427140
TryBlockMapEntry <
15h
,
15h
,
18h
,
1
, offset stru_427230.nFlag
+
0A0h
> __msRttiDscr <
0
,
008929C4
,
0FFFFFCD0h
,
402289h
>
.rdata:
00427140
TryBlockMapEntry <
0Fh
,
0Fh
,
18h
,
1
, offset stru_427230.nFlag
+
0B0h
> __msRttiDscr <
0
,
008929FC
,
0FFFFFCC4h
,
40213Ch
>
.rdata:
00427140
TryBlockMapEntry <
5
,
5
,
18h
,
1
, offset stru_427230.nFlag
+
0C0h
> __msRttiDscr <
0
,
008929FC
,
0FFFFFCCCh
,
401EDEh
>
.rdata:
00427140
TryBlockMapEntry <
3
,
3
,
18h
,
1
, offset stru_427230.nFlag
+
0D0h
> __msRttiDscr <
0
,
00892A10
,
0FFFFFD20h
,
401E63h
>
throw 会找到 __msRttiDscr ,可能存在多个同样的,如何区分了,查看 tryLow、tryHight、catchHigh进行比对,就是看作用域
#############################
.rdata:
00427230
stru_427230 __msRttiDscr <
9
,
00892A20
,
0
,
401D04h
>
/
/
class
std::exception
.rdata:
00427230
; DATA XREF: .rdata:stru_427140↑o
.rdata:
00427230
__msRttiDscr <
0
,
008929F0
,
0FFFFFCC0h
,
401DACh
>
/
/
int
`RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
0
,
00892A10
,
0FFFFFD10h
,
401F6Eh
>
/
/
unsigned char
*
`RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
9
,
00892A20
,
0
,
401FEEh
>
/
/
class
std::exception
.rdata:
00427230
__msRttiDscr <
9
,
00892A20
,
0
,
4020D8h
>
/
/
class
std::exception
.rdata:
00427230
__msRttiDscr <
0
,
008929FC
,
0FFFFFCC8h
,
402089h
>
/
/
void (__cdecl
*
)(unsigned char
*
) `RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
9
,
00892A20
,
0
,
402211h
>
/
/
class
std::exception
.rdata:
00427230
__msRttiDscr <
0
,
00892A3C
,
0FFFFFD4Fh
,
4021D2h
>
/
/
bool
`RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
9
,
00892A20
,
0
,
402321h
>
/
/
class
std::exception
.rdata:
00427230
__msRttiDscr <
40h
,
0
,
0
,
402349h
>
/
/
.rdata:
00427230
__msRttiDscr <
0
,
008929C4
,
0FFFFFCD0h
,
402289h
>
/
/
void
*
`RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
0
,
008929FC
,
0FFFFFCC4h
,
40213Ch
>
/
/
void (__cdecl
*
)(unsigned char
*
) `RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
0
,
008929FC
,
0FFFFFCCCh
,
401EDEh
>
/
/
void (__cdecl
*
)(unsigned char
*
) `RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
0
,
00892A10
,
0FFFFFD20h
,
401E63h
>
/
/
unsigned char
*
`RTTI
Type
Descriptor'
#############################
.data:
00892A20
; public
class
std::exception
/
*
mdisp:
0
*
/
.data:
00892A20
;
class
std::exception `RTTI
Type
Descriptor'
.data:
00892A20
??_R0?AVexception@std@@@
8
dd offset off_41D184
.data:
00892A20
; DATA XREF: .rdata:
00426CA0
↑o
.data:
00892A20
; .rdata:std::exception::`RTTI Base Class Descriptor at (
0
,
-
1
,
0
,
64
)'↑o ...
.data:
00892A20
; reference to RTTI's vftable
.data:
00892A24
dd
0
; internal runtime reference
.data:
00892A28
aAvexceptionStd db
'.?AVexception@std@@'
,
0
;
type
descriptor name
#############################
.data:
008929F0
;
int
`RTTI
Type
Descriptor'
.data:
008929F0
??_R0H@
8
dd offset off_41D184 ; DATA XREF: .rdata:
004279F4
↑o
.data:
008929F0
; reference to RTTI's vftable
.data:
008929F4
dd
0
; internal runtime reference
.data:
008929F8
db
'.H'
,
0
;
type
descriptor name
#############################
.data:
00892A10
; unsigned char
*
`RTTI
Type
Descriptor'
.data:
00892A10
??_R0PAE@
8
dd offset off_41D184 ; DATA XREF: .rdata:
0042793C
↑o
.data:
00892A10
; reference to RTTI's vftable
.data:
00892A14
dd
0
; internal runtime reference
.data:
00892A18
aPae db
'.PAE'
,
0
;
type
descriptor name
.data:
00892A1D
align
10h
#############################
.data:
008929FC
; void (__cdecl
*
)(unsigned char
*
) `RTTI
Type
Descriptor'
.data:
008929FC
??_R0P6AXPAE@Z@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427958
↑o
.data:
008929FC
; reference to RTTI's vftable
.data:
00892A00
dd
0
; internal runtime reference
.data:
00892A04
aP6axpaeZ db
'.P6AXPAE@Z'
,
0
;
type
descriptor name
#############################
.data:
00892A3C
;
bool
`RTTI
Type
Descriptor'
.data:
00892A3C
??_R0_N@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427A10
↑o
.data:
00892A3C
; reference to RTTI's vftable
#############################
.data:
008929C4
; void
*
`RTTI
Type
Descriptor'
.data:
008929C4
??_R0PAX@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427910
↑o
.data:
008929C4
; reference to RTTI's vftable
.data:
008929C8
dd
0
; internal runtime reference
.data:
008929CC
aPax db
'.PAX'
,
0
;
type
descriptor name
#############################
#############################
.data:
008929A4
; public
class
std::bad_exception
/
*
mdisp:
0
*
/
:
.data:
008929A4
; public
class
std::exception
/
*
mdisp:
0
*
/
.data:
008929A4
;
class
std::bad_exception `RTTI
Type
Descriptor'
.data:
008929A4
??_R0?AVbad_exception@std@@@
8
dd offset off_41D184
.data:
008929A4
; DATA XREF: FindHandler<__FrameHandler3>(EHExceptionRecord
*
,EHRegistrationNode
*
,_CONTEXT
*
,void
*
,_s_FuncInfo const
*
,uchar,
int
,EHRegistrationNode
*
)
+
116
↑o
.data:
008929A4
; .rdata:
00426C54
↑o ...
.data:
008929A4
; reference to RTTI's vftable
.data:
008929A8
dd
0
; internal runtime reference
.data:
008929AC
aAvbadException db
'.?AVbad_exception@std@@'
,
0
;
type
descriptor name
.data:
008929C4
; void
*
`RTTI
Type
Descriptor'
.data:
008929C4
??_R0PAX@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427910
↑o
.data:
008929C4
; reference to RTTI's vftable
.data:
008929C8
dd
0
; internal runtime reference
.data:
008929CC
aPax db
'.PAX'
,
0
;
type
descriptor name
.data:
008929D1
align
4
.data:
008929D4
; public
class
std::bad_alloc
/
*
mdisp:
0
*
/
:
.data:
008929D4
; public
class
std::exception
/
*
mdisp:
0
*
/
.data:
008929D4
;
class
std::bad_alloc `RTTI
Type
Descriptor'
.data:
008929D4
??_R0?AVbad_alloc@std@@@
8
dd offset off_41D184
.data:
008929D4
; DATA XREF: .rdata:std::bad_alloc::`RTTI Base Class Descriptor at (
0
,
-
1
,
0
,
64
)'↑o
.data:
008929D4
; .rdata:
00426D20
↑o ...
.data:
008929D4
; reference to RTTI's vftable
.data:
008929D8
dd
0
; internal runtime reference
.data:
008929DC
aAvbadAllocStd db
'.?AVbad_alloc@std@@'
,
0
;
type
descriptor name
.data:
008929F0
;
int
`RTTI
Type
Descriptor'
.data:
008929F0
??_R0H@
8
dd offset off_41D184 ; DATA XREF: .rdata:
004279F4
↑o
.data:
008929F0
; reference to RTTI's vftable
.data:
008929F4
dd
0
; internal runtime reference
.data:
008929F8
db
'.H'
,
0
;
type
descriptor name
.data:
008929FB
align
4
.data:
008929FC
; void (__cdecl
*
)(unsigned char
*
) `RTTI
Type
Descriptor'
.data:
008929FC
??_R0P6AXPAE@Z@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427958
↑o
.data:
008929FC
; reference to RTTI's vftable
.data:
00892A00
dd
0
; internal runtime reference
.data:
00892A04
aP6axpaeZ db
'.P6AXPAE@Z'
,
0
;
type
descriptor name
.data:
00892A0F
align
10h
.data:
00892A10
; unsigned char
*
`RTTI
Type
Descriptor'
.data:
00892A10
??_R0PAE@
8
dd offset off_41D184 ; DATA XREF: .rdata:
0042793C
↑o
.data:
00892A10
; reference to RTTI's vftable
.data:
00892A14
dd
0
; internal runtime reference
.data:
00892A18
aPae db
'.PAE'
,
0
;
type
descriptor name
.data:
00892A1D
align
10h
.data:
00892A20
; public
class
std::exception
/
*
mdisp:
0
*
/
.data:
00892A20
;
class
std::exception `RTTI
Type
Descriptor'
.data:
00892A20
??_R0?AVexception@std@@@
8
dd offset off_41D184
.data:
00892A20
; DATA XREF: .rdata:
00426CA0
↑o
.data:
00892A20
; .rdata:std::exception::`RTTI Base Class Descriptor at (
0
,
-
1
,
0
,
64
)'↑o ...
.data:
00892A20
; reference to RTTI's vftable
.data:
00892A24
dd
0
; internal runtime reference
.data:
00892A28
aAvexceptionStd db
'.?AVexception@std@@'
,
0
;
type
descriptor name
.data:
00892A3C
;
bool
`RTTI
Type
Descriptor'
.data:
00892A3C
??_R0_N@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427A10
↑o
.data:
00892A3C
; reference to RTTI's vftable
.data:
00892A40
dd
0
; internal runtime reference
.data:
00892A44
aN db
'._N'
,
0
;
type
descriptor name
.data:
00892A48
; public
class
std::bad_array_new_length
/
*
mdisp:
0
*
/
:
.data:
00892A48
; public
class
std::bad_alloc
/
*
mdisp:
0
*
/
:
.data:
00892A48
; public
class
std::exception
/
*
mdisp:
0
*
/
.data:
00892A48
;
class
std::bad_array_new_length `RTTI
Type
Descriptor'
.data:
00892A48
??_R0?AVbad_array_new_length@std@@@
8
dd offset off_41D184
.data:
00892A48
; DATA XREF: .rdata:
00426D54
↑o
.data:
00892A48
; .rdata:std::bad_array_new_length::`RTTI Base Class Descriptor at (
0
,
-
1
,
0
,
64
)'↑o ...
.data:
00892A48
; reference to RTTI's vftable
.data:
00892A4C
dd
0
; internal runtime reference
.data:
00892A50
aAvbadArrayNewL db
'.?AVbad_array_new_length@std@@'
,
0
;
type
descriptor name
.data:
00892A6F
align
10h
.data:
00892A70
; public
class
type_info
/
*
mdisp:
0
*
/
.data:
00892A70
;
class
type_info `RTTI
Type
Descriptor'
.data:
00892A70
??_R0?AVtype_info@@@
8
dd offset off_41D184
.data:
00892A70
; DATA XREF: .rdata:
00426C0C
↑o
.data:
00892A70
; .rdata:type_info::`RTTI Base Class Descriptor at (
0
,
-
1
,
0
,
64
)'↑o
.data:
00892A70
; reference to RTTI's vftable
.data:
00892A74
dd
0
; internal runtime reference
.data:
00892A78
aAvtypeInfo db
'.?AVtype_info@@'
,
0
;
type
descriptor name
.rdata:
00427050
FuncInfo1 FuncInfo <
19930522h
,
19h
, offset stru_427078,
0Ch
, offset stru_427140,\
.rdata:
00427050
; DATA XREF: .text:
0041C000
↑o
.rdata:
00427050
0
,
0
,
0
,
1
>
#############################
.rdata:
00427140
stru_427140 TryBlockMapEntry <
1
,
1
,
2
,
2
, offset stru_427230> __msRttiDscr <
9
,
00892A20
,
0
,
401D04h
>
.rdata:
00427140
; DATA XREF: .rdata:FuncInfo1↑o
.rdata:
00427140
TryBlockMapEntry <
7
,
7
,
8
,
1
, offset stru_427230.nFlag
+
20h
> __msRttiDscr <
0
,
00892A10
,
0FFFFFD10h
,
401F6Eh
>
.rdata:
00427140
TryBlockMapEntry <
9
,
9
,
0Ah
,
1
, offset stru_427230.nFlag
+
30h
> __msRttiDscr <
9
,
00892A20
,
0
,
401FEEh
>
.rdata:
00427140
TryBlockMapEntry <
0Dh
,
0Dh
,
0Eh
,
1
, offset stru_427230.nFlag
+
40h
> __msRttiDscr <
9
,
00892A20
,
0
,
4020D8h
>
.rdata:
00427140
TryBlockMapEntry <
0Bh
,
0Bh
,
0Eh
,
1
, offset stru_427230.nFlag
+
50h
> __msRttiDscr <
0
,
008929FC
,
0FFFFFCC8h
,
402089h
>
.rdata:
00427140
TryBlockMapEntry <
13h
,
13h
,
14h
,
1
, offset stru_427230.nFlag
+
60h
> __msRttiDscr <
9
,
00892A20
,
0
,
402211h
>
.rdata:
00427140
TryBlockMapEntry <
11h
,
11h
,
14h
,
1
, offset stru_427230.nFlag
+
70h
> __msRttiDscr <
0
,
00892A3C
,
0FFFFFD4Fh
,
4021D2h
>
.rdata:
00427140
TryBlockMapEntry <
17h
,
17h
,
18h
,
2
, offset stru_427230.nFlag
+
80h
> __msRttiDscr <
9
,
00892A20
,
0
,
402321h
>
.rdata:
00427140
TryBlockMapEntry <
15h
,
15h
,
18h
,
1
, offset stru_427230.nFlag
+
0A0h
> __msRttiDscr <
0
,
008929C4
,
0FFFFFCD0h
,
402289h
>
.rdata:
00427140
TryBlockMapEntry <
0Fh
,
0Fh
,
18h
,
1
, offset stru_427230.nFlag
+
0B0h
> __msRttiDscr <
0
,
008929FC
,
0FFFFFCC4h
,
40213Ch
>
.rdata:
00427140
TryBlockMapEntry <
5
,
5
,
18h
,
1
, offset stru_427230.nFlag
+
0C0h
> __msRttiDscr <
0
,
008929FC
,
0FFFFFCCCh
,
401EDEh
>
.rdata:
00427140
TryBlockMapEntry <
3
,
3
,
18h
,
1
, offset stru_427230.nFlag
+
0D0h
> __msRttiDscr <
0
,
00892A10
,
0FFFFFD20h
,
401E63h
>
throw 会找到 __msRttiDscr ,可能存在多个同样的,如何区分了,查看 tryLow、tryHight、catchHigh进行比对,就是看作用域
#############################
.rdata:
00427230
stru_427230 __msRttiDscr <
9
,
00892A20
,
0
,
401D04h
>
/
/
class
std::exception
.rdata:
00427230
; DATA XREF: .rdata:stru_427140↑o
.rdata:
00427230
__msRttiDscr <
0
,
008929F0
,
0FFFFFCC0h
,
401DACh
>
/
/
int
`RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
0
,
00892A10
,
0FFFFFD10h
,
401F6Eh
>
/
/
unsigned char
*
`RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
9
,
00892A20
,
0
,
401FEEh
>
/
/
class
std::exception
.rdata:
00427230
__msRttiDscr <
9
,
00892A20
,
0
,
4020D8h
>
/
/
class
std::exception
.rdata:
00427230
__msRttiDscr <
0
,
008929FC
,
0FFFFFCC8h
,
402089h
>
/
/
void (__cdecl
*
)(unsigned char
*
) `RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
9
,
00892A20
,
0
,
402211h
>
/
/
class
std::exception
.rdata:
00427230
__msRttiDscr <
0
,
00892A3C
,
0FFFFFD4Fh
,
4021D2h
>
/
/
bool
`RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
9
,
00892A20
,
0
,
402321h
>
/
/
class
std::exception
.rdata:
00427230
__msRttiDscr <
40h
,
0
,
0
,
402349h
>
/
/
.rdata:
00427230
__msRttiDscr <
0
,
008929C4
,
0FFFFFCD0h
,
402289h
>
/
/
void
*
`RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
0
,
008929FC
,
0FFFFFCC4h
,
40213Ch
>
/
/
void (__cdecl
*
)(unsigned char
*
) `RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
0
,
008929FC
,
0FFFFFCCCh
,
401EDEh
>
/
/
void (__cdecl
*
)(unsigned char
*
) `RTTI
Type
Descriptor'
.rdata:
00427230
__msRttiDscr <
0
,
00892A10
,
0FFFFFD20h
,
401E63h
>
/
/
unsigned char
*
`RTTI
Type
Descriptor'
#############################
.data:
00892A20
; public
class
std::exception
/
*
mdisp:
0
*
/
.data:
00892A20
;
class
std::exception `RTTI
Type
Descriptor'
.data:
00892A20
??_R0?AVexception@std@@@
8
dd offset off_41D184
.data:
00892A20
; DATA XREF: .rdata:
00426CA0
↑o
.data:
00892A20
; .rdata:std::exception::`RTTI Base Class Descriptor at (
0
,
-
1
,
0
,
64
)'↑o ...
.data:
00892A20
; reference to RTTI's vftable
.data:
00892A24
dd
0
; internal runtime reference
.data:
00892A28
aAvexceptionStd db
'.?AVexception@std@@'
,
0
;
type
descriptor name
#############################
.data:
008929F0
;
int
`RTTI
Type
Descriptor'
.data:
008929F0
??_R0H@
8
dd offset off_41D184 ; DATA XREF: .rdata:
004279F4
↑o
.data:
008929F0
; reference to RTTI's vftable
.data:
008929F4
dd
0
; internal runtime reference
.data:
008929F8
db
'.H'
,
0
;
type
descriptor name
#############################
.data:
00892A10
; unsigned char
*
`RTTI
Type
Descriptor'
.data:
00892A10
??_R0PAE@
8
dd offset off_41D184 ; DATA XREF: .rdata:
0042793C
↑o
.data:
00892A10
; reference to RTTI's vftable
.data:
00892A14
dd
0
; internal runtime reference
.data:
00892A18
aPae db
'.PAE'
,
0
;
type
descriptor name
.data:
00892A1D
align
10h
#############################
.data:
008929FC
; void (__cdecl
*
)(unsigned char
*
) `RTTI
Type
Descriptor'
.data:
008929FC
??_R0P6AXPAE@Z@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427958
↑o
.data:
008929FC
; reference to RTTI's vftable
.data:
00892A00
dd
0
; internal runtime reference
.data:
00892A04
aP6axpaeZ db
'.P6AXPAE@Z'
,
0
;
type
descriptor name
#############################
.data:
00892A3C
;
bool
`RTTI
Type
Descriptor'
.data:
00892A3C
??_R0_N@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427A10
↑o
.data:
00892A3C
; reference to RTTI's vftable
#############################
.data:
008929C4
; void
*
`RTTI
Type
Descriptor'
.data:
008929C4
??_R0PAX@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427910
↑o
.data:
008929C4
; reference to RTTI's vftable
.data:
008929C8
dd
0
; internal runtime reference
.data:
008929CC
aPax db
'.PAX'
,
0
;
type
descriptor name
#############################
#############################
.data:
008929A4
; public
class
std::bad_exception
/
*
mdisp:
0
*
/
:
.data:
008929A4
; public
class
std::exception
/
*
mdisp:
0
*
/
.data:
008929A4
;
class
std::bad_exception `RTTI
Type
Descriptor'
.data:
008929A4
??_R0?AVbad_exception@std@@@
8
dd offset off_41D184
.data:
008929A4
; DATA XREF: FindHandler<__FrameHandler3>(EHExceptionRecord
*
,EHRegistrationNode
*
,_CONTEXT
*
,void
*
,_s_FuncInfo const
*
,uchar,
int
,EHRegistrationNode
*
)
+
116
↑o
.data:
008929A4
; .rdata:
00426C54
↑o ...
.data:
008929A4
; reference to RTTI's vftable
.data:
008929A8
dd
0
; internal runtime reference
.data:
008929AC
aAvbadException db
'.?AVbad_exception@std@@'
,
0
;
type
descriptor name
.data:
008929C4
; void
*
`RTTI
Type
Descriptor'
.data:
008929C4
??_R0PAX@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427910
↑o
.data:
008929C4
; reference to RTTI's vftable
.data:
008929C8
dd
0
; internal runtime reference
.data:
008929CC
aPax db
'.PAX'
,
0
;
type
descriptor name
.data:
008929D1
align
4
.data:
008929D4
; public
class
std::bad_alloc
/
*
mdisp:
0
*
/
:
.data:
008929D4
; public
class
std::exception
/
*
mdisp:
0
*
/
.data:
008929D4
;
class
std::bad_alloc `RTTI
Type
Descriptor'
.data:
008929D4
??_R0?AVbad_alloc@std@@@
8
dd offset off_41D184
.data:
008929D4
; DATA XREF: .rdata:std::bad_alloc::`RTTI Base Class Descriptor at (
0
,
-
1
,
0
,
64
)'↑o
.data:
008929D4
; .rdata:
00426D20
↑o ...
.data:
008929D4
; reference to RTTI's vftable
.data:
008929D8
dd
0
; internal runtime reference
.data:
008929DC
aAvbadAllocStd db
'.?AVbad_alloc@std@@'
,
0
;
type
descriptor name
.data:
008929F0
;
int
`RTTI
Type
Descriptor'
.data:
008929F0
??_R0H@
8
dd offset off_41D184 ; DATA XREF: .rdata:
004279F4
↑o
.data:
008929F0
; reference to RTTI's vftable
.data:
008929F4
dd
0
; internal runtime reference
.data:
008929F8
db
'.H'
,
0
;
type
descriptor name
.data:
008929FB
align
4
.data:
008929FC
; void (__cdecl
*
)(unsigned char
*
) `RTTI
Type
Descriptor'
.data:
008929FC
??_R0P6AXPAE@Z@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427958
↑o
.data:
008929FC
; reference to RTTI's vftable
.data:
00892A00
dd
0
; internal runtime reference
.data:
00892A04
aP6axpaeZ db
'.P6AXPAE@Z'
,
0
;
type
descriptor name
.data:
00892A0F
align
10h
.data:
00892A10
; unsigned char
*
`RTTI
Type
Descriptor'
.data:
00892A10
??_R0PAE@
8
dd offset off_41D184 ; DATA XREF: .rdata:
0042793C
↑o
.data:
00892A10
; reference to RTTI's vftable
.data:
00892A14
dd
0
; internal runtime reference
.data:
00892A18
aPae db
'.PAE'
,
0
;
type
descriptor name
.data:
00892A1D
align
10h
.data:
00892A20
; public
class
std::exception
/
*
mdisp:
0
*
/
.data:
00892A20
;
class
std::exception `RTTI
Type
Descriptor'
.data:
00892A20
??_R0?AVexception@std@@@
8
dd offset off_41D184
.data:
00892A20
; DATA XREF: .rdata:
00426CA0
↑o
.data:
00892A20
; .rdata:std::exception::`RTTI Base Class Descriptor at (
0
,
-
1
,
0
,
64
)'↑o ...
.data:
00892A20
; reference to RTTI's vftable
.data:
00892A24
dd
0
; internal runtime reference
.data:
00892A28
aAvexceptionStd db
'.?AVexception@std@@'
,
0
;
type
descriptor name
.data:
00892A3C
;
bool
`RTTI
Type
Descriptor'
.data:
00892A3C
??_R0_N@
8
dd offset off_41D184 ; DATA XREF: .rdata:
00427A10
↑o
.data:
00892A3C
; reference to RTTI's vftable
.data:
00892A40
dd
0
; internal runtime reference
.data:
00892A44
aN db
'._N'
,
0
;
type
descriptor name
.data:
00892A48
; public
class
std::bad_array_new_length
/
*
mdisp:
0
*
/
:
.data:
00892A48
; public
class
std::bad_alloc
/
*
mdisp:
0
*
/
:
.data:
00892A48
; public
class
std::exception
/
*
mdisp:
0
*
/
.data:
00892A48
;
class
std::bad_array_new_length `RTTI
Type
Descriptor'
.data:
00892A48
??_R0?AVbad_array_new_length@std@@@
8
dd offset off_41D184
.data:
00892A48
; DATA XREF: .rdata:
00426D54
↑o
.data:
00892A48
; .rdata:std::bad_array_new_length::`RTTI Base Class Descriptor at (
0
,
-
1
,
0
,
64
)'↑o ...
.data:
00892A48
; reference to RTTI's vftable
.data:
00892A4C
dd
0
; internal runtime reference
.data:
00892A50
aAvbadArrayNewL db
'.?AVbad_array_new_length@std@@'
,
0
;
type
descriptor name
.data:
00892A6F
align
10h
.data:
00892A70
; public
class
type_info
/
*
mdisp:
0
*
/
.data:
00892A70
;
class
type_info `RTTI
Type
Descriptor'
.data:
00892A70
??_R0?AVtype_info@@@
8
dd offset off_41D184
.data:
00892A70
; DATA XREF: .rdata:
00426C0C
↑o
.data:
00892A70
; .rdata:type_info::`RTTI Base Class Descriptor at (
0
,
-
1
,
0
,
64
)'↑o
.data:
00892A70
; reference to RTTI's vftable
.data:
00892A74
dd
0
; internal runtime reference
.data:
00892A78
aAvtypeInfo db
'.?AVtype_info@@'
,
0
;
type
descriptor name
GO_32_1:
/
/
RET_32_1
__asm{
_emit
0E8h
;
_emit
00h
;
_emit
00h
;
_emit
00h
;
_emit
00h
;
_emit
0C7h
;
_emit
44h
;
_emit
24h
;
_emit
04h
;
_emit
23h
;
_emit
00h
;
_emit
00h
;
_emit
00h
;
_emit
83h
;
_emit
04h
;
_emit
24h
;
_emit
0Dh
;
_emit
0CBh
;
}
#这是一段 64 转 32 的代码
.text:
00401EFB
.text:
00401EFB
loc_401EFB:
.text:
00401EFB
E8
00
00
00
00
call $
+
5
; Call Procedure
/
/
/
执行下一条指令。
.text:
00401F00
C7
44
24
04
23
00
00
00
mov [esp
+
394h
+
var_390],
23h
;
'#'
/
/
/
windbg64 此时写入了 堆栈第二条:用于
64
转
32
00000000
`
0019e9b8
00401f00
00000023
.text:
00401F08
83
04
24
0D
add [esp
+
394h
+
var_394],
0Dh
; Add
/
/
/
windbg64 此时写入了 堆栈第一条:程序返回地址跳过retf,接续执行
00000000
`
0019e9b8
00401f0d
00000023
.text:
00401F0C
CB retf ; Return Far
from
Procedure
GO_32_1:
/
/
RET_32_1
__asm{
_emit
0E8h
;
_emit
00h
;
_emit
00h
;
_emit
00h
;
_emit
00h
;
_emit
0C7h
;
_emit
44h
;
_emit
24h
;
_emit
04h
;
_emit
23h
;
_emit
00h
;
_emit
00h
;
_emit
00h
;
_emit
83h
;
_emit
04h
;
_emit
24h
;
_emit
0Dh
;
_emit
0CBh
;
}
#这是一段 64 转 32 的代码
.text:
00401EFB
.text:
00401EFB
loc_401EFB:
.text:
00401EFB
E8
00
00
00
00
call $
+
5
; Call Procedure
/
/
/
执行下一条指令。
.text:
00401F00
C7
44
24
04
23
00
00
00
mov [esp
+
394h
+
var_390],
23h
;
'#'
/
/
/
windbg64 此时写入了 堆栈第二条:用于
64
转
32
00000000
`
0019e9b8
00401f00
00000023
.text:
00401F08
83
04
24
0D
add [esp
+
394h
+
var_394],
0Dh
; Add
/
/
/
windbg64 此时写入了 堆栈第一条:程序返回地址跳过retf,接续执行
00000000
`
0019e9b8
00401f0d
00000023
.text:
00401F0C
CB retf ; Return Far
from
Procedure
unk_8934A0:g_sd
unk_8934B9:g_sd_g_szSerial
unk_8935D9:
8
个字节为
0
unk_8995F1:
0x10
个字节与 用户名相等
8935D9
-
8934A0
=
139
8995F1
-
8934A0
=
6151
8934B9
-
8934A0
=
19
g_sd_g_szSerial:用户输入的序列号,
32
字节
##############################################################
.text:
00401406
68
8C
68
42
00
push offset aInputName ;
"Input name:"
.text:
0040140B
E8
90
FC FF FF call sub_4010A0 ; Call Procedure
.text:
00401410
83
C4
04
add esp,
4
; Add
.text:
00401413
BA
10
00
00
00
mov edx,
10h
.text:
00401418
8D
4D
D8 lea ecx, [ebp
+
Buf1] ;
Buffer
.text:
0040141B
E8
70
FE FF FF call sub_401290 ; Call Procedure
.text:
00401420
0F
B6 D0 movzx edx, al ; Move with Zero
-
Extend
.text:
00401423
85
D2 test edx, edx ; Logical Compare
.text:
00401425
75
21
jnz short loc_401448 ; Jump
if
Not Zero (ZF
=
0
)
【Buf1】【局部变量】:用户输入的用户名
.text:
004014D0
.text:
004014D0
loc_4014D0:
.text:
004014D0
68
AC
68
42
00
push offset aInputKey ;
"Input key:"
.text:
004014D5
E8 C6 FB FF FF call sub_4010A0 ; Call Procedure
.text:
004014DA
83
C4
04
add esp,
4
; Add
.text:
004014DD
BA
40
00
00
00
mov edx,
40h
;
'@'
.text:
004014E2
8D
8D
70
FF FF FF lea ecx, [ebp
+
Buffer
] ;
Buffer
.text:
004014E8
E8 A3 FD FF FF call sub_401290 ; Call Procedure
.text:
004014ED
0F
B6 C0 movzx eax, al ; Move with Zero
-
Extend
.text:
004014F0
85
C0 test eax, eax ; Logical Compare
.text:
004014F2
75
21
jnz short loc_401515 ; Jump
if
Not Zero (ZF
=
0
)
【
Buffer
】【局部变量】:用户输入的序列号
.text:
00401515
.text:
00401515
loc_401515:
.text:
00401515
33
C9 xor ecx, ecx ; Logical Exclusive OR
.text:
00401517
89
4D
B8 mov [ebp
+
var_48], ecx
.text:
0040151A
89
4D
BC mov [ebp
+
var_44], ecx
.text:
0040151D
89
4D
C0 mov [ebp
+
var_40], ecx
.text:
00401520
89
4D
C4 mov [ebp
+
var_3C], ecx
.text:
00401523
89
4D
C8 mov [ebp
+
var_38], ecx
.text:
00401526
89
4D
CC mov [ebp
+
var_34], ecx
.text:
00401529
89
4D
D0 mov [ebp
+
var_30], ecx
.text:
0040152C
89
4D
D4 mov [ebp
+
var_2C], ecx
######【ebp+var_48】【局部变量】【 unsigned char byteEnc[32] = { 0 };】
.text:
0040152F
8D
55
B8 lea edx, [ebp
+
var_48] ; Load Effective Address
.text:
00401532
8D
8D
70
FF FF FF lea ecx, [ebp
+
Buffer
] ; Load Effective Address
.text:
00401538
E8 A3 FD FF FF call sub_4012E0 ; Call Procedure
######【ebp+var_48 = string2hex(szEnc)】【局部变量】【 string2hex(szEnc, byteEnc);】【此处是 16进制字符串 转 16进制】
.text:
0040153D
0F
B6 D0 movzx edx, al ; Move with Zero
-
Extend
.text:
00401540
85
D2 test edx, edx ; Logical Compare
.text:
00401542
75
21
jnz short loc_401565 ; Jump
if
Not Zero (ZF
=
0
)
【第一个是将用户输入的 序列号 拷贝到了 全局变量 unk_8934B9 长度是
32
字节(转换之后),之前是
64
个字符。】
######【unk_8934B9】【输入 序列号】【memcpy(g_sd_g_szSerial, byteEnc, 32);】
.text:
00401565
loc_401565:
.text:
00401565
B9
08
00
00
00
mov ecx,
8
.text:
0040156A
8D
75
B8 lea esi, [ebp
+
var_48] ; Load Effective Address
.text:
0040156D
BF B9
34
89
00
mov edi, offset unk_8934B9
.text:
00401572
F3 A5 rep movsd ; Move Byte(s)
from
String to String
【第二个是将内置的数据拷贝到了 全局变量】
.text:
00401574
C6
85
6C
FD FF FF
95
mov [ebp
+
var_294],
95h
.text:
0040157B
C6
85
6D
FD FF FF E2 mov [ebp
+
var_293],
0E2h
.text:
00401582
C6
85
6E
FD FF FF
80
mov [ebp
+
var_292],
80h
.text:
00401589
C6
85
6F
FD FF FF C6 mov [ebp
+
var_291],
0C6h
.text:
00401590
C6
85
70
FD FF FF EA mov [ebp
+
var_290],
0EAh
.text:
00401597
C6
85
71
FD FF FF C3 mov [ebp
+
var_28F],
0C3h
…………………………………………………………………………………………………………………………………………………………………………
.text:
00401C58
C6
85
68
FE FF FF CF mov [ebp
+
var_198],
0CFh
.text:
00401C5F
C6
85
69
FE FF FF AE mov [ebp
+
var_197],
0AEh
.text:
00401C66
C6
85
6A
FE FF FF
8B
mov [ebp
+
var_196],
8Bh
.text:
00401C6D
C6
85
6B
FE FF FF CA mov [ebp
+
var_195],
0CAh
#########################################################################################################
.text:
00401C74
8D
85
6C
FE FF FF lea eax, [ebp
+
var_194] ; Load Effective Address
.text:
00401C7A
50
push eax
.text:
00401C7B
8D
8D
6C
FD FF FF lea ecx, [ebp
+
var_294] ; Load Effective Address
.text:
00401C81
51
push ecx
.text:
00401C82
8D
8D
7C
FC FF FF lea ecx, [ebp
+
var_384] ; Load Effective Address
.text:
00401C88
E8 D3
07
00
00
call unknown_libname_3 ; Microsoft VisualC
14
/
net runtime
.text:
00401C8D
8B
50
04
mov edx, [eax
+
4
]
.text:
00401C90
52
push edx
.text:
00401C91
8B
00
mov eax, [eax]
.text:
00401C93
50
push eax
.text:
00401C94
8D
8D
E8 FC FF FF lea ecx, [ebp
+
var_318] ; Load Effective Address
.text:
00401C9A
E8
41
08
00
00
call sub_4024E0 ; Call Procedure
#########################################################################################################
上面这段代码,应该是执行了一个内部的机制。
list
<uint8_t> list_table
=
{}
程序现将所有的数据赋值给了一堆局部变量,然后将 [ebp
+
var_294] 作为
list
<uint8_t> list_table 的地址,调用了 unknown_libname_3 方法
接下来:call sub_4024E0 没看明白。。。。(
2022
-
06
-
03
2120
)
######【ebp+var_194】:长度 0x100 = 256 字节
#########################################################################################################
.text:
00401C9F
C7
45
FC
00
00
00
00
mov [ebp
+
var_4],
0
【
try
】【
0
】
.text:
00401CA6
68
00
01
00
00
push
100h
;
.text:
00401CAB
6A
00
push
0
;
.text:
00401CAD
8D
8D
70
FE FF FF lea ecx, [ebp
+
var_190] ;
.text:
00401CB3
51
push ecx ; void
*
.text:
00401CB4
E8
17
71
00
00
call _memset ; Call Procedure【内存拷贝,其实是初始化了局部变量 】【[ebp
+
var_190]】
.text:
00401CB9
83
C4
0C
add esp,
0Ch
;
.text:
00401CBC
C6
45
FC
01
mov byte ptr [ebp
+
var_4],
1
【
try
】【
1
】
.text:
00401CC0
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands
.text:
00401CC4
7D
1E
jge short loc_401CE4 ; Jump
if
Greater
or
Equal (SF
=
OF)【大于等于
100
,则退出】
######【ebp+var_190】:长度 0x100 = 256 字节
/
/
对应于C
# uint8_t table[256] = { };
.text:
00401CC6
8D
8D
B4 FC FF FF lea ecx, [ebp
+
pExceptionObject] ; Load Effective Address
.text:
00401CCC
E8 FF F3 FF FF call sub_4010D0 ; Call Procedure
.text:
00401CD1
68
90
79
42
00
push offset __TI1?AVexception@std@@ ; pThrowInfo
.text:
00401CD6
8D
95
B4 FC FF FF lea edx, [ebp
+
pExceptionObject] ; Load Effective Address
.text:
00401CDC
52
push edx ; pExceptionObject
.text:
00401CDD
E8
0C
70
00
00
call __CxxThrowException@
8
; attributes:
.rdata:
00427140
stru_427140 TryBlockMapEntry <
1
,
1
,
2
,
2
, offset stru_427230> __msRttiDscr <
9
,
00892A20
,
0
,
401D04h
>
【
401D04
】
.text:
00401D04
C7
85
D8 FC FF FF D9
34
89
00
mov [ebp
+
var_328], offset unk_8934D9
.text:
00401D0E
C7
85
44
FD FF FF
00
00
00
00
mov [ebp
+
var_2BC],
0
【循环索引:
0
】
.text:
00401D18
8D
8D
E8 FC FF FF lea ecx, [ebp
+
var_318] ; Load Effective Address 【循环长度】
.text:
00401D1E
89
8D
34
FD FF FF mov [ebp
+
var_2CC], ecx
.text:
00401D24
8D
95
48
FD FF FF lea edx, [ebp
+
var_2B8] ; Load Effective Address
.text:
00401D2A
52
push edx
.text:
00401D2B
8B
8D
34
FD FF FF mov ecx, [ebp
+
var_2CC]
.text:
00401D31
E8
5A
07
00
00
call sub_402490 ; Call Procedure 【找this指针?】
.text:
00401D36
8D
85
DC FC FF FF lea eax, [ebp
+
var_324] ; Load Effective Address
.text:
00401D3C
50
push eax
.text:
00401D3D
8B
8D
34
FD FF FF mov ecx, [ebp
+
var_2CC]
.text:
00401D43
E8
38
07
00
00
call ?_Unwrapped@?$_Tree_iterator@V?$_Tree_val@U?$_Tree_simple_types@U?$pair@QAXU_Mutex_count_pair@?A0x04e813ea@@@std@@@std@@@std@@@std@@QBE?AV?$_Tree_unchecked_iterator@V?$_Tree_val@U?$_Tree_simple_types@U?$pair@QAXU_Mutex_count_pair@?A0x04e813ea@@@std@@@std@@@std@@@
2
@XZ ; std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<void
*
const,`anonymous namespace'::_Mutex_count_pair>>>>::_Unwrapped(void)
.text:
00401D48
EB
0B
jmp short loc_401D55 ; Jump
.text:
00401D55
.text:
00401D55
loc_401D55:
.text:
00401D55
8D
8D
DC FC FF FF lea ecx, [ebp
+
var_324] ; Load Effective Address
.text:
00401D5B
51
push ecx
.text:
00401D5C
8D
8D
48
FD FF FF lea ecx, [ebp
+
var_2B8] ; Load Effective Address
.text:
00401D62
E8 D9
06
00
00
call unknown_libname_2 ; Microsoft VisualC
14
/
net runtime
.text:
00401D67
0F
B6 D0 movzx edx, al ; Move with Zero
-
Extend
.text:
00401D6A
85
D2 test edx, edx ; Logical Compare
.text:
00401D6C
74
38
jz short loc_401DA6 ; catch执行之后,下一个地址存入eax里面
.text:
00401DA6
loc_401DA6: ; catch执行之后,下一个地址存入eax里面
.text:
00401DA6
B8 EC
1D
40
00
mov eax, offset loc_401DEC
.text:
00401DAB
C3 retn ; Return Near
from
Procedure
.text:
00401DEC
loc_401DEC:
.text:
00401DEC
C7
45
FC
00
00
00
00
mov [ebp
+
var_4],
0
【
try
】【
0
】
.text:
00401DF3
.text:
00401DF3
loc_401DF3:
.text:
00401DF3
C7
85
64
FD FF FF FC
30
0D
00
mov [ebp
+
dwSize],
0D30FCh
【size_t decompress_size
=
0x000d30f2
+
10
;】
.text:
00401DFD
C7
85
D4 FC FF FF
00
00
00
00
mov [ebp
+
var_32C],
0
【LPBYTE lpbuff1
=
NULL;】
.text:
00401E07
C7
85
5C
FD FF FF
00
00
00
00
mov [ebp
+
var_2A4],
0
【uLong shellcode_size
=
0
;】
.text:
00401E11
C7
85
58
FD FF FF
00
00
00
00
mov [ebp
+
var_2A8],
0
【uLongf ulongfsize
=
0
;】
.text:
00401E1B
C6
45
FC
03
mov byte ptr [ebp
+
var_4],
3
【
try
】【
3
】
.text:
00401E1F
6A
40
push
40h
;
'@'
; flProtect
.text:
00401E21
68
00
10
00
00
push
1000h
; flAllocationType
.text:
00401E26
8B
95
64
FD FF FF mov edx, [ebp
+
dwSize]
.text:
00401E2C
52
push edx ; dwSize
.text:
00401E2D
6A
00
push
0
; lpAddress
.text:
00401E2F
FF
15
00
D0
41
00
call ds:VirtualAlloc ; Indirect Call Near Procedure
【VirtualAlloc(NULL, decompress_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);】
.text:
00401E35
89
85
28
FD FF FF mov [ebp
+
var_2D8], eax 【LPBYTE lpbuff
=
】
.text:
00401E3B
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands
.text:
00401E3F
7D
1D
jge short loc_401E5E ; Jump
if
Greater
or
Equal (SF
=
OF)【<
100
】
【LPBYTE lpbuff】【局部变量】
=
即将存放的第一阶段代码
.text:
00401E41
8B
85
28
FD FF FF mov eax, [ebp
+
var_2D8]
.text:
00401E47
89
85
24
FD FF FF mov [ebp
+
var_2DC], eax
.text:
00401E4D
68
4C
7A
42
00
push offset __TI2PAE ; pThrowInfo
.text:
00401E52
8D
8D
24
FD FF FF lea ecx, [ebp
+
var_2DC] ; Load Effective Address
.text:
00401E58
51
push ecx ; pExceptionObject
.text:
00401E59
E8
90
6E
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.rdata:
00427140
TryBlockMapEntry <
3
,
3
,
18h
,
1
, offset stru_427230.nFlag
+
0D0h
> __msRttiDscr <
0
,
00892A10
,
0FFFFFD20h
,
401E63h
>
【
401E63
】
.text:
00401E63
89
65
F0 mov [ebp
+
var_10], esp
.text:
00401E66
8B
95
64
FD FF FF mov edx, [ebp
+
dwSize] ; 解密长度 【ulongfsize
=
(size_t)decompress_size;】
.text:
00401E6C
89
95
58
FD FF FF mov [ebp
+
var_2A8], edx
.text:
00401E72
C7
85
5C
FD FF FF
21
E9
0C
00
mov [ebp
+
var_2A4],
0CE921h
; 原始长度 【shellcode_size
=
sizeof(g_shellcode_compress_64_1);】
.text:
00401E7C
8B
85
5C
FD FF FF mov eax, [ebp
+
var_2A4]
.text:
00401E82
50
push eax
.text:
00401E83
68
90
D2
5C
00
push offset unk_5CD290 ; 原始数据密文 【g_shellcode_compress_64_1】
.text:
00401E88
8D
95
58
FD FF FF lea edx, [ebp
+
var_2A8] ; 解密长度
.text:
00401E8E
8B
8D
20
FD FF FF mov ecx, [ebp
+
var_2E0] ; 解密地址 【LPBYTE lpbuff】
.text:
00401E94
E8
67
F1 FF FF call sub_401000 ; 【第一阶段解码】
.text:
00401E99
83
C4
08
add esp,
8
; Add
.text:
00401E9C
C7
85
40
FD FF FF
00
00
00
00
mov [ebp
+
var_2C0],
0
【PFNDEC pfnDec1
=
NULL;】
.text:
00401EA6
C6
45
FC
05
mov byte ptr [ebp
+
var_4],
5
【
try
】【
5
】
.text:
00401EAA
8B
8D
20
FD FF FF mov ecx, [ebp
+
var_2E0]
.text:
00401EB0
89
8D
40
FD FF FF mov [ebp
+
var_2C0], ecx 【pfnDec1
=
(PFNDEC)lpbuff;】【存放
64
位代码】
.text:
00401EB6
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands
.text:
00401EBA
7D
1D
jge short loc_401ED9 ; Jump
if
Greater
or
Equal (SF
=
OF)
.text:
00401EBC
8B
95
40
FD FF FF mov edx, [ebp
+
var_2C0] 【catch 拷贝 对象】
.text:
00401EC2
89
95
1C
FD FF FF mov [ebp
+
var_2E4], edx
.text:
00401EC8
68
80
79
42
00
push offset __TI1P6AXPAE@Z ; pThrowInfo
.text:
00401ECD
8D
85
1C
FD FF FF lea eax, [ebp
+
var_2E4] ; Load Effective Address
.text:
00401ED3
50
push eax ; pExceptionObject
.text:
00401ED4
E8
15
6E
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.rdata:
00427140
TryBlockMapEntry <
5
,
5
,
18h
,
1
, offset stru_427230.nFlag
+
0C0h
> __msRttiDscr <
0
,
008929FC
,
0FFFFFCCCh
,
401EDEh
>
【
401EDE
】【接下来就是一个
32
转
64
,执行完了之后,再转
32
】
.text:
00401EDE
89
65
F0 mov [ebp
+
var_10], esp
.text:
00401EE1
6A
FF push
0FFFFFFFFh
.text:
00401EE3
83
04
24
01
add [esp
+
var_s0],
1
; Add
.text:
00401EE7
68
FB
1E
40
00
push offset loc_401EFB
.text:
00401EEC
8D
0D
A0
34
89
00
lea ecx, unk_8934A0 ; Load Effective Address
.text:
00401EF2
6A
33
push
33h
;
'3'
.text:
00401EF4
FF B5 CC FC FF FF push [ebp
+
var_334]
.text:
00401EFA
CB retf ; Return Far
from
Procedure
.text:
00401EFB
.text:
00401EFB
loc_401EFB:
.text:
00401EFB
E8
00
00
00
00
call $
+
5
; Call Procedure
.text:
00401F00
C7
44
24
04
23
00
00
00
mov [esp
+
394h
+
var_390],
23h
;
'#'
.text:
00401F08
83
04
24
0D
add [esp
+
394h
+
var_394],
0Dh
; Add
.text:
00401F0C
CB retf ; Return Far
from
Procedure
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
【第二阶段开始】
.text:
00401F0D
BA
00
03
00
00
mov edx,
300h
.text:
00401F12
8B
8D
40
FD FF FF mov ecx, [ebp
+
var_2C0]
.text:
00401F18
E8
03
F1 FF FF call sub_401020 ; Call Procedure 【change_mem_rand(pfnDec1,
0x300
)】
.text:
00401F1D
C7
85
3C
FD FF FF
00
00
00
00
mov [ebp
+
var_2C4],
0
.text:
00401F27
C6
45
FC
07
mov byte ptr [ebp
+
var_4],
7
【
try
】【
7
】
.text:
00401F2B
C7
85
64
FD FF FF
0B
E5
2F
00
mov [ebp
+
dwSize],
2FE50Bh
【decompress_size
=
0x002fe501
+
10
;】
.text:
00401F35
6A
40
push
40h
;
'@'
; flProtect
.text:
00401F37
68
00
10
00
00
push
1000h
; flAllocationType
.text:
00401F3C
8B
8D
64
FD FF FF mov ecx, [ebp
+
dwSize]
.text:
00401F42
51
push ecx ; dwSize
.text:
00401F43
6A
00
push
0
; lpAddress
.text:
00401F45
FF
15
00
D0
41
00
call ds:VirtualAlloc ; Indirect Call Near Procedure
【VirtualAlloc(NULL, decompress_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);】
.text:
00401F4B
89
85
18
FD FF FF mov [ebp
+
var_2E8], eax 【LPBYTE lpbuff】
.text:
00401F51
8B
95
18
FD FF FF mov edx, [ebp
+
var_2E8]
.text:
00401F57
89
95
14
FD FF FF mov [ebp
+
var_2EC], edx
.text:
00401F5D
68
4C
7A
42
00
push offset __TI2PAE ; pThrowInfo
.text:
00401F62
8D
85
14
FD FF FF lea eax, [ebp
+
var_2EC] ; Load Effective Address
.text:
00401F68
50
push eax ; pExceptionObject
.text:
00401F69
E8
80
6D
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.rdata:
00427140
TryBlockMapEntry <
7
,
7
,
8
,
1
, offset stru_427230.nFlag
+
20h
> __msRttiDscr <
0
,
00892A10
,
0FFFFFD10h
,
401F6Eh
>
【
401F6E
】
.text:
00401F6E
8B
8D
64
FD FF FF mov ecx, [ebp
+
dwSize] 【ulongfsize
=
(size_t)decompress_size;】
.text:
00401F74
89
8D
58
FD FF FF mov [ebp
+
var_2A8], ecx
.text:
00401F7A
C7
85
5C
FD FF FF EC
6D
1F
00
mov [ebp
+
var_2A4],
1F6DECh
【shellcode_size
=
sizeof(g_shellcode_compress_32_2);】
.text:
00401F84
8B
95
5C
FD FF FF mov edx, [ebp
+
var_2A4]
.text:
00401F8A
52
push edx
.text:
00401F8B
68
B8 BB
69
00
push offset unk_69BBB8 【g_shellcode_compress_32_2】加密地址
.text:
00401F90
8D
95
58
FD FF FF lea edx, [ebp
+
var_2A8] ; Load Effective Address
.text:
00401F96
8B
8D
10
FD FF FF mov ecx, [ebp
+
var_2F0] 【lpbuff】【解密地址】
.text:
00401F9C
E8
5F
F0 FF FF call sub_401000 ; 第二阶段解码
.text:
00401FA1
83
C4
08
add esp,
8
; Add
.text:
00401FA4
8B
85
10
FD FF FF mov eax, [ebp
+
var_2F0]
.text:
00401FAA
89
85
3C
FD FF FF mov [ebp
+
var_2C4], eax 【 pfnDec2
=
(PFNDEC)lpbuff;】
.text:
00401FB0
B8 BF
1F
40
00
mov eax, offset loc_401FBF
.text:
00401FB5
C3 retn ; Return Near
from
Procedure
.text:
00401FBF
loc_401FBF:
.text:
00401FBF
C7
45
FC
06
00
00
00
mov [ebp
+
var_4],
6
【
try
】【
6
】
.text:
00401FC6
.text:
00401FC6
loc_401FC6:
.text:
00401FC6
C6
45
FC
09
mov byte ptr [ebp
+
var_4],
9
【
try
】【
9
】
.text:
00401FCA
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands
.text:
00401FCE
7D
1C
jge short loc_401FEC ; Jump
if
Greater
or
Equal (SF
=
OF)
.text:
00401FD0
8D
8D
A8 FC FF FF lea ecx, [ebp
+
var_358] ; Load Effective Address
.text:
00401FD6
E8 F5 F0 FF FF call sub_4010D0 ; Call Procedure
.text:
00401FDB
68
90
79
42
00
push offset __TI1?AVexception@std@@ ; pThrowInfo
.text:
00401FE0
8D
8D
A8 FC FF FF lea ecx, [ebp
+
var_358] ; Load Effective Address
.text:
00401FE6
51
push ecx ; pExceptionObject
.text:
00401FE7
E8
02
6D
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.rdata:
00427140
TryBlockMapEntry <
9
,
9
,
0Ah
,
1
, offset stru_427230.nFlag
+
30h
> __msRttiDscr <
9
,
00892A20
,
0
,
401FEEh
>
【
401FEE
】
.text:
00401FEE
68
A0
34
89
00
push offset unk_8934A0 【g_sd】【重要】【全局变量】
.text:
00401FF3
FF
95
3C
FD FF FF call [ebp
+
var_2C4] ; Indirect Call Near Procedure 【pfnDec2(g_sd);】
.text:
00401FF9
83
C4
04
add esp,
4
; Add
.text:
00401FFC
B8
0B
20
40
00
mov eax, offset loc_40200B
.text:
00402001
C3 retn ; Return Near
from
Procedure
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
【第三阶段处理】
.text:
0040200B
loc_40200B:
.text:
0040200B
C7
45
FC
06
00
00
00
mov [ebp
+
var_4],
6
【
try
】【
6
】
.text:
00402012
.text:
00402012
loc_402012:
.text:
00402012
C7
85
38
FD FF FF
00
00
00
00
mov [ebp
+
var_2C8],
0
【LPBYTE lpbuff3
=
NULL;】
.text:
0040201C
C6
45
FC
0B
mov byte ptr [ebp
+
var_4],
0Bh
【
try
】【B】
.text:
00402020
C7
85
64
FD FF FF
09
D0
1A
00
mov [ebp
+
dwSize],
1AD009h
; 【decompress_size
=
0x001acfff
+
10
;】
.text:
0040202A
6A
40
push
40h
;
'@'
; flProtect
.text:
0040202C
68
00
10
00
00
push
1000h
; flAllocationType
.text:
00402031
8B
95
64
FD FF FF mov edx, [ebp
+
dwSize]
.text:
00402037
52
push edx ; dwSize
.text:
00402038
6A
00
push
0
; lpAddress
.text:
0040203A
FF
15
00
D0
41
00
call ds:VirtualAlloc ; lpbuff3
=
(LPBYTE)VirtualAlloc(NULL, decompress_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
【VirtualAlloc(NULL, decompress_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);】
.text:
00402040
89
85
38
FD FF FF mov [ebp
+
var_2C8], eax
.text:
00402046
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands
.text:
0040204A
7E
1E
jle short loc_40206A ; Jump
if
Less
or
Equal (ZF
=
1
| SF!
=
OF)【】
.text:
0040206A
.text:
0040206A
loc_40206A:
.text:
0040206A
8B
8D
3C
FD FF FF mov ecx, [ebp
+
var_2C4] 【pfnDec2】【准备将其随机化】
.text:
00402070
89
8D
0C
FD FF FF mov [ebp
+
var_2F4], ecx
.text:
00402076
68
80
79
42
00
push offset __TI1P6AXPAE@Z ; pThrowInfo
.text:
0040207B
8D
95
0C
FD FF FF lea edx, [ebp
+
var_2F4] ; Load Effective Address
.text:
00402081
52
push edx ; pExceptionObject
.text:
00402082
E8
67
6C
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.rdata:
00427140
TryBlockMapEntry <
0Bh
,
0Bh
,
0Eh
,
1
, offset stru_427230.nFlag
+
50h
> __msRttiDscr <
0
,
008929FC
,
0FFFFFCC8h
,
402089h
>
【
402089
】
.text:
00402089
89
65
F0 mov [ebp
+
var_10], esp
.text:
0040208C
BA
00
03
00
00
mov edx,
300h
.text:
00402091
8B
8D
C8 FC FF FF mov ecx, [ebp
+
var_338]
.text:
00402097
E8
84
EF FF FF call sub_401020 ; 随机打乱解码 【change_mem_rand(pfnDec,
0x300
);】
.text:
0040209C
C6
45
FC
0D
mov byte ptr [ebp
+
var_4],
0Dh
【
try
】【D】
.text:
004020A0
8B
85
64
FD FF FF mov eax, [ebp
+
dwSize] 【ulongfsize
=
(size_t)decompress_size;】【解密长度】
.text:
004020A6
89
85
58
FD FF FF mov [ebp
+
var_2A8], eax
.text:
004020AC
C7
85
5C
FD FF FF DD
39
1A
00
mov [ebp
+
var_2A4],
1A39DDh
【 shellcode_size
=
sizeof(g_shellcode_compress_64_3);】【加密长度】
.text:
004020B6
8B
8D
5C
FD FF FF mov ecx, [ebp
+
var_2A4]
.text:
004020BC
51
push ecx
.text:
004020BD
68
B0
98
42
00
push offset unk_4298B0 【g_shellcode_compress_64_3】【加密地址】
.text:
004020C2
8D
95
58
FD FF FF lea edx, [ebp
+
var_2A8] ; Load Effective Address
.text:
004020C8
8B
8D
38
FD FF FF mov ecx, [ebp
+
var_2C8] 【lpbuff3】【解密地址】
.text:
004020CE
E8
2D
EF FF FF call sub_401000 ; 第三阶段解码
.text:
004020D3
83
C4
08
add esp,
8
; Add
.text:
004020D6
EB
06
jmp short loc_4020DE ; Jump
.text:
004020DE
C7
45
FC
0C
00
00
00
mov [ebp
+
var_4],
0Ch
.text:
004020E5
EB
07
jmp short loc_4020EE ; Jump
.text:
004020EE
loc_4020EE:
.text:
004020EE
B8 FD
20
40
00
mov eax, offset loc_4020FD
.text:
004020F3
C3 retn ; Return Near
from
Procedure
.text:
004020FD
loc_4020FD:
.text:
004020FD
C7
45
FC
06
00
00
00
mov [ebp
+
var_4],
6
.text:
00402104
.text:
00402104
loc_402104:
.text:
00402104
8B
95
38
FD FF FF mov edx, [ebp
+
var_2C8] 【lpbuff3】【解密地址】
.text:
0040210A
89
95
08
FD FF FF mov [ebp
+
var_2F8], edx
.text:
00402110
C6
45
FC
0F
mov byte ptr [ebp
+
var_4],
0Fh
【
try
】【F】
.text:
00402114
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands
.text:
00402118
7D
1D
jge short loc_402137 ; Jump
if
Greater
or
Equal (SF
=
OF)
.text:
0040211A
8B
85
08
FD FF FF mov eax, [ebp
+
var_2F8]
.text:
00402120
89
85
04
FD FF FF mov [ebp
+
var_2FC], eax
.text:
00402126
68
80
79
42
00
push offset __TI1P6AXPAE@Z ; pThrowInfo
.text:
0040212B
8D
8D
04
FD FF FF lea ecx, [ebp
+
var_2FC] ; Load Effective Address
.text:
00402131
51
push ecx ; pExceptionObject
.text:
00402132
E8 B7
6B
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.rdata:
00427140
TryBlockMapEntry <
0Fh
,
0Fh
,
18h
,
1
, offset stru_427230.nFlag
+
0B0h
> __msRttiDscr <
0
,
008929FC
,
0FFFFFCC4h
,
40213Ch
>
【
40213C
】
32
转
64
,执行之后,返回
32
.text:
0040213C
89
65
F0 mov [ebp
+
var_10], esp
.text:
0040213F
6A
FF push
0FFFFFFFFh
.text:
00402141
83
04
24
01
add [esp
+
var_s0],
1
; Add
.text:
00402145
68
59
21
40
00
push offset loc_402159
.text:
0040214A
8D
0D
A0
34
89
00
lea ecx, unk_8934A0 ; Load Effective Address
.text:
00402150
6A
33
push
33h
;
'3'
.text:
00402152
FF B5 C4 FC FF FF push [ebp
+
var_33C]
.text:
00402158
CB retf ; Return Far
from
Procedure
.text:
00402159
loc_402159:
.text:
00402159
E8
00
00
00
00
call $
+
5
; Call Procedure
.text:
0040215E
C7
44
24
04
23
00
00
00
mov [esp
+
394h
+
var_390],
23h
;
'#'
.text:
00402166
83
04
24
0D
add [esp
+
394h
+
var_394],
0Dh
; Add
.text:
0040216A
CB retf ; Return Far
from
Procedure
【shellcode执行完成】
.text:
0040216B
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands
.text:
0040216F
7E
1B
jle short loc_40218C ; Jump
if
Less
or
Equal (ZF
=
1
| SF!
=
OF)
.text:
0040218C
loc_40218C:
.text:
0040218C
C6
45
FC
11
mov byte ptr [ebp
+
var_4],
11h
【
try
】【
11
】
.text:
00402190
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands
.text:
00402194
7D
3A
jge short loc_4021D0 ; Jump
if
Greater
or
Equal (SF
=
OF) 【大于等于
100
,不用考虑】
.text:
00402196
A1 D9
35
89
00
mov eax, dword_8935D9 【g_sd_g_qwDecSuccess】
【
#define g_sd_g_qwDecSuccess (*(uint64_t*)(g_sd+313))】【他是8个字节,也就是要求 2个DWORD为都为0】【实际上是8个字节为0】
.text:
0040219B
0B
05
DD
35
89
00
or
eax, dword_8935DD ; Logical Inclusive OR
.text:
004021A1
74
09
jz short loc_4021AC ; Jump
if
Zero (ZF
=
1
) 【此时不能被触发,否则会failed】
.text:
004021AC
loc_4021AC:
.text:
004021AC
C6
85
6B
FD FF FF
00
mov [ebp
+
var_295],
0
【g_sd_g_qwDecSuccess
=
False
】
.text:
004021A3
C6
85
6B
FD FF FF
01
mov [ebp
+
var_295],
1
【g_sd_g_qwDecSuccess
=
True
】【失败】
.text:
004021AA
EB
07
jmp short loc_4021B3 ; Jump
.text:
004021B3
.text:
004021B3
loc_4021B3:
.text:
004021B3
8A
8D
6B
FD FF FF mov cl, [ebp
+
var_295]
.text:
004021B9
88
8D
62
FD FF FF mov [ebp
+
var_29E], cl
.text:
004021BF
68
E0
79
42
00
push offset __TI1_N ; pThrowInfo
.text:
004021C4
8D
95
62
FD FF FF lea edx, [ebp
+
var_29E] ; Load Effective Address
.text:
004021CA
52
push edx ; pExceptionObject
.text:
004021CB
E8
1E
6B
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.rdata:
00427140
TryBlockMapEntry <
11h
,
11h
,
14h
,
1
, offset stru_427230.nFlag
+
70h
> __msRttiDscr <
0
,
00892A3C
,
0FFFFFD4Fh
,
4021D2h
>
【
4021D2
】
.text:
004021D2
89
65
F0 mov [ebp
+
var_10], esp
.text:
004021D5
C6
45
FC
13
mov byte ptr [ebp
+
var_4],
13h
.text:
004021D9
0F
B6
85
4F
FD FF FF movzx eax, [ebp
+
var_2B1] ; Move with Zero
-
Extend
.text:
004021E0
85
C0 test eax, eax ; Logical Compare 【g_sd_g_qwDecSuccess】
.text:
004021E2
74
2B
jz short loc_40220F ; Jump
if
Zero (ZF
=
1
)
.text:
004021E4
BA
00
01
00
00
mov edx,
100h
【g_sd_g_qwDecSuccess
=
True
】【此时应该是弹出 failed】
.text:
004021E9
B9 D9
34
89
00
mov ecx, offset unk_8934D9
.text:
004021EE
E8
2D
EE FF FF call sub_401020 ; Call Procedure
.text:
004021F3
8D
8D
84
FC FF FF lea ecx, [ebp
+
var_37C] ; Load Effective Address
.text:
004021F9
E8 D2 EE FF FF call sub_4010D0 ; Call Procedure
.text:
004021FE
68
90
79
42
00
push offset __TI1?AVexception@std@@ ; pThrowInfo
.text:
00402203
8D
8D
84
FC FF FF lea ecx, [ebp
+
var_37C] ; Load Effective Address
.text:
00402209
51
push ecx ; pExceptionObject
.text:
0040220A
E8 DF
6A
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.rdata:
00427140
TryBlockMapEntry <
13h
,
13h
,
14h
,
1
, offset stru_427230.nFlag
+
60h
> __msRttiDscr <
9
,
00892A20
,
0
,
402211h
>
/
/
/
【
402211
】
.text:
00402216
E8
85
EE FF FF call sub_4010A0 ; Call Procedure
.text:
0040221B
83
C4
04
add esp,
4
; Add
.text:
0040221E
68
A4
68
42
00
push offset aPause ;
"pause"
.text:
00402223
E8
3F
9C
00
00
call sub_40BE67 ; Call Procedure
.text:
00402228
83
C4
04
add esp,
4
; Add
.text:
0040222B
6A
00
push
0
; uExitCode
.text:
0040222D
FF
15
04
D0
41
00
call ds:ExitProcess ; Indirect Call Near Procedure
【此时是:】【g_sd_g_qwDecSuccess
=
False
】
.text:
0040220F
loc_40220F: 【g_sd_g_qwDecSuccess
=
False
】
.text:
0040220F
EB
28
jmp short loc_402239 ; Jump
.text:
00402239
loc_402239:
.text:
00402239
C7
45
FC
12
00
00
00
mov [ebp
+
var_4],
12h
.text:
00402240
EB
07
jmp short loc_402249 ; Jump
.text:
00402249
loc_402249:
.text:
00402249
B8
58
22
40
00
mov eax, offset loc_402258
.text:
0040224E
C3 retn ; Return Near
from
Procedure
.text:
00402258
loc_402258:
.text:
00402258
C7
45
FC
10
00
00
00
mov [ebp
+
var_4],
10h
.text:
0040225F
loc_40225F:
.text:
0040225F
C6
45
FC
15
mov byte ptr [ebp
+
var_4],
15h
【
try
】【
15
】
.text:
00402263
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands 【
if
(argc <
100
)】
.text:
00402267
7D
1B
jge short loc_402284 ; Jump
if
Greater
or
Equal (SF
=
OF) 【跳出
try
,也就是出错了】
.text:
00402269
C7
85
FC FC FF FF F1
95
89
00
mov [ebp
+
var_304], offset unk_8995F1 【(void
*
)g_sd_g_szDec】【全局变量】【关键,就是序列号】
.text:
00402273
68
BC
79
42
00
push offset __TI1PAX ; pThrowInfo
.text:
00402278
8D
95
FC FC FF FF lea edx, [ebp
+
var_304] ; Load Effective Address
.text:
0040227E
52
push edx ; pExceptionObject
.text:
0040227F
E8
6A
6A
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.rdata:
00427140
TryBlockMapEntry <
15h
,
15h
,
18h
,
1
, offset stru_427230.nFlag
+
0A0h
> __msRttiDscr <
0
,
008929C4
,
0FFFFFCD0h
,
402289h
>
【
402289
】
.text:
00402289
89
65
F0 mov [ebp
+
var_10], esp
.text:
0040228C
C6
45
FC
17
mov byte ptr [ebp
+
var_4],
17h
【
try
】【
17
】
.text:
00402290
6A
10
push
10h
; Size
.text:
00402292
8B
85
D0 FC FF FF mov eax, [ebp
+
Buf2] 【buff】【g_sd_g_szDec】【注意
try
与 catch 的参数的传递】
.text:
00402298
50
push eax ; Buf2
.text:
00402299
8D
4D
D8 lea ecx, [ebp
+
Buf1] ; Load Effective Address 【szInput】
.text:
0040229C
51
push ecx ; Buf1
.text:
0040229D
E8
2A
8B
01
00
call _memcmp ; Call Procedure 【memcmp(szInput, buff,
16
);】
.text:
004022A2
83
C4
0C
add esp,
0Ch
; Add
.text:
004022A5
89
85
F8 FC FF FF mov [ebp
+
var_308], eax 【结果】
.text:
004022AB
33
D2 xor edx, edx ; Logical Exclusive OR
.text:
004022AD
83
BD F8 FC FF FF
00
cmp
[ebp
+
var_308],
0
; Compare Two Operands 【相等,则 eax
=
1
】
.text:
004022B4
0F
94
C2 setz dl ;
Set
Byte
if
Zero (ZF
=
1
)
.text:
004022B7
88
95
61
FD FF FF mov [ebp
+
var_29F], dl
.text:
004022BD
0F
B6
85
61
FD FF FF movzx eax, [ebp
+
var_29F] ; Move with Zero
-
Extend
.text:
004022C4
85
C0 test eax, eax ; Logical Compare
.text:
004022C6
74
2D
jz short loc_4022F5 ; Jump
if
Zero (ZF
=
1
)
.text:
004022C8
BA
00
01
00
00
mov edx,
100h
【此时 ZF
=
0
,也就是非零】
.text:
004022CD
B9 D9
34
89
00
mov ecx, offset unk_8934D9
.text:
004022D2
E8
49
ED FF FF call sub_401020 ; Call Procedure【随机化】
.text:
004022D7
8D
8D
90
FC FF FF lea ecx, [ebp
+
var_370] ; Load Effective Address
.text:
004022DD
E8 EE ED FF FF call sub_4010D0 ; Call Procedure
.text:
004022E2
68
90
79
42
00
push offset __TI1?AVexception@std@@ ; pThrowInfo
.text:
004022E7
8D
8D
90
FC FF FF lea ecx, [ebp
+
var_370] ; Load Effective Address 【throw std::exception{};】
/
/
class
std::exception
.rdata:
00427230
__msRttiDscr <
9
,
00892A20
,
0
,
402321h
>
.text:
004022ED
51
push ecx ; pExceptionObject
.text:
004022EE
E8 FB
69
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.text:
004022F5
loc_4022F5: 【失败】
.text:
004022F5
BA
00
01
00
00
mov edx,
100h
.text:
004022FA
B9 D9
34
89
00
mov ecx, offset unk_8934D9
.text:
004022FF
E8
1C
ED FF FF call sub_401020 ; Call Procedure【随机化】
.text:
00402304
C7
85
F4 FC FF FF
01
00
00
00
mov [ebp
+
var_30C],
1
【 throw
1
;】.rdata:
00427230
__msRttiDscr <
40h
,
0
,
0
,
402349h
>
.text:
0040230E
68
28
79
42
00
push offset __TI1H ; pThrowInfo
.text:
00402313
8D
95
F4 FC FF FF lea edx, [ebp
+
var_30C] ; Load Effective Address
.text:
00402319
52
push edx ; pExceptionObject
.text:
0040231A
E8 CF
69
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
【
try
:
17
有两个catch,此时会通过对象值来判断用哪一个catch】
.rdata:
00427140
TryBlockMapEntry <
17h
,
17h
,
18h
,
2
, offset stru_427230.nFlag
+
80h
> __msRttiDscr <
9
,
00892A20
,
0
,
402321h
>
.rdata:
00427230
__msRttiDscr <
9
,
00892A20
,
0
,
402321h
>
/
/
class
std::exception
.rdata:
00427230
__msRttiDscr <
40h
,
0
,
0
,
402349h
>
【
402321
】
.text:
00402326
E8
75
ED FF FF call sub_4010A0 ; Call Procedure
.text:
0040232B
83
C4
04
add esp,
4
; Add
.text:
0040232E
68
A4
68
42
00
push offset aPause ;
"pause"
.text:
00402333
E8
2F
9B
00
00
call sub_40BE67 ; Call Procedure
.text:
00402338
83
C4
04
add esp,
4
; Add
.text:
0040233B
6A
00
push
0
; uExitCode
.text:
0040233D
FF
15
04
D0
41
00
call ds:ExitProcess ; Indirect Call Near Procedure
unk_8934A0:g_sd
unk_8934B9:g_sd_g_szSerial
unk_8935D9:
8
个字节为
0
unk_8995F1:
0x10
个字节与 用户名相等
8935D9
-
8934A0
=
139
8995F1
-
8934A0
=
6151
8934B9
-
8934A0
=
19
g_sd_g_szSerial:用户输入的序列号,
32
字节
##############################################################
.text:
00401406
68
8C
68
42
00
push offset aInputName ;
"Input name:"
.text:
0040140B
E8
90
FC FF FF call sub_4010A0 ; Call Procedure
.text:
00401410
83
C4
04
add esp,
4
; Add
.text:
00401413
BA
10
00
00
00
mov edx,
10h
.text:
00401418
8D
4D
D8 lea ecx, [ebp
+
Buf1] ;
Buffer
.text:
0040141B
E8
70
FE FF FF call sub_401290 ; Call Procedure
.text:
00401420
0F
B6 D0 movzx edx, al ; Move with Zero
-
Extend
.text:
00401423
85
D2 test edx, edx ; Logical Compare
.text:
00401425
75
21
jnz short loc_401448 ; Jump
if
Not Zero (ZF
=
0
)
【Buf1】【局部变量】:用户输入的用户名
.text:
004014D0
.text:
004014D0
loc_4014D0:
.text:
004014D0
68
AC
68
42
00
push offset aInputKey ;
"Input key:"
.text:
004014D5
E8 C6 FB FF FF call sub_4010A0 ; Call Procedure
.text:
004014DA
83
C4
04
add esp,
4
; Add
.text:
004014DD
BA
40
00
00
00
mov edx,
40h
;
'@'
.text:
004014E2
8D
8D
70
FF FF FF lea ecx, [ebp
+
Buffer
] ;
Buffer
.text:
004014E8
E8 A3 FD FF FF call sub_401290 ; Call Procedure
.text:
004014ED
0F
B6 C0 movzx eax, al ; Move with Zero
-
Extend
.text:
004014F0
85
C0 test eax, eax ; Logical Compare
.text:
004014F2
75
21
jnz short loc_401515 ; Jump
if
Not Zero (ZF
=
0
)
【
Buffer
】【局部变量】:用户输入的序列号
.text:
00401515
.text:
00401515
loc_401515:
.text:
00401515
33
C9 xor ecx, ecx ; Logical Exclusive OR
.text:
00401517
89
4D
B8 mov [ebp
+
var_48], ecx
.text:
0040151A
89
4D
BC mov [ebp
+
var_44], ecx
.text:
0040151D
89
4D
C0 mov [ebp
+
var_40], ecx
.text:
00401520
89
4D
C4 mov [ebp
+
var_3C], ecx
.text:
00401523
89
4D
C8 mov [ebp
+
var_38], ecx
.text:
00401526
89
4D
CC mov [ebp
+
var_34], ecx
.text:
00401529
89
4D
D0 mov [ebp
+
var_30], ecx
.text:
0040152C
89
4D
D4 mov [ebp
+
var_2C], ecx
######【ebp+var_48】【局部变量】【 unsigned char byteEnc[32] = { 0 };】
.text:
0040152F
8D
55
B8 lea edx, [ebp
+
var_48] ; Load Effective Address
.text:
00401532
8D
8D
70
FF FF FF lea ecx, [ebp
+
Buffer
] ; Load Effective Address
.text:
00401538
E8 A3 FD FF FF call sub_4012E0 ; Call Procedure
######【ebp+var_48 = string2hex(szEnc)】【局部变量】【 string2hex(szEnc, byteEnc);】【此处是 16进制字符串 转 16进制】
.text:
0040153D
0F
B6 D0 movzx edx, al ; Move with Zero
-
Extend
.text:
00401540
85
D2 test edx, edx ; Logical Compare
.text:
00401542
75
21
jnz short loc_401565 ; Jump
if
Not Zero (ZF
=
0
)
【第一个是将用户输入的 序列号 拷贝到了 全局变量 unk_8934B9 长度是
32
字节(转换之后),之前是
64
个字符。】
######【unk_8934B9】【输入 序列号】【memcpy(g_sd_g_szSerial, byteEnc, 32);】
.text:
00401565
loc_401565:
.text:
00401565
B9
08
00
00
00
mov ecx,
8
.text:
0040156A
8D
75
B8 lea esi, [ebp
+
var_48] ; Load Effective Address
.text:
0040156D
BF B9
34
89
00
mov edi, offset unk_8934B9
.text:
00401572
F3 A5 rep movsd ; Move Byte(s)
from
String to String
【第二个是将内置的数据拷贝到了 全局变量】
.text:
00401574
C6
85
6C
FD FF FF
95
mov [ebp
+
var_294],
95h
.text:
0040157B
C6
85
6D
FD FF FF E2 mov [ebp
+
var_293],
0E2h
.text:
00401582
C6
85
6E
FD FF FF
80
mov [ebp
+
var_292],
80h
.text:
00401589
C6
85
6F
FD FF FF C6 mov [ebp
+
var_291],
0C6h
.text:
00401590
C6
85
70
FD FF FF EA mov [ebp
+
var_290],
0EAh
.text:
00401597
C6
85
71
FD FF FF C3 mov [ebp
+
var_28F],
0C3h
…………………………………………………………………………………………………………………………………………………………………………
.text:
00401C58
C6
85
68
FE FF FF CF mov [ebp
+
var_198],
0CFh
.text:
00401C5F
C6
85
69
FE FF FF AE mov [ebp
+
var_197],
0AEh
.text:
00401C66
C6
85
6A
FE FF FF
8B
mov [ebp
+
var_196],
8Bh
.text:
00401C6D
C6
85
6B
FE FF FF CA mov [ebp
+
var_195],
0CAh
#########################################################################################################
.text:
00401C74
8D
85
6C
FE FF FF lea eax, [ebp
+
var_194] ; Load Effective Address
.text:
00401C7A
50
push eax
.text:
00401C7B
8D
8D
6C
FD FF FF lea ecx, [ebp
+
var_294] ; Load Effective Address
.text:
00401C81
51
push ecx
.text:
00401C82
8D
8D
7C
FC FF FF lea ecx, [ebp
+
var_384] ; Load Effective Address
.text:
00401C88
E8 D3
07
00
00
call unknown_libname_3 ; Microsoft VisualC
14
/
net runtime
.text:
00401C8D
8B
50
04
mov edx, [eax
+
4
]
.text:
00401C90
52
push edx
.text:
00401C91
8B
00
mov eax, [eax]
.text:
00401C93
50
push eax
.text:
00401C94
8D
8D
E8 FC FF FF lea ecx, [ebp
+
var_318] ; Load Effective Address
.text:
00401C9A
E8
41
08
00
00
call sub_4024E0 ; Call Procedure
#########################################################################################################
上面这段代码,应该是执行了一个内部的机制。
list
<uint8_t> list_table
=
{}
程序现将所有的数据赋值给了一堆局部变量,然后将 [ebp
+
var_294] 作为
list
<uint8_t> list_table 的地址,调用了 unknown_libname_3 方法
接下来:call sub_4024E0 没看明白。。。。(
2022
-
06
-
03
2120
)
######【ebp+var_194】:长度 0x100 = 256 字节
#########################################################################################################
.text:
00401C9F
C7
45
FC
00
00
00
00
mov [ebp
+
var_4],
0
【
try
】【
0
】
.text:
00401CA6
68
00
01
00
00
push
100h
;
.text:
00401CAB
6A
00
push
0
;
.text:
00401CAD
8D
8D
70
FE FF FF lea ecx, [ebp
+
var_190] ;
.text:
00401CB3
51
push ecx ; void
*
.text:
00401CB4
E8
17
71
00
00
call _memset ; Call Procedure【内存拷贝,其实是初始化了局部变量 】【[ebp
+
var_190]】
.text:
00401CB9
83
C4
0C
add esp,
0Ch
;
.text:
00401CBC
C6
45
FC
01
mov byte ptr [ebp
+
var_4],
1
【
try
】【
1
】
.text:
00401CC0
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands
.text:
00401CC4
7D
1E
jge short loc_401CE4 ; Jump
if
Greater
or
Equal (SF
=
OF)【大于等于
100
,则退出】
######【ebp+var_190】:长度 0x100 = 256 字节
/
/
对应于C
# uint8_t table[256] = { };
.text:
00401CC6
8D
8D
B4 FC FF FF lea ecx, [ebp
+
pExceptionObject] ; Load Effective Address
.text:
00401CCC
E8 FF F3 FF FF call sub_4010D0 ; Call Procedure
.text:
00401CD1
68
90
79
42
00
push offset __TI1?AVexception@std@@ ; pThrowInfo
.text:
00401CD6
8D
95
B4 FC FF FF lea edx, [ebp
+
pExceptionObject] ; Load Effective Address
.text:
00401CDC
52
push edx ; pExceptionObject
.text:
00401CDD
E8
0C
70
00
00
call __CxxThrowException@
8
; attributes:
.rdata:
00427140
stru_427140 TryBlockMapEntry <
1
,
1
,
2
,
2
, offset stru_427230> __msRttiDscr <
9
,
00892A20
,
0
,
401D04h
>
【
401D04
】
.text:
00401D04
C7
85
D8 FC FF FF D9
34
89
00
mov [ebp
+
var_328], offset unk_8934D9
.text:
00401D0E
C7
85
44
FD FF FF
00
00
00
00
mov [ebp
+
var_2BC],
0
【循环索引:
0
】
.text:
00401D18
8D
8D
E8 FC FF FF lea ecx, [ebp
+
var_318] ; Load Effective Address 【循环长度】
.text:
00401D1E
89
8D
34
FD FF FF mov [ebp
+
var_2CC], ecx
.text:
00401D24
8D
95
48
FD FF FF lea edx, [ebp
+
var_2B8] ; Load Effective Address
.text:
00401D2A
52
push edx
.text:
00401D2B
8B
8D
34
FD FF FF mov ecx, [ebp
+
var_2CC]
.text:
00401D31
E8
5A
07
00
00
call sub_402490 ; Call Procedure 【找this指针?】
.text:
00401D36
8D
85
DC FC FF FF lea eax, [ebp
+
var_324] ; Load Effective Address
.text:
00401D3C
50
push eax
.text:
00401D3D
8B
8D
34
FD FF FF mov ecx, [ebp
+
var_2CC]
.text:
00401D43
E8
38
07
00
00
call ?_Unwrapped@?$_Tree_iterator@V?$_Tree_val@U?$_Tree_simple_types@U?$pair@QAXU_Mutex_count_pair@?A0x04e813ea@@@std@@@std@@@std@@@std@@QBE?AV?$_Tree_unchecked_iterator@V?$_Tree_val@U?$_Tree_simple_types@U?$pair@QAXU_Mutex_count_pair@?A0x04e813ea@@@std@@@std@@@std@@@
2
@XZ ; std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<void
*
const,`anonymous namespace'::_Mutex_count_pair>>>>::_Unwrapped(void)
.text:
00401D48
EB
0B
jmp short loc_401D55 ; Jump
.text:
00401D55
.text:
00401D55
loc_401D55:
.text:
00401D55
8D
8D
DC FC FF FF lea ecx, [ebp
+
var_324] ; Load Effective Address
.text:
00401D5B
51
push ecx
.text:
00401D5C
8D
8D
48
FD FF FF lea ecx, [ebp
+
var_2B8] ; Load Effective Address
.text:
00401D62
E8 D9
06
00
00
call unknown_libname_2 ; Microsoft VisualC
14
/
net runtime
.text:
00401D67
0F
B6 D0 movzx edx, al ; Move with Zero
-
Extend
.text:
00401D6A
85
D2 test edx, edx ; Logical Compare
.text:
00401D6C
74
38
jz short loc_401DA6 ; catch执行之后,下一个地址存入eax里面
.text:
00401DA6
loc_401DA6: ; catch执行之后,下一个地址存入eax里面
.text:
00401DA6
B8 EC
1D
40
00
mov eax, offset loc_401DEC
.text:
00401DAB
C3 retn ; Return Near
from
Procedure
.text:
00401DEC
loc_401DEC:
.text:
00401DEC
C7
45
FC
00
00
00
00
mov [ebp
+
var_4],
0
【
try
】【
0
】
.text:
00401DF3
.text:
00401DF3
loc_401DF3:
.text:
00401DF3
C7
85
64
FD FF FF FC
30
0D
00
mov [ebp
+
dwSize],
0D30FCh
【size_t decompress_size
=
0x000d30f2
+
10
;】
.text:
00401DFD
C7
85
D4 FC FF FF
00
00
00
00
mov [ebp
+
var_32C],
0
【LPBYTE lpbuff1
=
NULL;】
.text:
00401E07
C7
85
5C
FD FF FF
00
00
00
00
mov [ebp
+
var_2A4],
0
【uLong shellcode_size
=
0
;】
.text:
00401E11
C7
85
58
FD FF FF
00
00
00
00
mov [ebp
+
var_2A8],
0
【uLongf ulongfsize
=
0
;】
.text:
00401E1B
C6
45
FC
03
mov byte ptr [ebp
+
var_4],
3
【
try
】【
3
】
.text:
00401E1F
6A
40
push
40h
;
'@'
; flProtect
.text:
00401E21
68
00
10
00
00
push
1000h
; flAllocationType
.text:
00401E26
8B
95
64
FD FF FF mov edx, [ebp
+
dwSize]
.text:
00401E2C
52
push edx ; dwSize
.text:
00401E2D
6A
00
push
0
; lpAddress
.text:
00401E2F
FF
15
00
D0
41
00
call ds:VirtualAlloc ; Indirect Call Near Procedure
【VirtualAlloc(NULL, decompress_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);】
.text:
00401E35
89
85
28
FD FF FF mov [ebp
+
var_2D8], eax 【LPBYTE lpbuff
=
】
.text:
00401E3B
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands
.text:
00401E3F
7D
1D
jge short loc_401E5E ; Jump
if
Greater
or
Equal (SF
=
OF)【<
100
】
【LPBYTE lpbuff】【局部变量】
=
即将存放的第一阶段代码
.text:
00401E41
8B
85
28
FD FF FF mov eax, [ebp
+
var_2D8]
.text:
00401E47
89
85
24
FD FF FF mov [ebp
+
var_2DC], eax
.text:
00401E4D
68
4C
7A
42
00
push offset __TI2PAE ; pThrowInfo
.text:
00401E52
8D
8D
24
FD FF FF lea ecx, [ebp
+
var_2DC] ; Load Effective Address
.text:
00401E58
51
push ecx ; pExceptionObject
.text:
00401E59
E8
90
6E
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.rdata:
00427140
TryBlockMapEntry <
3
,
3
,
18h
,
1
, offset stru_427230.nFlag
+
0D0h
> __msRttiDscr <
0
,
00892A10
,
0FFFFFD20h
,
401E63h
>
【
401E63
】
.text:
00401E63
89
65
F0 mov [ebp
+
var_10], esp
.text:
00401E66
8B
95
64
FD FF FF mov edx, [ebp
+
dwSize] ; 解密长度 【ulongfsize
=
(size_t)decompress_size;】
.text:
00401E6C
89
95
58
FD FF FF mov [ebp
+
var_2A8], edx
.text:
00401E72
C7
85
5C
FD FF FF
21
E9
0C
00
mov [ebp
+
var_2A4],
0CE921h
; 原始长度 【shellcode_size
=
sizeof(g_shellcode_compress_64_1);】
.text:
00401E7C
8B
85
5C
FD FF FF mov eax, [ebp
+
var_2A4]
.text:
00401E82
50
push eax
.text:
00401E83
68
90
D2
5C
00
push offset unk_5CD290 ; 原始数据密文 【g_shellcode_compress_64_1】
.text:
00401E88
8D
95
58
FD FF FF lea edx, [ebp
+
var_2A8] ; 解密长度
.text:
00401E8E
8B
8D
20
FD FF FF mov ecx, [ebp
+
var_2E0] ; 解密地址 【LPBYTE lpbuff】
.text:
00401E94
E8
67
F1 FF FF call sub_401000 ; 【第一阶段解码】
.text:
00401E99
83
C4
08
add esp,
8
; Add
.text:
00401E9C
C7
85
40
FD FF FF
00
00
00
00
mov [ebp
+
var_2C0],
0
【PFNDEC pfnDec1
=
NULL;】
.text:
00401EA6
C6
45
FC
05
mov byte ptr [ebp
+
var_4],
5
【
try
】【
5
】
.text:
00401EAA
8B
8D
20
FD FF FF mov ecx, [ebp
+
var_2E0]
.text:
00401EB0
89
8D
40
FD FF FF mov [ebp
+
var_2C0], ecx 【pfnDec1
=
(PFNDEC)lpbuff;】【存放
64
位代码】
.text:
00401EB6
83
7D
08
64
cmp
[ebp
+
argc],
64h
;
'd'
; Compare Two Operands
.text:
00401EBA
7D
1D
jge short loc_401ED9 ; Jump
if
Greater
or
Equal (SF
=
OF)
.text:
00401EBC
8B
95
40
FD FF FF mov edx, [ebp
+
var_2C0] 【catch 拷贝 对象】
.text:
00401EC2
89
95
1C
FD FF FF mov [ebp
+
var_2E4], edx
.text:
00401EC8
68
80
79
42
00
push offset __TI1P6AXPAE@Z ; pThrowInfo
.text:
00401ECD
8D
85
1C
FD FF FF lea eax, [ebp
+
var_2E4] ; Load Effective Address
.text:
00401ED3
50
push eax ; pExceptionObject
.text:
00401ED4
E8
15
6E
00
00
call __CxxThrowException@
8
; _CxxThrowException(x,x)
.rdata:
00427140
TryBlockMapEntry <
5
,
5
,
18h
,
1
, offset stru_427230.nFlag
+
0C0h
> __msRttiDscr <
0
,
008929FC
,
0FFFFFCCCh
,
401EDEh
>
【
401EDE
】【接下来就是一个
32
转
64
,执行完了之后,再转
32
】
.text:
00401EDE
89
65
F0 mov [ebp
+
var_10], esp
.text:
00401EE1
6A
FF push
0FFFFFFFFh
.text:
00401EE3
83
04
24
01
add [esp
+
var_s0],
1
; Add
.text:
00401EE7
68
FB
1E
40
00
push offset loc_401EFB
.text:
00401EEC
8D
0D
A0
34
89
00
lea ecx, unk_8934A0 ; Load Effective Address
.text:
00401EF2
6A
33
push
33h
;
'3'
.text:
00401EF4
FF B5 CC FC FF FF push [ebp
+
var_334]
.text:
00401EFA
CB retf ; Return Far
from
Procedure
.text:
00401EFB
.text:
00401EFB
loc_401EFB:
.text:
00401EFB
E8
00
00
00
00
call $
+
5
; Call Procedure
.text:
00401F00
C7
44
24
04
23
00
00
00
mov [esp
+
394h
+
var_390],
23h
;
'#'
.text:
00401F08
83
04
24
0D
add [esp
+
394h
+
var_394],
0Dh
; Add
.text:
00401F0C
CB retf ; Return Far
from
Procedure
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
【第二阶段开始】
.text:
00401F0D
BA
00
03
00
00
mov edx,
300h
.text:
00401F12
8B
8D
40
FD FF FF mov ecx, [ebp
+
var_2C0]
.text:
00401F18
E8
03
F1 FF FF call sub_401020 ; Call Procedure 【change_mem_rand(pfnDec1,
0x300
)】
.text:
00401F1D
C7
85
3C
FD FF FF
00
00
00
00
mov [ebp
+
var_2C4],
0
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
|
|
---|---|
|
期待完成
|
|
kanxue 期待完成混淆代码种类太多了,这是个体力活。 混淆循坏里嵌套混淆混淆、混淆循环里嵌入堆栈平衡无效代码,多种情况夹杂在一起,没有现成的脚本来实现去除。 目前还没写好的适配的脚本处理方法:科锐团队厉害,此题的WP都略过了去除混淆的方法,搞清楚此题,对能力提升非常有帮助。 |
|
目前对三段代码进行分析的时候,里面有大量的花指令,还有固定格式的,还有嵌套的,原理摸得差不多,但是用代码消除有点费劲,有没有对花指令研究透的大脑,特别是 科锐团队,可以一起交流交流下。
一直想录制一段视频,发现整理框架代码可以讲清楚,但是三段代码如何去除花指令,最后得出加密的逻辑代码,卡壳了 |
|
接主题帖: 首先贴出三段dump出来的代码。 |
|
dump1.exe:第一段代码是64bit,里面有大量花指令,需要进行清除之后,才方便进行程序逻辑分析。(待续) |
|
dump2.exe:第二段代码是32bit,里面有大量花指令,需要进行清除之后,才方便进行程序逻辑分析。 花指令的特征主要有如下几处: 一、连续的指令 1、ebp、esp还原【是后面的特例】 seg000:000CC824 014 55 push ebp seg000:000CC825 018 89 E5 mov ebp, esp seg000:000CC827 018 8D 64 24 FC lea esp, [esp-4] seg000:000CC82B 01C 89 EC mov esp, ebp seg000:000CC82D 01C 5D pop ebp 2、esp还原【是后面的特例】 seg000:000C5FBA 01C 52 push edx seg000:000C5FBB 020 8D 64 24 04 lea esp, [esp+4] 3、无用指令【待核实,只有一处】 seg000:0021C40D 84 56 C7 test [esi-39h], dl seg000:0021C410 08 00 or [eax], al
1、ebp、esp还原【中间嵌入长跳转】 seg000:000CC824 014 55 push ebp seg000:000CC825 018 89 E5 mov ebp, esp seg000:000CC827 018 8D 64 24 FC lea esp, [esp-4] seg000:000CC82B 01C 89 EC mov esp, ebp seg000:000CC82D 01C 5D pop ebp 2、esp还原【中间嵌入长跳转】 seg000:000C5FBA 01C 52 push edx seg000:000C5FBB 020 8D 64 24 04 lea esp, [esp+4] 3、pushf、popf还原【中间嵌入长跳转】 seg000:002A0496 loc_2A0496: ; CODE XREF: seg000:00000001↑j seg000:002A0496 9C pushf seg000:002A0497 51 push ecx seg000:002A0498 50 push eax seg000:002A0499 31 C0 xor eax, eax seg000:002A049B seg000:002A049B loc_2A049B: ; CODE XREF: seg000:002A04B3↓j seg000:002A049B 83 F8 03 cmp eax, 3 seg000:002A049E 74 15 jz short loc_2A04B5 seg000:002A04A0 40 inc eax seg000:002A04A1 81 E9 2E CD 9B A2 sub ecx, 0A29BCD2Eh seg000:002A04A7 81 C9 07 48 0C 20 or ecx, 200C4807h seg000:002A04AD 81 D9 2B 22 BB B1 sbb ecx, 0B1BB222Bh seg000:002A04B3 72 E6 jb short loc_2A049B seg000:002A04B5 seg000:002A04B5 loc_2A04B5: ; CODE XREF: seg000:002A049E↑j seg000:002A04B5 58 pop eax seg000:002A04B6 59 pop ecx seg000:002A04B7 9D popf 4、pushf、popf还原【中间嵌入长跳转、还嵌套自身】 seg000:002AE278 9C pushf seg000:002AE279 E9 5E 37 FB FF jmp loc_2619DC seg000:002619DC loc_2619DC: ; CODE XREF: seg000:002AE279↓j seg000:002619DC 52 push edx seg000:002619DD 51 push ecx seg000:002619DE 9C pushf 【此处 嵌套了自身】 seg000:002619DF 50 push eax seg000:002619E0 52 push edx seg000:002619E1 31 D2 xor edx, edx seg000:002619E3 seg000:002619E3 loc_2619E3: ; CODE XREF: seg000:002619F8↓j seg000:002619E3 83 FA 0A cmp edx, 0Ah seg000:002619E6 74 12 jz short loc_2619FA seg000:002619E8 42 inc edx seg000:002619E9 05 3F 86 3A 6F add eax, 6F3A863Fh seg000:002619EE 0D 99 24 DF 25 or eax, 25DF2499h seg000:002619F3 05 D0 BA 30 4B add eax, 4B30BAD0h seg000:002619F8 7E E9 jle short loc_2619E3 seg000:002619FA seg000:002619FA loc_2619FA: ; CODE XREF: seg000:002619E6↑j seg000:002619FA 5A pop edx seg000:002619FB 58 pop eax seg000:002619FC 9D popf seg000:002619FD E9 B6 62 EC FF jmp loc_127CB8 seg000:00127CB8 loc_127CB8: ; CODE XREF: seg000:002619FD↓j seg000:00127CB8 31 C9 xor ecx, ecx seg000:00127CBA seg000:00127CBA loc_127CBA: ; CODE XREF: seg000:000FAD33↑j seg000:00127CBA 83 F9 06 cmp ecx, 6 seg000:00127CBD 55 push ebp seg000:00127CBE 89 E5 mov ebp, esp seg000:00127CC0 8D 64 24 FC lea esp, [esp-4] seg000:00127CC4 89 EC mov esp, ebp seg000:00127CC6 5D pop ebp seg000:00127CC7 E9 E0 48 F4 FF jmp loc_6C5AC seg000:0006C5AC loc_6C5AC: ; CODE XREF: seg000:00127CC7↓j seg000:0006C5AC 0F 84 15 0A FF FF jz loc_5CFC7 seg000:0006C5B2 41 inc ecx seg000:0006C5B3 E9 78 7B 1B 00 jmp loc_224130 seg000:00224130 loc_224130: ; CODE XREF: seg000:0006C5B3↑j seg000:00224130 81 FA 6B 15 C8 6D cmp edx, 6DC8156Bh seg000:00224136 81 E2 38 42 C7 AF and edx, 0AFC74238h seg000:0022413C E9 EC 6B ED FF jmp loc_FAD2D seg000:000FAD2D loc_FAD2D: ; CODE XREF: seg000:0022413C↓j seg000:000FAD2D 81 DA FA A1 7F 86 sbb edx, 867FA1FAh seg000:000FAD33 0F 80 81 CF 02 00 jo loc_127CBA seg000:000FAD39 E9 89 22 F6 FF jmp loc_5CFC7 seg000:0005CFC7 loc_5CFC7: ; CODE XREF: seg000:loc_6C5AC↓j seg000:0005CFC7 ; seg000:000FAD39↓j seg000:0005CFC7 59 pop ecx seg000:0005CFC8 5A pop edx seg000:0005CFC9 E9 54 CF 1E 00 jmp loc_249F22 seg000:00249F22 loc_249F22: ; CODE XREF: seg000:0005CFC9↑j seg000:00249F22 9D popf seg000:00249F23 8D 64 24 04 lea esp, [esp+4] seg000:00249F27 E9 4B AA E9 FF jmp loc_E4977 seg000:000E4977 loc_E4977: ; CODE XREF: seg000:00249F27↓j seg000:000E4977 E9 C5 2E 1A 00 jmp loc_287841 seg000:00287841 loc_287841: ; CODE XREF: seg000:loc_E4977↑j seg000:00287841 9D popf 这两个花指令的简略特征是: 9C pushf 52 push edx 51 push ecx 31 C9 xor ecx, ecx 83 F9 08 cmp ecx, 8 【JZ 后续代码 的最后一个有条件跳转会 跳转到此处】 0F 84 A2 17 E4 FF jz loc_E9020 59 pop ecx 5A pop edx 9D popf 【JZ】后续代码 特征1: 47 inc edi 81 EA 4A 0A 6A C8 sub edx, 0C86A0A4Ah 81 F2 F7 12 2D EE xor edx, 0EE2D12F7h 81 EA C6 07 02 1C sub edx, 1C0207C6h 0F 89 FB E3 13 00 jns loc_1D2296 特征2: 43 inc ebx 1D F3 63 58 CC sbb eax, 0CC5863F3h 25 DC C9 C5 7F and eax, 7FC5C9DCh 05 C8 9D D9 2E add eax, 2ED99DC8h 0F 8D FB 01 FA FF jge loc_1A7C7E 特征3: 41 inc ecx 3D 7C AA 0E E6 cmp eax, 0E60EAA7Ch 35 93 5A FA 84 xor eax, 84FA5A93h 1D 64 15 D9 23 sbb eax, 23D91564h 0F 88 B0 7F EA FF js loc_158A72 特征4: 41 inc ecx 81 D2 B7 D6 07 45 adc edx, 4507D6B7h 81 CA 5A 03 73 78 or edx, 7873035Ah 81 C2 10 EA 7D 71 add edx, 717DEA10h 0F 88 E1 61 03 00 js loc_1CC00A 特征5: 41 inc ecx 15 CB 30 92 03 adc eax, 39230CBh 25 86 2C C9 70 and eax, 70C92C86h 15 17 1C 96 C5 adc eax, 0C5961C17h 0F 86 FE 34 11 00 jbe loc_2077A4 现在需要对其进行批量消除 1、首先去除固定的连续指令序列,这个较为简单,也能很快去除。 2、其次去除带有跳转的不连续指令序列,这个较为麻烦,需要分析指令。 3、检查,是否有遗漏,或是错误删除。 在消除过程中:注意需要将JZ处指令,改成JMP,强制跳转过去【可有效避免F5时垃圾代码生成】;将pushf处指令改为jmp,直接跳转到popf之后的指令【跳出花指令干扰】。 留出疑问: 1、尝试,不对垃圾指令进行nop,是否能够避免错误? 2、代码里面存在 自加密解密,那采用nop会存在错误。。。 附python代码:仅供参考,去除完成之后,发现代码存在问题,一是没有全部清除干净,二是存在错误指令,疑似删错。 ############################################################################## #清除单个:注意主线的JMP保留【0-8】、支线的JMP消除【9-13】。 def clearSingle(patternList): #考虑清除 # 全部清0,将 jz 设置为 jmp if len(patternList)<=0: return for p in patternList: #实际上是第5条指令,如果有重复的JZ,那就需要只处理第5条指令。 if p[1].upper() == "JZ": #修改机器码 JMP if idc.get_wide_byte(p[0]) == 0x74: ida_bytes.patch_byte(p[0],0xEB) elif idc.get_wide_word(p[0])==0x840F: ida_bytes.patch_word(p[0],0xE990) continue else: #nop #my_nop(p[0],NextHead(p[0]))#有可能误删 nextAddr = idaapi.decode_insn(idaapi.insn_t(),p[0]) + p[0] my_nop(p[0],nextAddr) ###或者再进一步搜索一下,直接将分支都nop,但是如何才能得知回到循环了? ####修改首地址,跳转到末尾 def ModifySingle(patternList,endAddrIndex): if len(patternList)<=0: return startAddr = patternList[0][0] endAddr = patternList[endAddrIndex][0] insn = idaapi.insn_t() endAddr = idaapi.decode_insn(insn,endAddr) + endAddr PrintInfo2("#"*10+"修改首位地址,使其跳转到尾部。") PrintInfo2("startAddr=0x{:X},endAddr=0x{:X}".format(startAddr,endAddr)) patch_byte(startAddr,0xE9) ######################### ## startAddr = 0x2A0496 ## endAddr = 0x2A04B8 ## ## endAddr = 0x2A048D ######################### #### diffValue = endAddr - startAddr - 5 ####支持负数处理 value = struct.unpack('>L', struct.pack('l', diffValue))[0] & 0xFFFFFFFF #value = 0x1d000000 bytesValue = struct.pack('>L',value) #bytesValue = b'\x1d\x00\x00\x00' #strValue = bytesValue.hex() #strValue = '1d000000' #value = hex(value)[2:] idaapi.patch_bytes(startAddr+1,bytesValue)
最后于 2022-8-31 13:13
被htg编辑
,原因:
|
|
2022-10-14 2325 发现新的匹配方式: 看来需要现对等效代码做一个替换,然后再用通用的方式来处理,这里还是涉及到长跳转的处理。 lea esp, [esp-4] jmp ...... mov [esp+8+var_8], edi ///等效为 【push edi】 等效为 【push edi】 ---------------------------------- mov eax, [esp+0Ch+var_C] ///等效为 【pop eax】 jmp loc_12F11B lea esp, [esp+4] 等效为 【pop eax】 seg000:000089C8 loc_89C8: ; CODE XREF: sub_1DC2DF:loc_58E65↓j seg000:000089C8 pushf seg000:000089C9 jmp loc_1EBF44 seg000:001EBF44 loc_1EBF44: ; CODE XREF: sub_1DC2DF-1D3916↑j seg000:001EBF44 pushf seg000:001EBF45 jmp loc_7961A seg000:0007961A loc_7961A: ; CODE XREF: seg000:001BE3E8↓j seg000:0007961A ; sub_1DC2DF+FC66↓j seg000:0007961A lea esp, [esp-4] seg000:0007961E mov [esp+8+var_8], edi ///等效为 【push edi】 seg000:00079621 jmp loc_1F1B2E seg000:001F1B2E loc_1F1B2E: ; CODE XREF: sub_1DC2DF-162CBE↑j seg000:001F1B2E lea esp, [esp-4] seg000:001F1B32 mov [esp+0Ch+var_C], eax ///等效为 【push eax】 seg000:001F1B35 jmp loc_85EEC seg000:00085EEC loc_85EEC: ; CODE XREF: sub_1DC2DF+15856↓j seg000:00085EEC jmp loc_20B1E8 seg000:0020B1E8 loc_20B1E8: ; CODE XREF: sub_1DC2DF:loc_85EEC↑j seg000:0020B1E8 xor eax, eax seg000:0020B1EA jmp loc_1A1C4 seg000:0001A1C4 loc_1A1C4: ; CODE XREF: sub_1DC2DF+2EF0B↓j seg000:0001A1C4 jmp loc_E2395 seg000:000E2395 loc_E2395: ; CODE XREF: sub_1DC2DF:loc_1A1C4↑j seg000:000E2395 ; seg000:loc_7AB77↑j seg000:000E2395 cmp eax, 6 seg000:000E2398 jmp loc_86E48 seg000:00086E48 loc_86E48: ; CODE XREF: sub_1DC2DF-F9F47↓j seg000:00086E48 jz loc_82FF5 seg000:00086E4E jmp loc_6F4B4 seg000:0006F4B4 loc_6F4B4: ; CODE XREF: sub_1DC2DF-155491↓j seg000:0006F4B4 inc eax seg000:0006F4B5 jmp loc_21BB65 seg000:0021BB65 loc_21BB65: ; CODE XREF: sub_1DC2DF-16CE2A↑j seg000:0021BB65 adc edi, 17EF568Dh seg000:0021BB6B pushf 【新的嵌套循环】 seg000:0021BB6C jmp loc_1440CF seg000:001440CF loc_1440CF: ; CODE XREF: sub_1DC2DF+3F88D↓j seg000:001440CF jmp loc_15C847 seg000:0015C847 loc_15C847: ; CODE XREF: sub_1DC2DF:loc_1440CF↑j seg000:0015C847 push ebx seg000:0015C848 push eax seg000:0015C849 jmp loc_273C72 ------ seg000:00082FF5 loc_82FF5: ; CODE XREF: seg000:0007AB7D↑j seg000:00082FF5 ; sub_1DC2DF:loc_86E48↓j seg000:00082FF5 mov eax, [esp+0Ch+var_C] ///等效为 【pop eax】 seg000:00082FF8 jmp loc_12F11B seg000:0012F11B loc_12F11B: ; CODE XREF: sub_1DC2DF-1592E7↑j seg000:0012F11B lea esp, [esp+4] seg000:0012F11F pushf 【新的嵌套循环】 seg000:0002042D loc_2042D: ; CODE XREF: sub_1DC2DF-AD1BF↓j seg000:0002042D push edx seg000:0002042E push ecx seg000:0002042F jmp loc_2606FB |