本论坛为只读模式,仅供查阅,不能注册新用户,不能发帖/回帖,有问题可发邮件 xikug.xp (^) gmail.com
查看: 6682|回复: 10

传说中的XXX白名单? [复制链接]

Rank: 1

发表于 2011-6-18 03:14:45 |显示全部楼层
跟踪TX的NtOpenThread 看到他操作了3个链表,自己想想应该就是传说中的白名单吧。
/////////////////////这里是NtOpenThread中的TX的代理函数
/*
b0bec6a8 8bff            mov     edi,edi
b0bec6aa 55              push    ebp
b0bec6ab 8bec            mov     ebp,esp
b0bec6ad 81ec00010000    sub     esp,100h
b0bec6b3 60              pushad
b0bec6b4 9c              pushfd
b0bec6b5 b8205fbfb0      mov     eax,offset TesSafe+0xcf20 (b0bf5f20)
b0bec6ba 33c9            xor     ecx,ecx
b0bec6bc 41              inc     ecx
b0bec6bd f00fc108        lock xadd dword ptr [eax],ecx
b0bec6c1 ff7508          push    dword ptr [ebp+8]
b0bec6c4 ff15a030bfb0    call    dword ptr [TesSafe+0xa0a0 (b0bf30a0)] //调用PsGetThreadProcess取得PEPROCESS
b0bec6ca 8945fc          mov     dword ptr [ebp-4],eax//
b0bec6cd ff154c30bfb0    call    dword ptr [TesSafe+0xa04c (b0bf304c)] //PsGetCurrentProcess()取得现在进程的PEPROCESS
b0bec6d3 8945f8          mov     dword ptr [ebp-8],eax
b0bec6d6 6a02            push    2
b0bec6d8 ff75f8          push    dword ptr [ebp-8]
b0bec6db e892f9ffff      call    TesSafe+0x3072 (b0bec072)          //判断是不是保护进程创建线程,返回1放行
b0bec6e0 0fb6c0          movzx   eax,al
b0bec6e3 85c0            test    eax,eax
b0bec6e5 7402            je      TesSafe+0x36e9 (b0bec6e9)
b0bec6e7 eb49            jmp     TesSafe+0x3732 (b0bec732)
b0bec6e9 8b45fc          mov     eax,dword ptr [ebp-4]
b0bec6ec 3b45f8          cmp     eax,dword ptr [ebp-8]
b0bec6ef 7502            jne     TesSafe+0x36f3 (b0bec6f3)
b0bec6f1 eb3f            jmp     TesSafe+0x3732 (b0bec732)
b0bec6f3 6a02            push    2
b0bec6f5 ff75fc          push    dword ptr [ebp-4]
b0bec6f8 e835faffff      call    TesSafe+0x3132 (b0bec132) //这个函数返回0就调用原函数
b0bec6fd 0fb6c0          movzx   eax,al
b0bec700 85c0            test    eax,eax
b0bec702 7502            jne     TesSafe+0x3706 (b0bec706)
b0bec704 eb2c            jmp     TesSafe+0x3732 (b0bec732)
b0bec706 6a02            push    2
b0bec708 ff75f8          push    dword ptr [ebp-8]
b0bec70b e8a0f9ffff      call    TesSafe+0x30b0 (b0bec0b0) //这里返回1,就放行了。
b0bec710 0fb6c0          movzx   eax,al
b0bec713 85c0            test    eax,eax
b0bec715 7402            je      TesSafe+0x3719 (b0bec719)  //这里EAX为零就过滤掉了。
b0bec717 eb19            jmp     TesSafe+0x3732 (b0bec732) //调用原函数
b0bec719 b8205fbfb0      mov     eax,offset TesSafe+0xcf20 (b0bf5f20)
b0bec71e 83c9ff          or      ecx,0FFFFFFFFh
b0bec721 f00fc108        lock xadd dword ptr [eax],ecx //变量减1
b0bec725 9d              popfd
b0bec726 61              popad
b0bec727 8be5            mov     esp,ebp
b0bec729 5d              pop     ebp
b0bec72a b80f0000c0      mov     eax,0C000000Fh
b0bec72f c21c00          ret     1Ch
b0bec732 b8205fbfb0      mov     eax,offset TesSafe+0xcf20 (b0bf5f20)//这里存放的变量,确保HOOK不被取消
b0bec737 83c9ff          or      ecx,0FFFFFFFFh
b0bec73a f00fc108        lock xadd dword ptr [eax],ecx //这里减1
b0bec73e 9d              popfd
b0bec73f 61              popad
b0bec740 8be5            mov     esp,ebp
b0bec742 5d              pop     ebp
b0bec743 ff25fc5dbfb0    jmp     dword ptr [TesSafe+0xcdfc (b0bf5dfc)] //这里调用ObOpenObjectByPointer*/

