Header

  1. View current page

    kkamagui의 프로그래밍 작업실

Profile_image?t=1221830958&type=big
온갖 자료가 난무하는 kkamagui의 Springnote~!!!
22

06 Find Hide Process

1.RootKit 발췌

http://rootkit.com/newsread.php?newsid=519 : 원문

 

  1. // Easy to Find Hided PID Code
    // Author: Finback Jun.6,2006 <Finbackcpp@hotmail.com>
    // NOTE:this code needn't any driver supported

    #include "stdafx.h"
    #include <windows.h>
    #include "psapi.h"

    #pragma comment(lib,"psapi.lib")

    int main(int argc, char* argv[])
    {
        printf("\nEasy to Find Hided PID Code \n");
        printf("Author: Finback Jun.6,2006 <Finbackcpp@hotmail.com> \n");
        printf("NOTE:this code needn't any driver supported \n");
        printf(" \n");

            DWORD aProcesses[1024], cbNeeded;

        if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
            return 0;
        DWORD cProcesses = cbNeeded / sizeof(DWORD);

        DWORD PidFor;
        for ( PidFor = 0x0c; PidFor < 0xFFFF; PidFor +=4 )
        {
            HANDLE hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |
                PROCESS_VM_READ,
                FALSE, PidFor );

            if (hProcess)
            {
                BOOL sHide = false;
                unsigned int i;
                char szName[MAX_PATH]="<Unknown>";
                HMODULE hModule;

                for ( i = 1; i <= cProcesses; i++ )
                {
                    if (PidFor == aProcesses[i])
                    {
                        sHide = true;
                        break;
                    }
                }
                if(EnumProcessModules(hProcess,&hModule,sizeof(hModule),&cbNeeded))
                    {
                        GetModuleFileNameEx(hProcess,hModule,szName,sizeof(szName));
                        printf("%-5d - %16s  %s\n", PidFor, szName, (sHide) ? "" : "--[Hidden]--");
                    }
                else
                    {
                        GetProcessImageFileName(hProcess,szName,sizeof(szName));
                        printf("%-5d - %16s  %s\n", PidFor, szName, "--[Zombie]--");
                    }
            }
            CloseHandle( hProcess );
        }
        return 0;
    }

 

2.PspCidTable 사용

원문 :http://somma.egloos.com/3678104

/** -----------------------------------------------------------------------
\brief

\param
\return
\code

\endcode
-------------------------------------------------------------------------*/
NTSTATUS __stdcall ScanXpHandleTable(IN PHANDLE_TABLE pPspCidTable,
/*IN DWORD NumberOfCpu, */
IN PPROC_MANAGER pPm)
{
ASSERT(NULL != pPspCidTable);
ASSERT(NULL != pPm);
if ( (NULL == pPspCidTable) || (NULL == pPm) )
{
SPDEBUG(DBG_GENERAL, DBG_ERR, "%s >> invalid parameter", __FUNCTION__);
return STATUS_INVALID_PARAMETER;
}

PXP_HANDLE_TABLE pXpHandleTable = (PXP_HANDLE_TABLE)pPspCidTable;
ULONG i = 0, j = 0, k = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL;

// 31 2 1 0
// |--------------------------------|-|-|
// 상위 30 비트 : _HANDLE_TABLE_ENTRY 포인터
// 하위 2 비트 : 핸들 테이블 레벨 인덱스
//
// LevelIndex : 현재 시스템에 구성된 HANDLE_TABLE 레벨
// pEntryPtr : 현재 LevelIndex 에 맞는 첫번째 PHANDLE_TABLE_ENTRY
//
ULONG LevelIndex = pXpHandleTable->TableCode & TABLE_LEVEL_MASK;
ULONG pEntryPtr = pXpHandleTable->TableCode & ~TABLE_LEVEL_MASK;

// xp, 2003 의 경우 페이지가 수용하는 만큼의 HANDLE_TABLE_ENTRY -1 개를 생성하며
// x86 mmu 는 프로세스당 16M 의 핸들을 사용할 수 있게 한다.
// top level pointers = 32 개
// mid level pointers = 1024 개
// sub handle table = 512 개
//
ULONG top_level_count = 32;
ULONG mid_level_count = 1024;
ULONG sub_level_count = PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY);

DWORD Cid = 0;
PHANDLE_TABLE_ENTRY pEntry = NULL;

