S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

HOOK SSDT Hide Process (五)

Posted on 2009-10-26 13:41 S.l.e!ep.¢% 阅读(703) 评论(0)  编辑 收藏 引用 所属分类: RootKit
HOOK SSDT Hide Process (四) 的code改进了一下,支持Display Process's Owner
在 XP 下进行测试没发现问题,但在 Win7 下只能显示当前用户的 Process, 其它用户还有一些 NETWORK SERVICE
的进程无法显示出来

Code:
#include <stdlib.h>
#include 
<stdio.h>
#include 
<windows.h>

typedef 
long NTSTATUS;

#define ULONG_PTR ULONG

#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)

#define NT_SUCCESS(Status) ((NTSTATUS)(Status)>=0) 

//
// Unicode strings are counted 16-bit character strings. If they are
// NULL terminated, Length does not include trailing NULL.
//

typedef 
struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;

} UNICODE_STRING, 
*PUNICODE_STRING;

//
// Thread priority
//

typedef LONG KPRIORITY;

//-----------------------------------------------------------------------------
// Query system information

typedef 
enum _SYSTEM_INFORMATION_CLASS
{
    SystemBasicInformation,                 
// 0x00 SYSTEM_BASIC_INFORMATION
    SystemProcessorInformation,             // 0x01 SYSTEM_PROCESSOR_INFORMATION
    SystemPerformanceInformation,           // 0x02
    SystemTimeOfDayInformation,             // 0x03
    SystemPathInformation,                  // 0x04
    SystemProcessInformation,               // 0x05
    SystemCallCountInformation,             // 0x06
    SystemDeviceInformation,                // 0x07
    SystemProcessorPerformanceInformation,  // 0x08
    SystemFlagsInformation,                 // 0x09
    SystemCallTimeInformation,              // 0x0A
    SystemModuleInformation,                // 0x0B SYSTEM_MODULE_INFORMATION
    SystemLocksInformation,                 // 0x0C
    SystemStackTraceInformation,            // 0x0D
    SystemPagedPoolInformation,             // 0x0E
    SystemNonPagedPoolInformation,          // 0x0F
    SystemHandleInformation,                // 0x10
    SystemObjectInformation,                // 0x11
    SystemPageFileInformation,              // 0x12
    SystemVdmInstemulInformation,           // 0x13
    SystemVdmBopInformation,                // 0x14
    SystemFileCacheInformation,             // 0x15
    SystemPoolTagInformation,               // 0x16
    SystemInterruptInformation,             // 0x17
    SystemDpcBehaviorInformation,           // 0x18
    SystemFullMemoryInformation,            // 0x19
    SystemLoadGdiDriverInformation,         // 0x1A
    SystemUnloadGdiDriverInformation,       // 0x1B
    SystemTimeAdjustmentInformation,        // 0x1C
    SystemSummaryMemoryInformation,         // 0x1D
    SystemNextEventIdInformation,           // 0x1E
    SystemEventIdsInformation,              // 0x1F
    SystemCrashDumpInformation,             // 0x20
    SystemExceptionInformation,             // 0x21
    SystemCrashDumpStateInformation,        // 0x22
    SystemKernelDebuggerInformation,        // 0x23
    SystemContextSwitchInformation,         // 0x24
    SystemRegistryQuotaInformation,         // 0x25
    SystemExtendServiceTableInformation,    // 0x26
    SystemPrioritySeperation,               // 0x27
    SystemPlugPlayBusInformation,           // 0x28
    SystemDockInformation,                  // 0x29
    
//SystemPowerInformation,               // 0x2A
    
//SystemProcessorSpeedInformation,      // 0x2B
    
//SystemCurrentTimeZoneInformation,     // 0x2C
    
//SystemLookasideInformation            // 0x2D

} SYSTEM_INFORMATION_CLASS, 
*PSYSTEM_INFORMATION_CLASS;

//
// Process information
// NtQuerySystemInformation with SystemProcessInformation
//

