📄 procname.c
字号:
/* found the necessary entry */
LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("%d CreateProccessNotifyProc(): Found (%s) %d %x %S\n", CURRENT_PROCESS_PID, Create == FALSE ? "delete" : "fix", p->ProcessId, p->next, p->ImageName));
tmp = p;
/* unlink the found entry */
prev->next = p->next;
if (Create == FALSE)
{
/* if the process is being deleted then free the entry */
PolicyDelete(&tmp->SecPolicy);
ExFreePoolWithTag(tmp, _POOL_TAG);
}
else
{
/*
* if the process is being executed and we found an entry with PID of 0 then
* replace 0 with the real pid
*/
tmp->ProcessId = (ULONG) ProcessId;
tmp->next = NULL;
FoundNewProcess = TRUE;
}
break;
}
KeReleaseSpinLock(&gImagePidHtblSpinLock, irql);
/*
* If necessary, reinsert the new entry that used to have a PID of 0.
* We need to reinsert since the hashtable is indexed by PIDs.
*/
if (FoundNewProcess == TRUE)
{
//XXX at this point no locks are held. if tmp->ProcessId process quits before ProcessInsertImagePidEntry()
// executes, we will get a zombie entry (will never be removed)
LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("%d Replacing 0 with %d for %S\n", CURRENT_PROCESS_PID, tmp->ProcessId, tmp->ImageName));
ProcessInsertImagePidEntry(tmp->ProcessId, tmp);
LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("%d Done replacing %d\n", CURRENT_PROCESS_PID, tmp->ProcessId, tmp->ImageName));
}
}
USHORT ProcessNameOffset = 0, ThreadServiceTableOffset = 0;
/*
* FindProcessNameOffset()
*
* Description:
* Identifies process name offset in the EPROCESS structure.
*
* The name offset is identified by searching for "System" string in the System EPROCESS structure
* (this function is called when the driver is loaded and thus runs in the "System" context).
*
* ThreadServiceTableOffset is the offset of the pointer to a service descriptor table (syscall table)
* in the Thread Environment Block (TEB). Used to determine whether a thread is GUI based or not.
*
* Parameters:
* None.
*
* Returns:
* Nothing.
*/
void
FindProcessNameOffset()
{
PEPROCESS SystemProcess = PsGetCurrentProcess(); // current "System" process
PETHREAD SystemThread = PsGetCurrentThread(); // current "System" thread
USHORT i;
/* Search for "System" process name in the current system process Process Environment Block */
for (i = 0; i < 1024; i++) // 372 on Windows XP SP1
{
if (_strnicmp((PCHAR) SystemProcess + i, "System", 6) == 0)
{
ProcessNameOffset = i;
break;
}
}
/* Search for KeServiceDescriptorTable address in the current system thread's Thread Environment Block */
for (i = 0; i < 500; i++) // 292 on Win2k3
{
if (* (PULONG) ((PCHAR) SystemThread + i) == (ULONG) &KeServiceDescriptorTable[0])
{
ThreadServiceTableOffset = i;
break;
}
}
}
/*
* GetCurrentProcessName()
*
* Description:
* Returns the current process pathname.
*
* Parameters:
* None.
*
* Returns:
* Pointer to the current process pathname ("Unknown" if not found).
*/
PWCHAR
GetCurrentProcessName()
{
PIMAGE_PID_ENTRY p;
PWCHAR name = NULL;
p = FindImagePidEntry(CURRENT_PROCESS_PID, 0);
if (p != NULL)
/*
* NOTE: we are returning a pointer to a member of a structure which is not locked at this point!
* Should be ok though since this function is only called in the context of a current process which
* cannot disappear from underneath us.
*/
name = p->ImageName;
else
name = L"(Unknown)";
return name;
}
/*
* FindExistingProcesses()
*
* Description:
* Enumerates all the existing processes using ZwQuerySystemInformation(SystemProcessesAndThreadsInformation)
* and creates IMAGE_PID_ENTRY for all of them. Called once at startup.
*
* Parameters:
* None.
*
* Returns:
* Nothing.
*/
VOID
EnumerateExistingProcesses()
{
ULONG size = 65535, i;
PUCHAR SystemInfo;
PSYSTEM_PROCESSES pSystemProcess;
NTSTATUS status;
/*
* The format of the data returned to the SystemInformation buffer is a sequence of
* SYSTEM_PROCESSES structures, chained together via the NextEntryDelta member.
* The Threads member of each SYSTEM_PROCESSES structure is an array of ThreadCount
* SYSTEM_THREADS structures.The end of the process chain is marked by a NextEntryDelta
* value of zero.
*/
/* first, find out the total amount of SystemProcessesAndThreadsInformation to be returned */
/*
status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, &i, 0, &size);
if (size == 0 || size > 1024*1024)
{
LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("FindExistingProcesses: ZwQuerySystemInformation failed. status=%x size=%d\n", status, size));
return;
}
*/
/* second, allocate the required amount of memory */
SystemInfo = ExAllocatePoolWithTag(PagedPool, size, _POOL_TAG);
if (SystemInfo == NULL)
{
LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("FindExistingProcesses: out of memory (requested %d bytes)\n", size));
return;
}
/* third, request the SystemProcessesAndThreadsInformation */
ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, SystemInfo, size, &i);
pSystemProcess = (PSYSTEM_PROCESSES) SystemInfo;
i = 0;
while (pSystemProcess->NextEntryDelta != 0)
{
if (pSystemProcess->ProcessName.Length != 0)
{
/* create a new process entry and load the associated security policy (if any) */
CreateAndLoadNewProcessEntry(pSystemProcess->ProcessId, &pSystemProcess->ProcessName, FALSE);
++i;
}
pSystemProcess = (PSYSTEM_PROCESSES) ( ((PUCHAR) pSystemProcess) + pSystemProcess->NextEntryDelta);
}
ExFreePoolWithTag(SystemInfo, _POOL_TAG);
/* if no processes exist, the computer must be booting up */
if (i == 0)
{
UNICODE_STRING System;
BootingUp = TRUE;
/*
* when booting up no processes are listed as existing even though "System" and "Idle"
* have already been initialized. Initialize "System" process entry since it will
* never be created otherwise.
*/
RtlInitUnicodeString(&System, L"System");
CreateAndLoadNewProcessEntry(SystemProcessId, &System, FALSE);
}
}
/*
* InitProcessNameEntries()
*
* Description:
* Initializes process id to process name related data.
*
* NOTE: Called once during driver initialization (DriverEntry()).
*
* Parameters:
* None.
*
* Returns:
* TRUE to indicate success, FALSE if failed.
*/
BOOLEAN
InitProcessNameEntries()
{
memset(gImagePidHtbl, 0, sizeof(gImagePidHtbl));
KeInitializeSpinLock(&gImagePidHtblSpinLock);
SystemProcessId = (ULONG) PsGetCurrentProcessId();
FindProcessNameOffset();
/* XXX investigate
A driver's process-notify routine is also called with Create set to FALSE, usually when the last thread within a process has terminated and the process address space is about to be deleted. In very rare circumstances, for processes in which no thread was ever created, a driver's process-notify routine is called only at the destruction of the process. */
if (! NT_SUCCESS( PsSetCreateProcessNotifyRoutine(CreateProcessNotifyProc, FALSE) ))
{
LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("InitProcessNameEntries: PsSetCreateProcessNotifyRoutine() failed\n"));
return FALSE;
}
return TRUE;
}
/*
* RemoveProcessNameEntries()
*
* Description:
* Removes the global hash table process entries and PsSetCreateProcessNotifyRoutine() callback.
*
* NOTE: Called once during driver unload (DriverUnload()).
*
* Parameters:
* None.
*
* Returns:
* Nothing.
*/
VOID
RemoveProcessNameEntries()
{
int i;
PIMAGE_PID_ENTRY p, tmp;
KIRQL irql;
#if HOOK_PROCESS
if (! NT_SUCCESS( PsSetCreateProcessNotifyRoutine(CreateProcessNotifyProc, TRUE) ))
LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("RemoveProcessEntries: PsSetCreateProcessNotifyRoutine remove failed\n"));
#endif
KeAcquireSpinLock(&gImagePidHtblSpinLock, &irql);
for (i = 0; i < IMAGE_PID_HASHTABLE_SIZE; i++)
{
p = gImagePidHtbl[i].next;
while (p)
{
LOG(LOG_SS_PROCESS, LOG_PRIORITY_VERBOSE, ("RemoveProcessEntries: Removing %d %x %S\n", p->ProcessId, p->next, p->ImageName));
tmp = p;
p = p->next;
if (tmp->WaitingForUserRequestId != 0)
{
LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("RemoveProcessEntries: Process (pid=%d) is still waiting for a user request id %d!\n", tmp->ProcessId, tmp->WaitingForUserRequestId));
}
PolicyDelete(&tmp->SecPolicy);
ExFreePoolWithTag(tmp, _POOL_TAG);
}
}
KeReleaseSpinLock(&gImagePidHtblSpinLock, irql);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -