针对r3层的最强防御,应该就是自己实现调用r0的内核函数。不使用系统提供的API接口。这样能防御别人在导入函数的下断点,或者IAT HOOK。当然如果有些函数是不用进入内核,在r3层就 实现了所有功能的,不在这个讨论范围之内。
通过具体的两个API,来看r3是如何进入r0,看如何实现权限切换的。分析的环境为win10x64,版本为1903,样本程序也是64位程序。
调用OpenProcess
OpenProcess本质调用的是NtOpenProcess
NtOpenProcess的关键代码就是调用syscall
● 本质上所有进入内核的API都是通过syscall(32系统通过sysenter来进入内核,xp通过int 0x2e中断进入内核)进入r0,通过sysret从r0返回r3.
● 通过寄存器eax来区分不同的API.实际这个编号就是SSDT的序号。
● 参数通过栈传递,拷贝
● 关于0x7FFE308是_KUSER_SHARED_DATA结构体。内核有读写权限,r3只有读取权限。通过 _KUSER_SHARED_DATA.SystemCall的高位来判断系统是走中断进入内核还是通过门进入内核。
_KUSER_SHARED_DATA结构体解析如下:
● mov r10,rcx为什么要添加这句汇编指令,没有分析出来求大佬补充。
● 注意这里用windbg单步步入syscall是会跑飞的,只能在nt!NtOpenProcess下个断点,才能调试内核。
VirtualAllocEx函数调用
VirtualAllocEx内部调用kernelbase.VirtualAllocExNuma
kernelbase.VirtualAllocExNuma 调用 ZwAllocateVirtualMemory
ntdll!ZwAllocateVirtualMemory 进入内核
● 内核对应函数名nt!NtAllocateVirtualMemory
●
通过分析后得到,r3层最底层调用的是ntdll!NtOpenProcess。下面开始实现ntdll!NtOpenProcess。
● 由于vs对64位程序,不支持内联汇编。所以这里使用汇编和c/c++的联合编译。
● 由于根据IDA下载的微软pdb,能够解析NtOpenProcess调用的时候传入的参数的类型。但是没有具体的结构体的定义
● 通过wrk查询到OBJECT_ATTRIBUTES和CLIENT_ID结构体的定义。
门调用的关键代码
r3VirtualAllocExNuma测试效果如下:
在ZwAllocateVirtualMemory下断点是不会被命中的:
● 本意是想在写壳的时候,初始化IAT的时候,将IAT填入自己实现的API调用,避免在关键API下断。
● 奈何windows版本太多,ssdt的序号每个版本可能变化。提供两个思路:
○ 从不同版本的ntdll文件中解析ssdt序号
○ 从不同版本的pdb来解析ssdt序号
● 思路来自张老师讲Android的api的调用。Android的API序号不变,没有版本兼容问题。
● 如果有什么不对的欢迎大佬指点
00007FF790489EEF
|
44
:
8B85
20010000
| mov r8d,dword ptr ss:[rbp
+
120
] | TestDomeDlg.cpp:
632
/
/
pid
00007FF790489EF6
|
33D2
| xor edx,edx |
/
/
false
00007FF790489EF8
| B9 FFFF1F00 | mov ecx,
1FFFFF
|
/
/
PROCESS_ALL_ACCESS
00007FF790489EFD
| FF15
4D21AB00
| call qword ptr ds:[<&OpenProcess>] |
00007FF790489EEF
|
44
:
8B85
20010000
| mov r8d,dword ptr ss:[rbp
+
120
] | TestDomeDlg.cpp:
632
/
/
pid
00007FF790489EF6
|
33D2
| xor edx,edx |
/
/
false
00007FF790489EF8
| B9 FFFF1F00 | mov ecx,
1FFFFF
|
/
/
PROCESS_ALL_ACCESS
00007FF790489EFD
| FF15
4D21AB00
| call qword ptr ds:[<&OpenProcess>] |
00007FFC7207C0F0
|
4C
:
8BDC
| mov r11,rsp |
00007FFC7207C0F3
|
48
:
83EC
68
| sub rsp,
68
|
00007FFC7207C0F7
|
49
:
8363
C0
00
|
and
qword ptr ds:[r11
-
40
],
0
|
00007FFC7207C0FC
|
4D
:
8D4B
B8 | lea r9,qword ptr ds:[r11
-
48
] |
00007FFC7207C100
|
49
:
63C0
| movsxd rax,r8d |
00007FFC7207C103
|
0F57C0
| xorps xmm0,xmm0 |
00007FFC7207C106
| C74424
30
30000000
| mov dword ptr ss:[rsp
+
30
],
30
|
30
:
'0'
00007FFC7207C10E
|
4D
:
8D43
C8 | lea r8,qword ptr ds:[r11
-
38
] |
00007FFC7207C112
|
49
:
8363
D0
00
|
and
qword ptr ds:[r11
-
30
],
0
|
00007FFC7207C117
| F7DA | neg edx |
00007FFC7207C119
|
49
:
8943
B8 | mov qword ptr ds:[r11
-
48
],rax |
00007FFC7207C11D
|
8BD1
| mov edx,ecx |
00007FFC7207C11F
|
49
:
8D4B
20
| lea rcx,qword ptr ds:[r11
+
20
] | [r11
+
20
]:L
"兽郴翷"
00007FFC7207C123
|
1BC0
| sbb eax,eax |
00007FFC7207C125
|
83E0
02
|
and
eax,
2
|
00007FFC7207C128
|
894424
48
| mov dword ptr ss:[rsp
+
48
],eax |
00007FFC7207C12C
|
49
:
8363
D8
00
|
and
qword ptr ds:[r11
-
28
],
0
| [r11
-
28
]:AfxWndProc
+
E1
00007FFC7207C131
| F3:
0F7F4424
50
| movdqu xmmword ptr ss:[rsp
+
50
],xmm0 |
00007FFC7207C137
|
48
:FF15 BA781900 | call qword ptr ds:[<&NtOpenProcess>] |
00007FFC7207C13E
|
0F1F4400
00
| nop dword ptr ds:[rax
+
rax],eax |
00007FFC7207C143
|
85C0
| test eax,eax |
00007FFC7207C145
|
78
0E
| js kernelbase.
7FFC7207C155
|
00007FFC7207C147
|
48
:
8B8424
88000000
| mov rax,qword ptr ss:[rsp
+
88
] |
00007FFC7207C14F
|
48
:
83C4
68
| add rsp,
68
|
00007FFC7207C153
| C3 | ret |
00007FFC7207C0F0
|
4C
:
8BDC
| mov r11,rsp |
00007FFC7207C0F3
|
48
:
83EC
68
| sub rsp,
68
|
00007FFC7207C0F7
|
49
:
8363
C0
00
|
and
qword ptr ds:[r11
-
40
],
0
|
00007FFC7207C0FC
|
4D
:
8D4B
B8 | lea r9,qword ptr ds:[r11
-
48
] |
00007FFC7207C100
|
49
:
63C0
| movsxd rax,r8d |
00007FFC7207C103
|
0F57C0
| xorps xmm0,xmm0 |
00007FFC7207C106
| C74424
30
30000000
| mov dword ptr ss:[rsp
+
30
],
30
|
30
:
'0'
00007FFC7207C10E
|
4D
:
8D43
C8 | lea r8,qword ptr ds:[r11
-
38
] |
00007FFC7207C112
|
49
:
8363
D0
00
|
and
qword ptr ds:[r11
-
30
],
0
|
00007FFC7207C117
| F7DA | neg edx |
00007FFC7207C119
|
49
:
8943
B8 | mov qword ptr ds:[r11
-
48
],rax |
00007FFC7207C11D
|
8BD1
| mov edx,ecx |
00007FFC7207C11F
|
49
:
8D4B
20
| lea rcx,qword ptr ds:[r11
+
20
] | [r11
+
20
]:L
"兽郴翷"
00007FFC7207C123
|
1BC0
| sbb eax,eax |
00007FFC7207C125
|
83E0
02
|
and
eax,
2
|
00007FFC7207C128
|
894424
48
| mov dword ptr ss:[rsp
+
48
],eax |
00007FFC7207C12C
|
49
:
8363
D8
00
|
and
qword ptr ds:[r11
-
28
],
0
| [r11
-
28
]:AfxWndProc
+
E1
00007FFC7207C131
| F3:
0F7F4424
50
| movdqu xmmword ptr ss:[rsp
+
50
],xmm0 |
00007FFC7207C137
|
48
:FF15 BA781900 | call qword ptr ds:[<&NtOpenProcess>] |
00007FFC7207C13E
|
0F1F4400
00
| nop dword ptr ds:[rax
+
rax],eax |
00007FFC7207C143
|
85C0
| test eax,eax |
00007FFC7207C145
|
78
0E
| js kernelbase.
7FFC7207C155
|
00007FFC7207C147
|
48
:
8B8424
88000000
| mov rax,qword ptr ss:[rsp
+
88
] |
00007FFC7207C14F
|
48
:
83C4
68
| add rsp,
68
|
00007FFC7207C153
| C3 | ret |
00007FFC7454D1F0
|
4C
:
8BD1
| mov r10,rcx |
00007FFC7454D1F3
| B8
26000000
| mov eax,
26
/
/
每个不同的API都有不同的编号来区分 |
26
:
'&'
00007FFC7454D1F8
| F60425
0803FE7F
01
| test byte ptr ds:[
7FFE0308
],
1
|
00007FFC7454D200
|
75
03
| jne ntdll.
7FFC7454D205
|
00007FFC7454D202
|
0F05
| syscall
/
/
通过门进入内核
00007FFC7454D204
| C3 | ret |
00007FFC7454D205
| CD
2E
|
int
2E
/
/
通过中断进入内核 |
00007FFC7454D207
| C3 | ret |
00007FFC7454D1F0
|
4C
:
8BD1
| mov r10,rcx |
00007FFC7454D1F3
| B8
26000000
| mov eax,
26
/
/
每个不同的API都有不同的编号来区分 |
26
:
'&'
00007FFC7454D1F8
| F60425
0803FE7F
01
| test byte ptr ds:[
7FFE0308
],
1
|
00007FFC7454D200
|
75
03
| jne ntdll.
7FFC7454D205
|
00007FFC7454D202
|
0F05
| syscall
/
/
通过门进入内核
00007FFC7454D204
| C3 | ret |
00007FFC7454D205
| CD
2E
|
int
2E
/
/
通过中断进入内核 |
00007FFC7454D207
| C3 | ret |
1
: kd> dt nt!_KUSER_SHARED_DATA
*
*
*
Unable to resolve unqualified symbol
in
Bp expression
'l'
.
+
0x000
TickCountLowDeprecated : Uint4B
+
0x004
TickCountMultiplier : Uint4B
+
0x008
InterruptTime : _KSYSTEM_TIME
+
0x014
SystemTime : _KSYSTEM_TIME
+
0x020
TimeZoneBias : _KSYSTEM_TIME
+
0x02c
ImageNumberLow : Uint2B
+
0x02e
ImageNumberHigh : Uint2B
+
0x030
NtSystemRoot : [
260
] Wchar
+
0x238
MaxStackTraceDepth : Uint4B
+
0x23c
CryptoExponent : Uint4B
+
0x240
TimeZoneId : Uint4B
+
0x244
LargePageMinimum : Uint4B
+
0x248
AitSamplingValue : Uint4B
+
0x24c
AppCompatFlag : Uint4B
+
0x250
RNGSeedVersion : Uint8B
+
0x258
GlobalValidationRunlevel : Uint4B
+
0x25c
TimeZoneBiasStamp : Int4B
+
0x260
NtBuildNumber : Uint4B
+
0x264
NtProductType : _NT_PRODUCT_TYPE
+
0x268
ProductTypeIsValid : UChar
+
0x269
Reserved0 : [
1
] UChar
+
0x26a
NativeProcessorArchitecture : Uint2B
+
0x26c
NtMajorVersion : Uint4B
+
0x270
NtMinorVersion : Uint4B
+
0x274
ProcessorFeatures : [
64
] UChar
+
0x2b4
Reserved1 : Uint4B
+
0x2b8
Reserved3 : Uint4B
+
0x2bc
TimeSlip : Uint4B
+
0x2c0
AlternativeArchitecture : _ALTERNATIVE_ARCHITECTURE_TYPE
+
0x2c4
BootId : Uint4B
+
0x2c8
SystemExpirationDate : _LARGE_INTEGER
+
0x2d0
SuiteMask : Uint4B
+
0x2d4
KdDebuggerEnabled : UChar
+
0x2d5
MitigationPolicies : UChar
+
0x2d5
NXSupportPolicy : Pos
0
,
2
Bits
+
0x2d5
SEHValidationPolicy : Pos
2
,
2
Bits
+
0x2d5
CurDirDevicesSkippedForDlls : Pos
4
,
2
Bits
+
0x2d5
Reserved : Pos
6
,
2
Bits
+
0x2d6
CyclesPerYield : Uint2B
+
0x2d8
ActiveConsoleId : Uint4B
+
0x2dc
DismountCount : Uint4B
+
0x2e0
ComPlusPackage : Uint4B
+
0x2e4
LastSystemRITEventTickCount : Uint4B
+
0x2e8
NumberOfPhysicalPages : Uint4B
+
0x2ec
SafeBootMode : UChar
+
0x2ed
VirtualizationFlags : UChar
+
0x2ee
Reserved12 : [
2
] UChar
+
0x2f0
SharedDataFlags : Uint4B
+
0x2f0
DbgErrorPortPresent : Pos
0
,
1
Bit
+
0x2f0
DbgElevationEnabled : Pos
1
,
1
Bit
+
0x2f0
DbgVirtEnabled : Pos
2
,
1
Bit
+
0x2f0
DbgInstallerDetectEnabled : Pos
3
,
1
Bit
+
0x2f0
DbgLkgEnabled : Pos
4
,
1
Bit
+
0x2f0
DbgDynProcessorEnabled : Pos
5
,
1
Bit
+
0x2f0
DbgConsoleBrokerEnabled : Pos
6
,
1
Bit
+
0x2f0
DbgSecureBootEnabled : Pos
7
,
1
Bit
+
0x2f0
DbgMultiSessionSku : Pos
8
,
1
Bit
+
0x2f0
DbgMultiUsersInSessionSku : Pos
9
,
1
Bit
+
0x2f0
DbgStateSeparationEnabled : Pos
10
,
1
Bit
+
0x2f0
SpareBits : Pos
11
,
21
Bits
+
0x2f4
DataFlagsPad : [
1
] Uint4B
+
0x2f8
TestRetInstruction : Uint8B
+
0x300
QpcFrequency : Int8B
+
0x308
SystemCall : Uint4B
/
/
占
4
位,根据汇编代码却检测的
1
位
+
0x30c
SystemCallPad0 : Uint4B
+
0x310
SystemCallPad : [
2
] Uint8B
+
0x320
TickCount : _KSYSTEM_TIME
+
0x320
TickCountQuad : Uint8B
+
0x320
ReservedTickCountOverlay : [
3
] Uint4B
+
0x32c
TickCountPad : [
1
] Uint4B
+
0x330
Cookie : Uint4B
+
0x334
CookiePad : [
1
] Uint4B
+
0x338
ConsoleSessionForegroundProcessId : Int8B
+
0x340
TimeUpdateLock : Uint8B
+
0x348
BaselineSystemTimeQpc : Uint8B
+
0x350
BaselineInterruptTimeQpc : Uint8B
+
0x358
QpcSystemTimeIncrement : Uint8B
+
0x360
QpcInterruptTimeIncrement : Uint8B
+
0x368
QpcSystemTimeIncrementShift : UChar
+
0x369
QpcInterruptTimeIncrementShift : UChar
+
0x36a
UnparkedProcessorCount : Uint2B
+
0x36c
EnclaveFeatureMask : [
4
] Uint4B
+
0x37c
TelemetryCoverageRound : Uint4B
+
0x380
UserModeGlobalLogger : [
16
] Uint2B
+
0x3a0
ImageFileExecutionOptions : Uint4B
+
0x3a4
LangGenerationCount : Uint4B
+
0x3a8
Reserved4 : Uint8B
+
0x3b0
InterruptTimeBias : Uint8B
+
0x3b8
QpcBias : Uint8B
+
0x3c0
ActiveProcessorCount : Uint4B
+
0x3c4
ActiveGroupCount : UChar
+
0x3c5
Reserved9 : UChar
+
0x3c6
QpcData : Uint2B
+
0x3c6
QpcBypassEnabled : UChar
+
0x3c7
QpcShift : UChar
+
0x3c8
TimeZoneBiasEffectiveStart : _LARGE_INTEGER
+
0x3d0
TimeZoneBiasEffectiveEnd : _LARGE_INTEGER
+
0x3d8
XState : _XSTATE_CONFIGURATION
1
: kd> dt nt!_KUSER_SHARED_DATA
*
*
*
Unable to resolve unqualified symbol
in
Bp expression
'l'
.
+
0x000
TickCountLowDeprecated : Uint4B
+
0x004
TickCountMultiplier : Uint4B
+
0x008
InterruptTime : _KSYSTEM_TIME
+
0x014
SystemTime : _KSYSTEM_TIME
+
0x020
TimeZoneBias : _KSYSTEM_TIME
+
0x02c
ImageNumberLow : Uint2B
+
0x02e
ImageNumberHigh : Uint2B
+
0x030
NtSystemRoot : [
260
] Wchar
+
0x238
MaxStackTraceDepth : Uint4B
+
0x23c
CryptoExponent : Uint4B
+
0x240
TimeZoneId : Uint4B
+
0x244
LargePageMinimum : Uint4B
+
0x248
AitSamplingValue : Uint4B
+
0x24c
AppCompatFlag : Uint4B
+
0x250
RNGSeedVersion : Uint8B
+
0x258
GlobalValidationRunlevel : Uint4B
+
0x25c
TimeZoneBiasStamp : Int4B
+
0x260
NtBuildNumber : Uint4B
+
0x264
NtProductType : _NT_PRODUCT_TYPE
+
0x268
ProductTypeIsValid : UChar
+
0x269
Reserved0 : [
1
] UChar
+
0x26a
NativeProcessorArchitecture : Uint2B
+
0x26c
NtMajorVersion : Uint4B
+
0x270
NtMinorVersion : Uint4B
+
0x274
ProcessorFeatures : [
64
] UChar
+
0x2b4
Reserved1 : Uint4B
+
0x2b8
Reserved3 : Uint4B
+
0x2bc
TimeSlip : Uint4B
+
0x2c0
AlternativeArchitecture : _ALTERNATIVE_ARCHITECTURE_TYPE
+
0x2c4
BootId : Uint4B
+
0x2c8
SystemExpirationDate : _LARGE_INTEGER
+
0x2d0
SuiteMask : Uint4B
+
0x2d4
KdDebuggerEnabled : UChar
+
0x2d5
MitigationPolicies : UChar
+
0x2d5
NXSupportPolicy : Pos
0
,
2
Bits
+
0x2d5
SEHValidationPolicy : Pos
2
,
2
Bits
+
0x2d5
CurDirDevicesSkippedForDlls : Pos
4
,
2
Bits
+
0x2d5
Reserved : Pos
6
,
2
Bits
+
0x2d6
CyclesPerYield : Uint2B
+
0x2d8
ActiveConsoleId : Uint4B
+
0x2dc
DismountCount : Uint4B
+
0x2e0
ComPlusPackage : Uint4B
+
0x2e4
LastSystemRITEventTickCount : Uint4B
+
0x2e8
NumberOfPhysicalPages : Uint4B
+
0x2ec
SafeBootMode : UChar
+
0x2ed
VirtualizationFlags : UChar
+
0x2ee
Reserved12 : [
2
] UChar
+
0x2f0
SharedDataFlags : Uint4B
+
0x2f0
DbgErrorPortPresent : Pos
0
,
1
Bit
+
0x2f0
DbgElevationEnabled : Pos
1
,
1
Bit
+
0x2f0
DbgVirtEnabled : Pos
2
,
1
Bit
+
0x2f0
DbgInstallerDetectEnabled : Pos
3
,
1
Bit
+
0x2f0
DbgLkgEnabled : Pos
4
,
1
Bit
+
0x2f0
DbgDynProcessorEnabled : Pos
5
,
1
Bit
+
0x2f0
DbgConsoleBrokerEnabled : Pos
6
,
1
Bit
+
0x2f0
DbgSecureBootEnabled : Pos
7
,
1
Bit
+
0x2f0
DbgMultiSessionSku : Pos
8
,
1
Bit
+
0x2f0
DbgMultiUsersInSessionSku : Pos
9
,
1
Bit
+
0x2f0
DbgStateSeparationEnabled : Pos
10
,
1
Bit
+
0x2f0
SpareBits : Pos
11
,
21
Bits
+
0x2f4
DataFlagsPad : [
1
] Uint4B
+
0x2f8
TestRetInstruction : Uint8B
+
0x300
QpcFrequency : Int8B
+
0x308
SystemCall : Uint4B
/
/
占
4
位,根据汇编代码却检测的
1
位
+
0x30c
SystemCallPad0 : Uint4B
+
0x310
SystemCallPad : [
2
] Uint8B
+
0x320
TickCount : _KSYSTEM_TIME
+
0x320
TickCountQuad : Uint8B
+
0x320
ReservedTickCountOverlay : [
3
] Uint4B
+
0x32c
TickCountPad : [
1
] Uint4B
+
0x330
Cookie : Uint4B
+
0x334
CookiePad : [
1
] Uint4B
+
0x338
ConsoleSessionForegroundProcessId : Int8B
+
0x340
TimeUpdateLock : Uint8B
+
0x348
BaselineSystemTimeQpc : Uint8B
+
0x350
BaselineInterruptTimeQpc : Uint8B
+
0x358
QpcSystemTimeIncrement : Uint8B
+
0x360
QpcInterruptTimeIncrement : Uint8B
+
0x368
QpcSystemTimeIncrementShift : UChar
+
0x369
QpcInterruptTimeIncrementShift : UChar
+
0x36a
UnparkedProcessorCount : Uint2B
+
0x36c
EnclaveFeatureMask : [
4
] Uint4B
+
0x37c
TelemetryCoverageRound : Uint4B
+
0x380
UserModeGlobalLogger : [
16
] Uint2B
+
0x3a0
ImageFileExecutionOptions : Uint4B
+
0x3a4
LangGenerationCount : Uint4B
+
0x3a8
Reserved4 : Uint8B
+
0x3b0
InterruptTimeBias : Uint8B
+
0x3b8
QpcBias : Uint8B
+
0x3c0
ActiveProcessorCount : Uint4B
+
0x3c4
ActiveGroupCount : UChar
+
0x3c5
Reserved9 : UChar
+
0x3c6
QpcData : Uint2B
+
0x3c6
QpcBypassEnabled : UChar
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2022-7-10 17:18
被kardpan编辑
,原因: