首页
论坛
课程
招聘
某某的apc主动防御逆向分析
2010-3-28 20:54 6843

某某的apc主动防御逆向分析

2010-3-28 20:54
6843
实现原理:
inlinehook内核文件ntosknl.exe的内部函数KeInitializeApc,对相关参数进行检测,若发现不符合规则的APC插入动作则进行拦截。

拦截实现方式:

将KAPC结构中的参数Thread修改成自身的某一KThread结构指针,达到"挂入A,实际却挂到B的效果",从而使该APC失去效用。
若关键函数sub_130A4返回为1,则修改KAPC结构中的Thread参数,进行拦截;若返回为0,则放行此次插入APC动作。(见红色代码部分)

InlineHook位置:
蓝色代码部分


检测规则:

1)进程自身内的APC全部予以放过
2)进程间的用户APC互插,仅允许system进程的孙子进程(即csrss.exe winlogin.exe)和某一特定用户进程
3)拦截非正规调用KeInitializeApc进行用户APC插入的动作
详见sub_130A4 函数分析,里面的函数一环套另一环,比较多,只帖出了主函数部分

nt!KeInitializeApc:                               ;
mov     edi,edi                                   ;
push    ebp                                       ;
mov     ebp,esp                                   ;
mov     eax,dword ptr [ebp+8]                     ;[ebp+8]: Apc
mov     edx,dword ptr [ebp+10h]                   ;[ebp+10h]: TargetEnvironment
cmp     edx,2                                     ;
mov     ecx,dword ptr [ebp+0Ch]                   ;[ebp+0Ch]: Thread
mov     word ptr [eax],12h                        ;Apc->Type = 0x12
mov     word ptr [eax+2],30h                      ;Apc->Size = 0x30
jne     nt!KeInitializeApc+0x24 (804fd3c2)        ;若TargetEnvironment != CurrentApcEnvironment则跳转
mov     dl,byte ptr [ecx+165h]                    ;[ecx+165h]:Thread->ApcStateIndex,表示当前线程的环境值
---------------------------------------------------
[COLOR="Blue"]nop                                               ;inline Hook部分:仅对Apc->Thread进行了处理
call    xyz12345+0x333c (ba27b33c)                ;处理函数[/COLOR]
---------------------------------------------------
mov     dword ptr [eax+14h],ecx			  ;
mov     ecx,dword ptr [ebp+18h]                   ;
mov     byte ptr [eax+2Ch],dl                     ;
mov     dword ptr [eax+18h],ecx                   ;
mov     ecx,dword ptr [ebp+1Ch]                   ;
xor     edx,edx                                   ;
cmp     ecx,edx                                   ;
mov     dword ptr [eax+1Ch],ecx                   ;
je      nt!KeInitializeApc+0x50 (804fbaa6)        ;
mov     cl,byte ptr [ebp+20h]                     ;
mov     byte ptr [eax+2Dh],cl                     ;
--------------------------------------------------;
在进入处理函数之前,堆栈空间内容:
|Context            |
|Mode               |
|NormalRoutine      |
|RundownRoutine     |
|KernelRoutine      |
|TargetEnvironment  |
|Thread             |
|Apc                |
|KeInitializeApc.Ret|
|KeInitializeApc.Ebp|


b2a7033c:                                        ;
mov     edi, edi                                  ;
pusha                                             ;
pushf                                             ;
lock inc dword_16AC0                              ;多核同步
mov     eax, dword_16B44                          ;dword_16B44:PsExitSpecialApc函数地址
test    eax, eax                                  ;
jnz     short loc_1338A                           ;
mov     ebx, [ebp+14h]                            ;[ebp+14h]:KernelRoutine
mov     ecx, [ebp+20h]                            ;[ebp+20h]:NormalRoutine
mov     edx, [ebp+10h]                            ;[ebp+10h]:TargetEnvironment
mov     esi, [ebp+0Ch]                            ;[ebp+0Ch]:Thread
mov     eax, Object                               ;Object: 进程的ETHREAD结构指针
cmp     eax, esi                                  ;
jnz     short loc_133B5                           ;若当前线程不是Object代表的线程则跳转
test    ecx, ecx                                  ;
jnz     short loc_133B5                           ;若NormalRoutine!= NULL 则跳转
test    edx, edx                                  ;
jnz     short loc_133B5                           ;若TargetEnvironment != OriginalApcEnvironment则跳转
mov     edi, dword_16A7C                          ;dword_16A7C: ntoskln.exe模块的Base
cmp     ebx, edi                                  ;
jb      short loc_133B5                           ;若KernelRoutine 低于dword_16A7C 则跳转
mov     eax, dword_16AA0                          ;dword_16AA0: ntoskln.exe模块的Size
add     edi, eax                                  ;
cmp     ebx, edi                                  ;
jg      short loc_133B5                           ;若KernelRoutine 高于dword_16A7C + dword_16AA0 则跳转
mov     dword_16B44, ebx                          ;
jmp     short loc_133B5                           ;
--------------------------------------------------;
                                                  ;