typedef 
struct _SYSTEM_PROCESS_INFORMATION {
    ULONG NextEntryOffset;
    ULONG NumberOfThreads;
    LARGE_INTEGER SpareLi1;
    LARGE_INTEGER SpareLi2;
    LARGE_INTEGER SpareLi3;
    LARGE_INTEGER CreateTime;
    LARGE_INTEGER UserTime;
    LARGE_INTEGER KernelTime;
    UNICODE_STRING ImageName;
    KPRIORITY BasePriority;
    ULONG_PTR UniqueProcessId;
    ULONG_PTR InheritedFromUniqueProcessId;
    ULONG HandleCount;
    
// Next part is platform dependent

} SYSTEM_PROCESS_INFORMATION, 
*PSYSTEM_PROCESS_INFORMATION;

typedef NTSTATUS 
 (NTAPI 
*PNFNtQuerySystemInformation)(
    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
    OUT PVOID SystemInformation,
    IN ULONG SystemInformationLength,
    OUT PULONG ReturnLength
    );

PNFNtQuerySystemInformation pNtQuerySystemInformation;

//   
// GetProcessUsername()   
//   
/*

While I have not yet had time to thoroughly test this solution, 
it's working well for me so far (I just finished this initial version in the last couple of hours). Posting here because I searched all over before deciding to try a different approach, and could not find one. It seems that the DEBUG privilege will allow you to open a process handle, but not necessairly the process tokens. No back door for that!
I have been able to use GetUserObjectSecurity() from an Admin account to get the Owner SID for the process, and that generally turns out to be the user who started the process. Several system processes show "Builtin\Administrators" for their owner for my purposes I return NULL for those (other code then defaults the user to "SYSTEM" to match TaskMgr). You will still need the DEBUG privilege for this to work (else OpenProcess could fail).
I adapted this code from another post I found that used the well-known OpenProcessToken pathway. It isn't very pretty, but as I said I just got it working. Note the need for STANDARD_RIGHTS_READ on the hProcess. I also have PROCESS_QUERY_INFORMATION and PROCESS_VM_READ included in my calling code (for access to other process information) and have not tried calling GetProcessUsername() on a handle without these set to see if that works or not.
NOTE THAT THE RESULT IS RETURNED AS A STATIC!! It would be cleaner to let the caller pass in a buffer (in fact there are lots of things that should be cleaned up in this sample). It nonetheless demonstrates the concept.
Since I just came up with this and have had limited time to test it, if you use it please let me know if it works (or doesn't) for your application:
*/
// Get username and domain from a supplied process handle.   
//   
// hProcess : is the process handle of which   
//   to get the username from.   
//   
// bIncDomain : if true will prepend the DOMAIN and  to    
//   the returned string.   
//   
// Returns a reference to a static string containing the    
// username or NULL on error.   
//    
//   
char* GetProcessUsername(HANDLE hProcess, BOOL bIncDomain)   
{   
    
static char sname[300];   
    
char name[300], dom[300], *pret = 0;   
    SECURITY_DESCRIPTOR 
*psd = NULL;   
    BOOL b;   
    
int iUse, rc;   
    DWORD d;   
    SECURITY_INFORMATION SecInfo 
= OWNER_SECURITY_INFORMATION;   
    
    
// This Is a round-about method I discovered. Instead of OpenProcessToken and GetTokenInformation use GetUserObjectSecurity and pull   
    
// the OWNER information. Ignore BUILTIN Administrators group as an owner (we want that to show up as SYSTEM). Using the tokens is   
    
// subject to ACCESS DENIED errors on OpenProcessToken, even for administrators. This work around seems to work regardless. Unclear    
    
// what the diff between GetUserObjectSecurity and GetKernelObjectSecurity is. So stick with GetUserObjectSecurity for now.   
    
// Requires STANDARD_RIGHTS_READ on hProcess (in OpenProcess call).   
    
    
//b = GetKernelObjectSecurity(hProcess, SecInfo, psd, 0, &d);   
    b = GetUserObjectSecurity(hProcess, &SecInfo, psd, 0&d);   
    rc 
= GetLastError();   
    psd 
= (SECURITY_DESCRIPTOR *)malloc(d);   
    
if (psd != NULL)   
    {   
        memset (psd, 
0, d);   
        
//b = GetKernelObjectSecurity(hProcess, SecInfo, psd, d, &d);   
        b = GetUserObjectSecurity(hProcess, &SecInfo, psd, d, &d);   
        
if (b)   
        {   
            PSID psidOwner;   
            BOOL bDefaulted;   
            b 
= GetSecurityDescriptorOwner(psd, &psidOwner, &bDefaulted);   
            
if (IsValidSid(psidOwner) )   
            {   
                
// We have a valid Owner SID. Decode it   
                DWORD dlen = sizeof(dom);   
                DWORD nlen 
= sizeof(name);   
                b 
= LookupAccountSid(0, psidOwner, name, &nlen, dom, &dlen, (PSID_NAME_USE)&iUse);   
                
if (b && lstrcmpi(dom, "Builtin"!= 0 && lstrcmpi(dom, "Administrators"!= 0)   
                {   
                    
//copy info to our static buffer   
                    if (dlen && bIncDomain)   
                    {   
                        lstrcpy(sname,dom);   
                        lstrcat(sname,
"\\");   
                        lstrcat(sname,name);   
                    }    
                    
else   
                        lstrcpy(sname,name);   
                    
//set our return variable   
                    pret = sname;   
                }   
                
else   
                    rc 
= GetLastError();   
            }   
        }   
        
else   
            rc 
= GetLastError();   
    }   
    
    
if (psd != NULL)   
        free (psd);   
    
return pret;   
}   

BOOL QueryThreadInfo()
{
    HMODULE hMod 
= GetModuleHandle("ntdll.dll");

    
if (hMod == NULL)
    {
        hMod 
= LoadLibrary("ntdll.dll");
        
if (hMod == NULL)
        {
            printf(
"LoadLibrary Error: %d\n", GetLastError());
            
return FALSE;
        }
    }

    pNtQuerySystemInformation 
= (PNFNtQuerySystemInformation)GetProcAddress(hMod, "NtQuerySystemInformation");

    
if( pNtQuerySystemInformation == NULL )
    {
        printf(
"GetProcAddress for NtQuerySystemInformation Error: %d\n", GetLastError());
        
return FALSE;
    }

//     ULONG dwNumberBytes = 0x8000;
//     char* pBuf = (char*)malloc(dwNumberBytes);
//     PSYSTEM_PROCESS_INFORMATION pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)pBuf;
    ULONG nNeedSize = 0;
    
    NTSTATUS nStatus 
= pNtQuerySystemInformation(SystemProcessInformation, NULL, NULL, &nNeedSize);
    
    
if (STATUS_INFO_LENGTH_MISMATCH != nStatus)
    {
        
return FALSE;
    }

    PVOID lpBuffer 
= LocalAlloc(LPTR, nNeedSize);

    
if (NULL == lpBuffer)
    {
        
return FALSE;
    }

    nStatus 
= pNtQuerySystemInformation(SystemProcessInformation, lpBuffer, nNeedSize, 0);

    
if (NT_SUCCESS(nStatus))
    {
        PSYSTEM_PROCESS_INFORMATION ProcessInfo 
= (PSYSTEM_PROCESS_INFORMATION)lpBuffer;

        
while( NULL != ProcessInfo ) 
        {        
            
char szANSIString[MAX_PATH];   
            memset(szANSIString, 
0, MAX_PATH);
            WideCharToMultiByte(CP_ACP, 
                WC_COMPOSITECHECK,
                ProcessInfo
->ImageName.Buffer,
                
-1
                szANSIString, 
                
sizeof(szANSIString), 
                NULL,
                NULL);

            printf(
"%d  ", ProcessInfo->UniqueProcessId);
            printf(
"%s  ", szANSIString);

            HANDLE hProcess 
= ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessInfo->UniqueProcessId);
            printf(
"%s  ", GetProcessUsername(hProcess, FALSE));
            CloseHandle(hProcess);
            printf(
"\n");

            
if ( ProcessInfo->NextEntryOffset )
            {
                ProcessInfo 
=  (PSYSTEM_PROCESS_INFORMATION)
                    ((DWORD)ProcessInfo 
+ (DWORD)(ProcessInfo->NextEntryOffset));
            }
            
else
            {
                ProcessInfo 
= NULL;
            }
        }

        
return TRUE;
    }
    
else
    {
        LocalFree(lpBuffer);
        
return FALSE;
    }

    
return FALSE;
}

int main()
{
    
if!QueryThreadInfo() )
    {
        printf(
"QueryThreadInfo Error!\n");
        
return 0;
    }

    
return 0;
}



只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理