// xp 의 경우 _HANDLE_TABLE.TableCode 의 하위 2비트를 통해서
// 3 단계 _HANDLE_TABLE 을 구성한다.
//
switch (LevelIndex)
{
case 0 :
SPDEBUG(DBG_GENERAL, DBG_INFO, "handle table level index = 0", "");
for (i = 0; i < sub_level_count; i++)
{
pEntry = &((PHANDLE_TABLE_ENTRY)pEntryPtr)[i];

if ( ( NULL != pEntry ) && (NULL != pEntry->Object) )
{
// xp, 2003 은 _HANDLE_TABLE_ENTRY.Object 필드의 최하위 비트가 Lock 비트 이므로
// Lock 비트를 클리어시키면 _HANDLE_TABLE_ENTRY.Object 는 커널 오브젝트 포인터가 된다.
// 즉 이것은 _OBJECT_HEADER.Body 를 가리키는 포인터이다.
// 이때 _OBJECT_HEADER.Type 필드를 참조해서 Body 가 어떤 오브젝트인지 판단하며
// 만일 Process object 인 경우 Body 필드는 _EPROCESS 구조체의 시작 주소가 된다.
// 주의할 것은 _OBJECT_HEADER.Body 필드는 포인터가 아닌 실제 구조체란 것이다.
//
// ( (ULONG) Entry->Object & ~XP_TABLE_ENTRY_LOCK_BIT )
//
// 위 식은 실제 Object 를 가리키는 포인터 이므로 _OBJECT_HEADER 를 찾기 위해서는
//
// PVOID pObj = ( (ULONG) Entry->Object & ~XP_TABLE_ENTRY_LOCK_BIT ); // process (_EPROCESS) / thread (_ETHREAD)
//
// POBJECT_HEADER pObjHeader = (ULONG) pObj - (Body offset);
//
// BodyOffset 은 xp sp2 의 경우 0x18 이다.
//
// kd> dt _OBJECT_HEADER
// +0x000 PointerCount : Int4B
// +0x004 HandleCount : Int4B
// +0x004 NextToFree : Ptr32 Void
// +0x008 Type : Ptr32 _OBJECT_TYPE
// +0x00c NameInfoOffset : UChar
// +0x00d HandleInfoOffset : UChar
// +0x00e QuotaInfoOffset : UChar
// +0x00f Flags : UChar
// +0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
// +0x010 QuotaBlockCharged : Ptr32 Void
// +0x014 SecurityDescriptor : Ptr32 Void
// +0x018 Body : _QUAD <<<<=======
//
//
PVOID pObjBody = (PVOID)( (ULONG) pEntry->Object & ~XP_TABLE_ENTRY_LOCK_BIT );
POBJECT_HEADER pObjHdr = OBJECT_TO_OBJECT_HEADER(pObjBody);
if (pObjHdr->Type == *PsProcessType)
{
PEPROCESS pEproc = (PEPROCESS) pObjBody;
Cid = *(ULONG*)((ULONG)pEproc + pPm->UniqueProcessId_offset);
//
// process list 에 추가
//
status = AddProcessAtDpcLevel(pPm, Cid, pEproc);
if (! NT_SUCCESS(status) )
{
SPDEBUG(DBG_GENERAL, DBG_ERR,
"AddProcessAtDpcLevel()");
continue;
}
}//if (pObjHdr->Type == *PsProcessType)
}
} // for
break;

case 1 :
SPDEBUG(DBG_GENERAL, DBG_INFO, "handle table level index = 1", "");
for (i = 0; i < mid_level_count; i++)
{
if (NULL != ( (PVOID *)pEntryPtr)[i] )
{
for (j = 0; j < sub_level_count; j++)
{
pEntry = &((PHANDLE_TABLE_ENTRY *)pEntryPtr)[i][j];
if ( (NULL != pEntry) && (NULL != pEntry->Object) )
{
PVOID pObjBody = (PVOID)( (ULONG) pEntry->Object & ~XP_TABLE_ENTRY_LOCK_BIT );
POBJECT_HEADER pObjHdr = OBJECT_TO_OBJECT_HEADER(pObjBody);
if (pObjHdr->Type == *PsProcessType)
{
PEPROCESS pEproc = (PEPROCESS) pObjBody;
Cid = *(ULONG*)((ULONG)pEproc + pPm->UniqueProcessId_offset);
//
// process list 에 추가
//
status = AddProcessAtDpcLevel(pPm, Cid, pEproc);
if (! NT_SUCCESS(status) )
{
SPDEBUG(DBG_GENERAL, DBG_ERR,
"AddProcessAtDpcLevel()");
continue;
}
}
} // if
}//for
}//if
}//for
break;

case 2 :
SPDEBUG(DBG_GENERAL, DBG_INFO, "handle table level index = 2", "");
for (i = 0; i < top_level_count; i++)
{
if (NULL != ( (PVOID *)pEntryPtr)[i] )
{
for (j = 0; j < mid_level_count; j++)
{
if (NULL != ((PVOID **)pEntryPtr)[i][j])
{
for (k = 0; k < sub_level_count; k++)
{
pEntry = &((PHANDLE_TABLE_ENTRY **)pEntryPtr)[i][j][k];
if ( (NULL != pEntry) && (NULL != pEntry->Object) )
{
PVOID pObjBody = (PVOID)( (ULONG) pEntry->Object & ~XP_TABLE_ENTRY_LOCK_BIT );
POBJECT_HEADER pObjHdr = OBJECT_TO_OBJECT_HEADER(pObjBody);
if (pObjHdr->Type == *PsProcessType)
{
PEPROCESS pEproc = (PEPROCESS) pObjBody;
Cid = *(ULONG*)((ULONG)pEproc + pPm->UniqueProcessId_offset);
//
// process list 에 추가
//
status = AddProcessAtDpcLevel(pPm, Cid, pEproc);
if (! NT_SUCCESS(status) )
{
SPDEBUG(DBG_GENERAL, DBG_ERR,
"AddProcessAtDpcLevel");
continue;
}
}
}
}
}
}//for
}//if
}//for
break;
default:
SPDEBUG(DBG_GENERAL, DBG_INFO,
"oops! handle table level index is over 3?");
break;
}

return STATUS_SUCCESS;
}

History

Last edited on 03/29/2008 13:52 by kkamagui

Comments (0)

You must log in to leave a comment. Please sign in.