.text:0001338A loc_1338A:                         ;
mov     eax, [ebp+0Ch]                            ;[ebp+0Ch]:Thread
push    eax                                       ;
mov     eax, [ebp+14h]                            ;[ebp+14h]:KernelRoutine
push    eax                                       ;
mov     eax, [ebp+4]                              ;[ebp+4]: KeInitializeApc.Ret
push    eax                                       ;
[COLOR="Green"]call    sub_130A4                                 ;关键函数
[/COLOR]test    al, al                                    ;
jz      short loc_133B5                           ;
popf                                              ;
popa                                              ;
[COLOR="red"]mov     ecx, Object                               ;
mov     [eax+8], ecx                              ;Apc->Thread = Object
mov     ecx, [ebp+14h]                            ;[/COLOR]
lock dec dword_16AC0                              ;
retn                                              ;
-----------------------------                     ;
.text:000133B5 loc_133B5:                         ;
popf                                              ;
popa                                              ;
[COLOR="red"]mov     [eax+8], ecx                              ;
mov     ecx, [ebp+14h]                            ;[/COLOR]
lock dec dword_16AC0                              ;
retn                                              ;


char __stdcall sub_130A4(unsigned int a1, int a2, void *a3)
//(KeInitializeApc.Ret, KernelRoutine, Thread)
{
  ...
  v4 = PsGetCurrentProcessId();//获得当前进程的进程ID
  v21 = sub_126D2(v5);//由Ethread指针返回此线程所属进程的进程ID(非挂靠进程)
  if ( Object && !(unsigned __int8)sub_12CEC(v4) && v4 != (HANDLE)v21 && v21 != -1 )
  //当前进程不是插入APC目标线程的所属进程,目标线程所属进程不是NtCurrentProcess(),当前进程不在自身的私有结构链表中
  {
    if ( !(unsigned __int8)sub_12CEC((PVOID)v21) )
	//若目标线程所属进程id不在私有结构链表中,则返回
      return v3;
    v3 = 1;
	//捕获1)非正规调用KeInitializeApc 2)用户空间APC(用户空间APC的KernelRoutine为PsExitSpecialApc)
    if ( a1 <= dword_16A7C || a1 >= dword_16AA0 + dword_16A7C || a2 == dword_16B44 )
	//a1 <= ntosknl.exe.Base || a1 >= ntosknl.exe.Base + ntosknl.exe.Size || a2 == PsExitSpecialApc
    {
      if ( a2 <= (unsigned int)dword_16A7C || a2 >= (unsigned int)(dword_16A7C + dword_16AA0) )
      {//若a2不在ntosknl.exe模块势力范围,则打印可疑信息
        if ( a2 != dword_16B44 )
          goto LABEL_37;
      }
      else
      {//若a2在ntosknl.exe模块势力范围,但不等于PsExitSpecialApc则跳过此次处理
        if ( a2 != dword_16B44 )
          return 0;
      }
      v12 = KeGetCurrentThread();
      if ( !(unsigned __int8)sub_12F12(v12) )
      {//排除某一用户程序的插APC行为
        if ( (_WORD)NtBuildNumber <= 3790 ) //windows xp 64-bit Edition Version 2003
        {
          v14 = IoGetCurrentProcess();
          v6 = sub_12660(v14);//返回当前进程的父进程的Eprocess结构
          VirtualAddress = (PVOID)v6;
          if ( v6 )
          {
            v7 = sub_12660((PVOID)v6);//返回当前进程的爷进程的Eprocess结构
            VirtualAddress = (PVOID)v7;
            if ( v7 )
            {
              v8 = sub_11944(v7);//获得爷进程ID
              if ( (_WORD)NtBuildNumber != 2195 ) //若系统版本不是 windows 2000
                v9 = v8 == 4;//确认爷进程是否为4,即是否为 system进程
              else
                v9 = v8 == 8;
              if ( v9 )
                return 0;
			          //若某个进程的爷进程为system进程,则允许Apc插入
            }
          }
        }
        else
        {
        ......

          v10 = sub_1268A(v5);//返回Thread所属进程的Eprocess结构指针

          VirtualAddress = (PVOID)v10;
          if ( v10 )
          {
            *(_DWORD *)(dword_1684C + v10) &= 0xFFFFFFF7;//dword_1684C = 0x248
						//清除Eprocess.Flags的ProcessDelete位
            *(_DWORD *)((char *)v5 + dword_16AE8) &= 0xFFFFFFFE;//dword_16AE8 = 0x248 
						//清除Ethread.CrossThreadFlags的Terminated位

          }
        }
        v3 = 1;
LABEL_37:
         ...
        return v3;
      }
    }
    return 0;
  }
  return 0;
}


不对之处,望海涵!并请帮忙指出

[公告]请完善个人简历信息,好工作来找你!