还原成C代码这个函数是这样的


struct tpthreadst{
DWORD    dw34;  //又是一个PEPROCESS
DWORD    dw30;
DWORD    dw2c;
DWORD    dw28;
PEPROCESS epro; //-24偏移
DWORD     dw20;
DWORD     dw1c;
DWORD     dw18;
dword     dw14;
dword     dw10;
dword     dwc;
dword     dw08;
dword     dw04;
struct tpthreadst * pNext;
}



Safe_NtOpenThread_HOOK(  IN PVOID  Object,
  IN ULONG  HandleAttributes,
  IN PACCESS_STATE  PassedAccessState  OPTIONAL,
  IN ACCESS_MASK  DesiredAccess  OPTIONAL,
  IN POBJECT_TYPE  ObjectType  OPTIONAL,
  IN KPROCESSOR_MODE  AccessMode,
  OUT PHANDLE  Handle)
{
         __asm   pushad
         __asm   pushfd
        static DWORD g_OpenThreadCon = 0;
        static DWORD g_ObOpenObjectByPointer = 0;
        static struct tpthreadst *pst61a8;
        PEPROCESS thread_eprocess,self_eprocess;
       
        thread_eprocess = PsGetThreadProcess(Object);
        self_eprocess = PsGetCurrentProcess();
        if(Funcc072(self_eprocess,2) != 0) goto EnableCall; //如果在链表1中就放行
        if(thread_eprocess == self_eprocess) //如果是进程自己创建线程放行
                goto EnableCall;
        if(funcc132(thread_eprocess,2) == 0) goto EnableCall; //如果线程不在链表2中的放行
        if(funcc0b0(self_eprocess,2)!= 0) goto EnableCall;     //如果调用的进程不在链表3中放行
  UnableCall:
        __asm popfd
        __asm popad
        return 0xC000000F;
EnableCall:
        __asm popfd
        __asm popad
        jmp [g_ObOpenObjectByPointer]
}



bool Funcc072(PEPROCESS epro, int ntype)
{
        //这个函数返回1 ,就直接调用NtOpenThread 中被HOOK的原函数
        //功能应该是遍历保护程序的链表比较调用NTOPENTHREAD的进程是不是保护进程,不是返回0
        tpthreadst *ptemst = pst61a8->pNext;
        while(ptemst != pst61a8){
                if(ptemst->pNext == epro){
                        ptemst->dw04 +=1;

                        if(ptemst->dw1c == 0)
                                return  0;
                        return 1;
                }
                ptemst = ptemst->pNext;
        }
        return 0;
}

bool funcc132(PEPROCESS epro,int ntype)
{
        bool bdpc = false;
        bool bret = false;
        static tpthreadst *ptemst = (tpthreadst *)0xb0bf61c0;

        KIRQL PreIrql;
        if(KeGetCurrentIrql() < 2)
                PreIrql = KfAcquireSpinLock(0Xb0bf61bc);
        else{
                KefAcquireSpinLockAtDpcLevel(0Xb0bf61bc);
                bret = true;
        }
        while(ptemst->pNext != 0xb0bf61c0){
                if(ptemst->dw34 == epro){
                        if(ptemst->dw20 != 0)
                        bret = true;
                        break;
                }
        }
        if(bret)  KefReleaseSpinLockFromDpcLevel(0Xb0bf61bc);
        else      
                KfReleaseSpinLock(0Xb0bf61bc,PreIrql);
        return bret;
}


