僵尸进程的一点玩法

前言

这几天在看WRK的时候,偶然间发现的一个东西,逆向之后,发现了个僵尸进程的玩法。目前菜鸡一枚,有说的不准确的地方,请大家多多指正!

被忽略的RundownProtection

看过WRK的同学们应该对这个属性不陌生,每当要对某个进程进行操作的时候,总会有一个属性检查,贴上部分代码


    ProcessToLock = FromProcess;
    if (FromProcess == PsGetCurrentProcess()) {
        ProcessToLock = ToProcess;
    }

    //
    // Make sure the process still has an address space.
    //

    if (ExAcquireRundownProtection (&ProcessToLock->RundownProtect) == FALSE) {
        return STATUS_PROCESS_IS_TERMINATING;
    }

这是RundownProtect的结构体,可以看到在正常情况下是为0的

  [Type: _EX_RUNDOWN_REF]
    [+0x000] Count            : 0x0 [Type: unsigned __int64]
    [+0x000] Ptr              : 0x0 [Type: void *]

看到WRK的注释之后,便欲探索一下ExAcquireRundownProtection

ExAcquireRundownProtection

.text:00000001400FA630 48 8B 01                                      mov     rax, [rcx]
.text:00000001400FA633 A8 01                                         test    al, 1           ; 判断RunRef.count的位0是否为1,等于则跳转
.text:00000001400FA635 75 13                                         jnz     short loc_1400FA64A ; 返回FALSE
.text:00000001400FA635
.text:00000001400FA637 44 8D 04 12                                   lea     r8d, [rdx+rdx]  ; 参数
.text:00000001400FA637
.text:00000001400FA63B
.text:00000001400FA63B                               loc_1400FA63B:                          ; CODE XREF: ExAcquireRundownProtectionEx+18↓j
.text:00000001400FA63B 49 8D 14 00                                   lea     rdx, [r8+rax]   ; 参数
.text:00000001400FA63F F0 48 0F B1 11                                lock cmpxchg [rcx], rdx ; Compare and Exchange
.text:00000001400FA644 74 07                                         jz      short loc_1400FA64D ; 返回TRUE
.text:00000001400FA644
.text:00000001400FA646 A8 01                                         test    al, 1           ; Logical Compare
.text:00000001400FA648 74 F1                                         jz      short loc_1400FA63B ; 循环
.text:00000001400FA648
.text:00000001400FA64A
.text:00000001400FA64A                               loc_1400FA64A:                          ; CODE XREF: ExAcquireRundownProtectionEx+5↑j
.text:00000001400FA64A 32 C0                                         xor     al, al          ; 返回FALSE
.text:00000001400FA64C C3                                            retn                    ; Return Near from Procedure
.text:00000001400FA64C
.text:00000001400FA64D                               ; ---------------------------------------------------------------------------
.text:00000001400FA64D
.text:00000001400FA64D                               loc_1400FA64D:                          ; CODE XREF: ExAcquireRundownProtectionEx+14↑j
.text:00000001400FA64D B0 01                                         mov     al, 1           ; 返回TRUE
.text:00000001400FA64F C3                                            retn                    ; Return Near from Procedure

经过一番逆向后,发现当RundownProtection的第一个成员的第零位(二进制)为0时,则函数返回TRUE,否则返回FALSE。

应用

如果我们修改RundownProtect为1,那么是否可以实现任何API访问此进程都失败呢,接下来做一下实验。