收藏
点赞0
打赏
分享
最新回复 (3)
雪    币: 36
活跃值: 活跃值 (29)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
skypismire 活跃值 1 2010-3-29 14:51
2
0
上面的仅仅只是冰山一角阿
ntkrnlpa.exe:CcFastMdlReadWait:805510c0 has been inline-hooked!
ntkrnlpa.exe:CcFastReadNotPossible:805510c8 has been inline-hooked!
ntkrnlpa.exe:CcFastReadWait:805510d0 has been inline-hooked!
ntkrnlpa.exe:ExDesktopObjectType:8055c53c has been inline-hooked!
。。。。
ntkrnlpa.exe:HalPrivateDispatchTable:80546910 has been inline-hooked!
ntkrnlpa.exe:InitSafeBootMode:80552380 has been inline-hooked!
ntkrnlpa.exe:IoAdapterObjectType:80552870 has been inline-hooked!
ntkrnlpa.exe:IoDeviceHandlerObjectSize:80552854 has been inline-hooked!
ntkrnlpa.exe:IoDeviceHandlerObjectType:8055285c has been inline-hooked!
ntkrnlpa.exe:IoDeviceObjectType:80552864 has been inline-hooked!
ntkrnlpa.exe:IoDriverObjectType:80552860 has been inline-hooked!
ntkrnlpa.exe:IoFileObjectType:80552858 has been inline-hooked!
ntkrnlpa.exe:IoReadOperationCount:80552850 has been inline-hooked!
ntkrnlpa.exe:IoReadTransferCount:80552840 has been inline-hooked!
ntkrnlpa.exe:IoReportHalResourceUsage:8068a1c8 has been inline-hooked!
ntkrnlpa.exe:IoWriteOperationCount:8055284c has been inline-hooked!
ntkrnlpa.exe:IoWriteTransferCount:80552838 has been inline-hooked!
ntkrnlpa.exe:KdDebuggerEnabled:8054d541 has been inline-hooked!
ntkrnlpa.exe:KdDebuggerNotPresent:8054d540 has been inline-hooked!
ntkrnlpa.exe:KdEnteredDebugger:8054d544 has been inline-hooked!
ntkrnlpa.exe:KeDcacheFlushCount:8054d554 has been inline-hooked!
。。。。。
ntkrnlpa.exe:KeSetProfileIrql:80690b64 has been inline-hooked!
ntkrnlpa.exe:KeTickCount:8054be20 has been inline-hooked!
ntkrnlpa.exe:KiEnableTimerWatchdog:8054d578 has been inline-hooked!
ntkrnlpa.exe:LpcPortObjectType:80554a08 has been inline-hooked!
ntkrnlpa.exe:Mm64BitPhysicalAddress:805594c4 has been inline-hooked!
ntkrnlpa.exe:MmHighestUserAddress:80559a5c has been inline-hooked!
ntkrnlpa.exe:MmSectionObjectType:805597c0 has been inline-hooked!
ntkrnlpa.exe:MmSystemRangeStart:80559a58 has been inline-hooked!
ntkrnlpa.exe:MmUserProbeAddress:80559a54 has been inline-hooked!
ntkrnlpa.exe:NlsAnsiCodePage:80670df8 has been inline-hooked!
ntkrnlpa.exe:NlsMbCodePageTag:80670e10 has been inline-hooked!
ntkrnlpa.exe:NlsMbOemCodePageTag:80671028 has been inline-hooked!
ntkrnlpa.exe:NlsOemCodePage:80670dfc has been inline-hooked!
ntkrnlpa.exe:NtGlobalFlag:805522ec has been inline-hooked!
ntkrnlpa.exe:PsInitialSystemProcess:8055b2d4 has been inline-hooked!
ntkrnlpa.exe:PsJobType:8055b260 has been inline-hooked!
ntkrnlpa.exe:PsProcessType:8055b2d8 has been inline-hooked!
ntkrnlpa.exe:PsThreadType:8055b2dc has been inline-hooked!
ntkrnlpa.exe:RtlPrefetchMemoryNonTemporal:80543364 has been inline-hooked!
ntkrnlpa.exe:SeExports:80671674 has been inline-hooked!
ntkrnlpa.exe:SePublicDefaultDacl:8067156c has been inline-hooked!
ntkrnlpa.exe:SeSystemDefaultDacl:8067157c has been inline-hooked!
ntkrnlpa.exe:SeTokenObjectType:80671804 has been inline-hooked!
hal.dll:HalAllProcessorsStarted:806ee560 has been inline-hooked!
hal.dll:HalInitSystem:806ee0b8 has been inline-hooked!
hal.dll:HalReportResourceUsage:806ee5d6 has been inline-hooked!
hal.dll:KdComPortInUse:806de780 has been inline-hooked!
USBD.SYS:USBD_RegisterHcDeviceCapabilities:f8bb23f0 has been
雪    币: 459
活跃值: 活跃值 (21)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
qihoocom 活跃值 9 2010-3-29 17:33
3
0
是你的INLINE扫描程序有问题。。全部都是全局变量。。。。囧
雪    币: 36
活跃值: 活跃值 (29)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
skypismire 活跃值 1 2010-3-29 19:40