|
Posted on 2009-10-26 13:41 S.l.e!ep.¢% 阅读(715) 评论(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; }
|