bool funcc0b0(PEPROCESS epro,int ntype)
{
        bool bdpc = false;
        bool bret = false;
        static tpthreadst *ptemst = (tpthreadst *)0xb0bf61b0;

        KIRQL PreIrql;
        if(KeGetCurrentIrql() < 2)
                PreIrql = KfAcquireSpinLock(0xb0bf61b8);
        else{
                KefAcquireSpinLockAtDpcLevel(0Xb0bf61b8);
                bret = true;
        }
        while(ptemst->pNext != 0xb0bf61c0){
                if(ptemst->pNext == epro){
                        ptemst->dw04 +=1;

                        if(ptemst->dw1c != 0)
                                bret = 1;
                        break;
                }
                ptemst = ptemst->pNext;
        }
        if(bret)  KefReleaseSpinLockFromDpcLevel(0Xb0bf61b8);
        else      
                KfReleaseSpinLock(0Xb0bf61b8,PreIrql);
        return bret;




这里再贴几个子函数的汇编代码:
//////////这里跟进看看Funcc072 函数的原型/////////////////////////////////
/*
        b0bec072 8bff            mov     edi,edi
        b0bec074 55              push    ebp
        b0bec075 8bec            mov     ebp,esp
        b0bec077 8b0da861bfb0    mov     ecx,dword ptr [TesSafe+0xd1a8 (b0bf61a8)] //链表1
        b0bec07d baa861bfb0      mov     edx,offset TesSafe+0xd1a8 (b0bf61a8)
        b0bec082 32c0            xor     al,al
        b0bec084 3bca            cmp     ecx,edx
        b0bec086 741f            je      TesSafe+0x30a7 (b0bec0a7)
        b0bec088 56              push    esi
        b0bec089 8b7508          mov     esi,dword ptr [ebp+8]
        b0bec08c 3b71dc          cmp     esi,dword ptr [ecx-24h]
        b0bec08f 7408            je      TesSafe+0x3099 (b0bec099)
        b0bec091 8b09            mov     ecx,dword ptr [ecx]
        b0bec093 3bca            cmp     ecx,edx
        b0bec095 75f2            jne     TesSafe+0x3089 (b0bec089)
        b0bec097 eb0d            jmp     TesSafe+0x30a6 (b0bec0a6)
        b0bec099 8b550c          mov     edx,dword ptr [ebp+0Ch]
        b0bec09c ff41fc          inc     dword ptr [ecx-4]
        b0bec09f 8551e4          test    dword ptr [ecx-1Ch],edx
        b0bec0a2 7402            je      TesSafe+0x30a6 (b0bec0a6)
        b0bec0a4 b001            mov     al,1
        b0bec0a6 5e              pop     esi
        b0bec0a7 5d              pop     ebp
        b0bec0a8 c20800          ret     8*/


/////////////////这里是funcc132函数////////////////////////////
/*
b0bec132 8bff            mov     edi,edi
        b0bec134 55              push    ebp
        b0bec135 8bec            mov     ebp,esp
        b0bec137 51              push    ecx
        b0bec138 53              push    ebx
        b0bec139 56              push    esi
        b0bec13a c645ff00        mov     byte ptr [ebp-1],0
        b0bec13e 32db            xor     bl,bl
        b0bec140 ff150830bfb0    call    dword ptr [TesSafe+0xa008 (b0bf3008)] //KeGetCurrentIrql
        b0bec146 3c02            cmp     al,2
        b0bec148 bebc61bfb0      mov     esi,offset TesSafe+0xd1bc (b0bf61bc)
        b0bec14d 8bce            mov     ecx,esi
        b0bec14f 720a            jb      TesSafe+0x315b (b0bec15b)
        b0bec151 ff157830bfb0    call    dword ptr [TesSafe+0xa078 (b0bf3078)] //KefAcquireSpinLockAtDpcLevel
        b0bec157 fec3            inc     bl
        b0bec159 eb09            jmp     TesSafe+0x3164 (b0bec164)
        b0bec15b ff150c30bfb0    call    dword ptr [TesSafe+0xa00c (b0bf300c)] //KfAcquireSpinLock
        b0bec161 8845fe          mov     byte ptr [ebp-2],al
        b0bec164 a1c061bfb0      mov     eax,dword ptr [TesSafe+0xd1c0 (b0bf61c0)]  //链表2
        b0bec169 b9c061bfb0      mov     ecx,offset TesSafe+0xd1c0 (b0bf61c0)
        b0bec16e eb0a            jmp     TesSafe+0x317a (b0bec17a)
        b0bec170 8b50cc          mov     edx,dword ptr [eax-34h] ////这里是系统的结构呢,还是TX自己定义的????
        b0bec173 3b5508          cmp     edx,dword ptr [ebp+8] //参数1(PEPROCEE)
        b0bec176 7408            je      TesSafe+0x3180 (b0bec180)
        b0bec178 8b00            mov     eax,dword ptr [eax]
        b0bec17a 3bc1            cmp     eax,ecx
        b0bec17c 75f2            jne     TesSafe+0x3170 (b0bec170)
        b0bec17e eb0c            jmp     TesSafe+0x318c (b0bec18c)
        b0bec180 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
        b0bec183 8548e0          test    dword ptr [eax-20h],ecx
        b0bec186 7404            je      TesSafe+0x318c (b0bec18c)
        b0bec188 c645ff01        mov     byte ptr [ebp-1],1
        b0bec18c 84db            test    bl,bl
        b0bec18e 8bce            mov     ecx,esi
        b0bec190 7408            je      TesSafe+0x319a (b0bec19a)
        b0bec192 ff157430bfb0    call    dword ptr [TesSafe+0xa074 (b0bf3074)]//KefReleaseSpinLockFromDpcLevel
        b0bec198 eb09            jmp     TesSafe+0x31a3 (b0bec1a3)
        b0bec19a 8a55fe          mov     dl,byte ptr [ebp-2]
        b0bec19d ff151030bfb0    call    dword ptr [TesSafe+0xa010 (b0bf3010)] //KfReleaseSpinLock
        b0bec1a3 8a45ff          mov     al,byte ptr [ebp-1]
        b0bec1a6 5e              pop     esi
        b0bec1a7 5b              pop     ebx
        b0bec1a8 c9              leave
        b0bec1a9 c20800          ret     8*/


//////////////////funcc0b0函数////////////////////////////
/*
        b0bec0b0 8bff            mov     edi,edi
        b0bec0b2 55              push    ebp
        b0bec0b3 8bec            mov     ebp,esp
        b0bec0b5 51              push    ecx
        b0bec0b6 53              push    ebx
        b0bec0b7 56              push    esi
        b0bec0b8 c645ff00        mov     byte ptr [ebp-1],0
        b0bec0bc 32db            xor     bl,bl
        b0bec0be ff150830bfb0    call    dword ptr [TesSafe+0xa008 (b0bf3008)] //KeGetCurrentIrql
        b0bec0c4 3c02            cmp     al,2
        b0bec0c6 beb861bfb0      mov     esi,offset TesSafe+0xd1b8 (b0bf61b8)
        b0bec0cb 8bce            mov     ecx,esi
        b0bec0cd 720a            jb      TesSafe+0x30d9 (b0bec0d9)
        b0bec0cf ff157830bfb0    call    dword ptr [TesSafe+0xa078 (b0bf3078)]//KefAcquireSpinLockAtDpcLevel
        b0bec0d5 fec3            inc     bl
        b0bec0d7 eb09            jmp     TesSafe+0x30e2 (b0bec0e2)
        b0bec0d9 ff150c30bfb0    call    dword ptr [TesSafe+0xa00c (b0bf300c)]//KfAcquireSpinLock
        b0bec0df 8845fe          mov     byte ptr [ebp-2],al
        b0bec0e2 a1b061bfb0      mov     eax,dword ptr [TesSafe+0xd1b0 (b0bf61b0)]  //链表3
        b0bec0e7 b9b061bfb0      mov     ecx,offset TesSafe+0xd1b0 (b0bf61b0)
        b0bec0ec eb0a            jmp     TesSafe+0x30f8 (b0bec0f8)
        b0bec0ee 8b50dc          mov     edx,dword ptr [eax-24h] //这里是系统的结构呢,还是TX自己定义的????
        b0bec0f1 3b5508          cmp     edx,dword ptr [ebp+8]   //PEPROCEE
        b0bec0f4 7408            je      TesSafe+0x30fe (b0bec0fe)
        b0bec0f6 8b00            mov     eax,dword ptr [eax]
        b0bec0f8 3bc1            cmp     eax,ecx
        b0bec0fa 75f2            jne     TesSafe+0x30ee (b0bec0ee)
        b0bec0fc eb0f            jmp     TesSafe+0x310d (b0bec10d)
        b0bec0fe 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
        b0bec101 ff40fc          inc     dword ptr [eax-4]
        b0bec104 8548e4          test    dword ptr [eax-1Ch],ecx
        b0bec107 7404            je      TesSafe+0x310d (b0bec10d)
        b0bec109 c645ff01        mov     byte ptr [ebp-1],1
        b0bec10d 84db            test    bl,bl
        b0bec10f 8bce            mov     ecx,esi
        b0bec111 7408            je      TesSafe+0x311b (b0bec11b)
        b0bec113 ff157430bfb0    call    dword ptr [TesSafe+0xa074 (b0bf3074)]//KefReleaseSpinLockFromDpcLevel
        b0bec119 eb09            jmp     TesSafe+0x3124 (b0bec124)
        b0bec11b 8a55fe          mov     dl,byte ptr [ebp-2]
        b0bec11e ff151030bfb0    call    dword ptr [TesSafe+0xa010 (b0bf3010)]//KfReleaseSpinLock
        b0bec124 8a45ff          mov     al,byte ptr [ebp-1]
        b0bec127 5e              pop     esi
        b0bec128 5b              pop     ebx
        b0bec129 c9              leave
        b0bec12a c20800          ret     8*/






    大家看出来他是通过3个函数比较3个链表,然后才决定放不放行的,那我们通过遍历3个链表的EPROCESS
结构读取出EPROCESS的进程名字基本上就能判断那个链表是白名单,那个是黑名单了吧? 不知道我的理解是否正确。

  论坛新版本用得不顺手大家看起来会很槽糕!哈哈,见谅!

Rank: 1

发表于 2011-11-28 13:25:16 |显示全部楼层
敲个代码鉴定下.DZ还算好用.

Rank: 1

发表于 2011-12-6 17:50:49 |显示全部楼层
马克

Rank: 1

发表于 2012-1-2 19:28:07 |显示全部楼层
继续。。。。,膜拜

Rank: 1

发表于 2012-5-16 03:03:20 |显示全部楼层
感谢分享 学习白名单

Rank: 1

发表于 2012-6-7 13:54:17 |显示全部楼层
感谢分享. 学习白名单.

Rank: 1

发表于 2012-10-25 16:37:02 |显示全部楼层
顶楼主 楼主观点不错  

www.ZTSUN.COM  充气娃娃多少钱
www.szyuantaidz.com  脚气
www.yushenjt.com  阴茎短小
www.btdyj.com  脚臭
www.1tidc.com  蹭网器
www.cn-xyz.com  卡皇
www.hfloge.com  白发治疗
www.hnshiqi.com  英国卫裤
www.wzeas.com  治疗白发
www.qdzjzc.com  伟哥官网
www.szjczq.com  日本充气娃娃

Rank: 1

发表于 2012-11-14 20:51:46 |显示全部楼层
我们来看 Directory类型的对象体 OBJECT_DIRECTORY 的定义

#define OBJECT_HASH_TABLE_SIZE 37

typedef struct _OBJECT_DIRECTORY
{
/*000*/ POBJECT_DIRECTOhttp://www.cqww8888.com
http://www.f1cqww.com
.comRY_ENTRY HashTable [OBJECT_HASH_TABLE_SIZE];
/*094*/ POBJECT_DIRECTORY_ENTRY CurrentEntry;
/*098*/ BOOLEAN CurrentEntryValid;
/*099*/ BYTE Reserved1;
/*09A*/ WORD Reserved2;
/*09C*/ DWORD Reserved3;
/*0A0*/ }
OBJECT_DIRECTORY;

typedef struct _OBJECT_DIRECTORY_ENTRY
{
/*000*/ struct _OBJECT_DIRECTORY_ENTRY *NextEntry;
/*004*/ POBJECT Object;
/*008*/ }
OBJECT_DIRECTORY_ENTRY;

从定义中我们看到 OBJECT_DIRECTORY 中主要是一个37项的哈希表。每项是一个指向 OBJECT_DIRECTORY_ENTRY 的指针。指向一个 OBJECT_DIRECTORY_ENTRY 组成的链。OBJECT_DIRECTORY_ENTRY 结构有两个域,第一个域是指向链的下一个OBJECT_DIRECTORY_ENTRY的指针,如果值为空的话,表明链已经结束了。第二域是指向一个某种类型对象的对象体的指针。比如上面例子中 HashBucket[ 16 ]: 81416530 Directory &#39;Driver&#39; 的链上只有一项,该项的第二个域指向一个Directory类型对象。当有一个新的对象想要放入某个目录下,或者需要根据对象的名字查找对象时,通过哈希函数来确定对象该在哈希表的37个表目中的哪一个链上。这里所做的就是通过对对象名的每一个字符做一定的计算,最后得到一个数,用这个数除以37,取余数,得到了0-36 中的某个数,来确定所在的哈希表目。也就是用哈希函数对对象名计算来确定该对象应该在哈希表中的什么地方。如果想了解那个哈希函数具体算法,可以跟一下 ObpLookupDirectoryEntry 函数。使用 kd? ObpLookupDirectoryEntry 获得该函数的入口地址,然后用SoftICE断该地址。我用SoftICE大概跟了一下,这个函数有3个参数,第一个参数是一个指向OBJECT_DIRECTORY的指针,指定查找的目录。第二个参数是一个指向UNICODE_STRING的指针,指定要查找的名字。我就不详细叙述了。如果只是想找到某个名字的对象的话,可以遍历整个目录的每一个OBJECT_DIRECTORY_ENTRY,这样虽然慢一些,不过如果将来哈希函数有所变化的话,不会受到影响。 OBJECT_DIRECTORY 中使用哈希表的原因是为了加快查找速度。如果不使用哈希表的话,可以每个目录只维护一个对象链表,不过那样的话,根据对象名在某个目录下查找该对象的指针,有可能得遍历该目录下的每个对象。而使用了哈希表,利用哈希函数的计算,将很快确定只在该目录下的一部分对象中遍历。目前目录对象哈希表的项数为37。影响项数的一个因素是通常一个目录下可能会有多少对象,应该尽可能保证链上只有一项,或者链很短,来保证查找的速度。在 kd 中使用 !object 命令观察几个对象目录,可以看到Win2k使用的哈希函数,和37作为哈希表项数,效果还是不错的,对象比较均匀的分布在哈希表中,而且很多哈希表项对应的链上只有一个对象,有多个对象的链也都不是很长。

下面我们来看实际的例子,从前面 kd 的输出
kd&gt; !object \\
!object \\
Object: 8141echtthttp://www.dsb369.com
http://www.cqww181.comd0 Type: (81452820) Directory
ObjectHeader: 8141ecb8
...
我们看到对象&quot;\\&quot;的对象头在 8141ecb8 ,对象体在 8141ecd0,对象头结构大小为0x18,也可以看出对象头和对象体是紧挨在一起的。下面我们来分析目录类型对象&quot;\\&quot;的对象体。

kd&gt; dd 8141ecd0 l a0/4
dd 8141ecd0 l a0/4
8141ecd0 e1008c68 e2f7c008 00000000 e10073c8
8141ece0 00000000 00000000 00000000 e2bac088
8141ecf0 00000000 e2bea1a8 e10001e8 00000000
8141ed00 00000000 e13891a8 e2bea328 00000000
8141ed10 e131eb08 e2baf188 e132f208 e1008ba8
8141ed20 e17b6708 e13d4268 e17b65e8 e135a768
8141ed30 e1007f28 00000000 e10004a8 e1007708
8141ed40 00000000 00000000 00000000 e1008b08
8141ed50 e10003a8 e2ffe508 00000000 e17bca68

Rank: 1

发表于 2012-12-26 16:42:08 |显示全部楼层
不错!!顶

Rank: 1

发表于 2013-3-26 00:42:16 |显示全部楼层
新手膜拜,大师

Rank: 1

发表于 2013-4-29 21:07:31 |显示全部楼层
本帖最后由 燃烧的木头 于 2013-4-29 21:07 编辑

学习了,我是新人,请多指教
您需要登录后才可以回帖 登录 | 立即加入

Archiver|手机版|第8个男人 - 论坛为只读模式,仅供查阅

GMT+8, 2019-5-27 04:10 , Processed in 0.028313 second(s), 8 queries .

Design by pvo.cn

© 2011 Pvo Inc.

回顶部