kd> dt _EPROCESS fffffa8002402710
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x160 ProcessLock      : _EX_PUSH_LOCK
   +0x168 CreateTime       : _LARGE_INTEGER 0x01d7a08a`1c139093
   +0x170 ExitTime         : _LARGE_INTEGER 0x0
   +0x178 RundownProtect   : _EX_RUNDOWN_REF
   +0x180 UniqueProcessId  : 0x00000000`0000057c Void
   +0x188 ActiveProcessLinks : _LIST_ENTRY [ 0xfffffa80`02b6e5b8 - 0xfffffa80`027b1528 ]
   +0x198 ProcessQuotaUsage : [2] 0x2680
   +0x1a8 ProcessQuotaPeak : [2] 0x2c20
   +0x1b8 CommitCharge     : 0x1f8
   +0x1c0 QuotaBlock       : 0xfffffa80`010724c0 _EPROCESS_QUOTA_BLOCK
   +0x1c8 CpuQuotaBlock    : (null) 
   +0x1d0 PeakVirtualSize  : 0x6002000
   +0x1d8 VirtualSize      : 0x50e7000
   +0x1e0 SessionProcessLinks : _LIST_ENTRY [ 0xfffffa80`02af5b40 - 0xfffffa80`027b1580 ]
   +0x1f0 DebugPort        : (null) 
   +0x1f8 ExceptionPortData : 0xfffffa80`01fd5c90 Void
   +0x1f8 ExceptionPortValue : 0xfffffa80`01fd5c90
   +0x1f8 ExceptionPortState : 0y000
   +0x200 ObjectTable      : 0xfffff8a0`021b6d70 _HANDLE_TABLE
   +0x208 Token            : _EX_FAST_REF
   +0x210 WorkingSetPage   : 0x22102
   +0x218 AddressCreationLock : _EX_PUSH_LOCK
   +0x220 RotateInProgress : (null) 
   +0x228 ForkInProgress   : (null) 
   +0x230 HardwareTrigger  : 0
   +0x238 PhysicalVadRoot  : 0xfffffa80`00d95bc0 _MM_AVL_TABLE
   +0x240 CloneRoot        : (null) 
   +0x248 NumberOfPrivatePages : 0x18c
   +0x250 NumberOfLockedPages : 0
   +0x258 Win32Process     : 0xfffff900`c2ffd010 Void
   +0x260 Job              : 0xfffffa80`00d27220 _EJOB
   +0x268 SectionObject    : 0xfffff8a0`02aeb6e0 Void
   +0x270 SectionBaseAddress : 0x00000000`00400000 Void
   +0x278 Cookie           : 0xf2b3718a
   +0x27c UmsScheduledThreads : 0
   +0x280 WorkingSetWatch  : (null) 
   +0x288 Win32WindowStation : 0x00000000`0000005c Void
   +0x290 InheritedFromUniqueProcessId : 0x00000000`00000524 Void
   +0x298 LdtInformation   : (null) 
   +0x2a0 Spare            : (null) 
   +0x2a8 ConsoleHostProcess : 0
   +0x2b0 DeviceMap        : 0xfffff8a0`015bff10 Void
   +0x2b8 EtwDataSource    : (null) 
   +0x2c0 FreeTebHint      : 0x00000000`7efa0000 Void
   +0x2c8 FreeUmsTebHint   : 0x00000001`00000000 Void
   +0x2d0 PageDirectoryPte : _HARDWARE_PTE
   +0x2d0 Filler           : 0
   +0x2d8 Session          : 0xfffff880`009c9000 Void
   +0x2e0 ImageFileName    : [15]  "Dbgview.exe"
   +0x2ef PriorityClass    : 0x2 ''
   +0x2f0 JobLinks         : _LIST_ENTRY [ 0xfffffa80`00d27248 - 0xfffffa80`00d27248 ]
   +0x300 LockedPagesList  : (null) 
   +0x308 ThreadListHead   : _LIST_ENTRY [ 0xfffffa80`024b6f80 - 0xfffffa80`02515860 ]
   +0x318 SecurityPort     : (null) 
   +0x320 Wow64Process     : 0x00000000`7efde000 Void
   +0x328 ActiveThreads    : 3
   +0x32c ImagePathHash    : 0xdecf2e47
   +0x330 DefaultHardErrorProcessing : 1
   +0x334 LastThreadExitStatus : 0n0
   +0x338 Peb              : 0x00000000`7efdf000 _PEB
   +0x340 PrefetchTrace    : _EX_FAST_REF
   +0x348 ReadOperationCount : _LARGE_INTEGER 0x0
   +0x350 WriteOperationCount : _LARGE_INTEGER 0x0
   +0x358 OtherOperationCount : _LARGE_INTEGER 0x0
   +0x360 ReadTransferCount : _LARGE_INTEGER 0x0
   +0x368 WriteTransferCount : _LARGE_INTEGER 0x0
   +0x370 OtherTransferCount : _LARGE_INTEGER 0x0
   +0x378 CommitChargeLimit : 0
   +0x380 CommitChargePeak : 0x226
   +0x388 AweInfo          : (null) 
   +0x390 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
   +0x398 Vm               : _MMSUPPORT
   +0x420 MmProcessLinks   : _LIST_ENTRY [ 0xfffffa80`02b6e850 - 0xfffffa80`027b17c0 ]
   +0x430 HighestUserAddress : 0x00000000`7fff0000 Void
   +0x438 ModifiedPageCount : 7
   +0x43c Flags2           : 0x2d014
   +0x43c JobNotReallyActive : 0y0
   +0x43c AccountingFolded : 0y0
   +0x43c NewProcessReported : 0y1
   +0x43c ExitProcessReported : 0y0
   +0x43c ReportCommitChanges : 0y1
   +0x43c LastReportMemory : 0y0
   +0x43c ReportPhysicalPageChanges : 0y0
   +0x43c HandleTableRundown : 0y0
   +0x43c NeedsHandleRundown : 0y0
   +0x43c RefTraceEnabled  : 0y0
   +0x43c NumaAware        : 0y0
   +0x43c ProtectedProcess : 0y0
   +0x43c DefaultPagePriority : 0y101
   +0x43c PrimaryTokenFrozen : 0y1
   +0x43c ProcessVerifierTarget : 0y0
   +0x43c StackRandomizationDisabled : 0y1
   +0x43c AffinityPermanent : 0y0
   +0x43c AffinityUpdateEnable : 0y0
   +0x43c PropagateNode    : 0y0
   +0x43c ExplicitAffinity : 0y0
   +0x440 Flags            : 0x144d0801
   +0x440 CreateReported   : 0y1
   +0x440 NoDebugInherit   : 0y0
   +0x440 ProcessExiting   : 0y0
   +0x440 ProcessDelete    : 0y0
   +0x440 Wow64SplitPages  : 0y0
   +0x440 VmDeleted        : 0y0
   +0x440 OutswapEnabled   : 0y0
   +0x440 Outswapped       : 0y0
   +0x440 ForkFailed       : 0y0
   +0x440 Wow64VaSpace4Gb  : 0y0
   +0x440 AddressSpaceInitialized : 0y10
   +0x440 SetTimerResolution : 0y0
   +0x440 BreakOnTermination : 0y0
   +0x440 DeprioritizeViews : 0y0
   +0x440 WriteWatch       : 0y0
   +0x440 ProcessInSession : 0y1
   +0x440 OverrideAddressSpace : 0y0
   +0x440 HasAddressSpace  : 0y1
   +0x440 LaunchPrefetched : 0y1
   +0x440 InjectInpageErrors : 0y0
   +0x440 VmTopDown        : 0y0
   +0x440 ImageNotifyDone  : 0y1
   +0x440 PdeUpdateNeeded  : 0y0
   +0x440 VdmAllowed       : 0y0
   +0x440 CrossSessionCreate : 0y0
   +0x440 ProcessInserted  : 0y1
   +0x440 DefaultIoPriority : 0y010
   +0x440 ProcessSelfDelete : 0y0
   +0x440 SetTimerResolutionLink : 0y0
   +0x444 ExitStatus       : 0n259
   +0x448 VadRoot          : _MM_AVL_TABLE
   +0x488 AlpcContext      : _ALPC_PROCESS_CONTEXT
   +0x4a8 TimerResolutionLink : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ]
   +0x4b8 RequestedTimerResolution : 0
   +0x4bc ActiveThreadsHighWatermark : 6
   +0x4c0 SmallestTimerResolution : 0
   +0x4c8 TimerResolutionStackRecord : (null) 

我们看到0x178偏移处,找到了RundownProtect这个属性,接着修改为1(第0位为0的数皆可)。

kd> ed fffffa8002402710+178 1

接着我们进入虚拟机查看效果
在这里插入图片描述
程序正常运行,不会PG。
(测试环境Win7 X64 7600)

总结

这个函数还有很多用处,例如多线程同步等等,还有就是…做完才发现,已经有大佬发过这个思路了~
更早的一篇

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值