首页
社区
课程
招聘
[求助]如何通过EPROCESS获取SYSTEM_PROCESS_INFORMATION结构体?
发表于: 2013-6-6 23:33 9159

[求助]如何通过EPROCESS获取SYSTEM_PROCESS_INFORMATION结构体?

2013-6-6 23:33
9159
RT
现在我能拿到进程的EPROCESS或者句柄和PID
想获取一下SYSTEM_PROCESS_INFORMATION结构体

但是不想用ZwQuerySystemInformation

请问还有什么其他的方法不?

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 160
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
WRK
sysinfo.c
NtQuerySystemInformation
2013-6-6 23:57
0
雪    币: 140
活跃值: (125)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
NtQuerySystemInformation里面调用的ExpGetProcessInformation获取数据
但是ExpGetProcessInformation没有代码。不行嘚。
2013-6-7 01:09
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我怎么有,lz不会用source insight吗
NTSTATUS
ExpGetProcessInformation (
    OUT PVOID SystemInformation,
    IN ULONG SystemInformationLength,
    OUT PULONG Length OPTIONAL,
    IN PULONG SessionId OPTIONAL,
    IN BOOLEAN ExtendedInformation
    )

{
    KLOCK_QUEUE_HANDLE LockHandle;
    PEPROCESS Process = NULL;
    PETHREAD Thread;
    PSYSTEM_PROCESS_INFORMATION ProcessInfo;
    PVOID ThreadInfo;
    ULONG ThreadInfoSize;
    PLIST_ENTRY NextThread;
    PVOID MappedAddress;
    PVOID LockVariable;
    ULONG ProcessSessionId;
    ULONG TotalSize = 0;
    ULONG NextEntryOffset = 0;
    PUCHAR Src;
    PWCHAR SrcW;
    PWSTR Dst;
    ULONG n, nc;
    NTSTATUS status = STATUS_SUCCESS, status1;
    PUNICODE_STRING pImageFileName;

    if (ARGUMENT_PRESENT(Length)) {
        *Length = 0;
    }

    if (SystemInformationLength > 0) {
        status1 = ExLockUserBuffer (SystemInformation,
                                    SystemInformationLength,
                                    KeGetPreviousMode(),
                                    IoWriteAccess,
                                    &MappedAddress,
                                    &LockVariable);

        if (!NT_SUCCESS(status1)) {
            return status1;
        }

    } else {

        //
        // This indicates the caller just wants to know the size of the
        // buffer to allocate but is not prepared to accept any data content
        // in this instance.
        //

        MappedAddress = NULL;
        LockVariable = NULL;
    }

    if (ExtendedInformation) {
        ThreadInfoSize = sizeof(SYSTEM_EXTENDED_THREAD_INFORMATION);

    } else {
        ThreadInfoSize = sizeof(SYSTEM_THREAD_INFORMATION);
    }

    ProcessInfo = (PSYSTEM_PROCESS_INFORMATION) MappedAddress;

    try {

        //
        // Do the idle process first then all the other processes.
        //

        for  (Process = PsIdleProcess;
              Process != NULL;
              Process = PsGetNextProcess ((Process == PsIdleProcess) ? NULL : Process)) {

            //
            // If the process is marked as exiting, the executive process has
            // no active threads, the kernel process has no threads, and the
            // kernel process has been signaled, then skip the process.
            //
            // N.B. It is safe to examine the kernel thread list without a
            //      lock since no list pointers are dereferenced.
            //

            if (((Process->Flags & PS_PROCESS_FLAGS_PROCESS_EXITING) != 0) &&
                (Process->Pcb.Header.SignalState != 0) &&
                (Process->ActiveThreads == 0) &&
                (IsListEmpty(&Process->Pcb.ThreadListHead) == TRUE)) {

                continue;
            }

            if (ARGUMENT_PRESENT(SessionId) && (Process == PsIdleProcess)) {
                continue;
            }

            ProcessSessionId = MmGetSessionId (Process);
            if ((ARGUMENT_PRESENT(SessionId)) &&
                (ProcessSessionId != *SessionId)) {
                continue;
            }

            ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)
                            ((PUCHAR)MappedAddress + TotalSize);

            NextEntryOffset = sizeof(SYSTEM_PROCESS_INFORMATION);
            TotalSize += sizeof(SYSTEM_PROCESS_INFORMATION);
            if (TotalSize > SystemInformationLength) {
                status = STATUS_INFO_LENGTH_MISMATCH;
                if (ARGUMENT_PRESENT(Length) == FALSE) {
                    leave;
                }

            } else {

                //
                // Get information for each process.
                //

                ExpCopyProcessInfo (ProcessInfo, Process, ExtendedInformation);
                ProcessInfo->NumberOfThreads = 0;
                ProcessInfo->NextEntryOffset = 0;

                //
                // Store the Remote Terminal SessionId
                //

                ProcessInfo->SessionId = ProcessSessionId;
                ProcessInfo->ImageName.Buffer = NULL;
                ProcessInfo->ImageName.Length = 0;
                ProcessInfo->ImageName.MaximumLength = 0;
                if (Process == PsIdleProcess) {

                    //
                    // Since Idle process and system process share the same
                    // object table, zero out idle processes handle count to
                    // reduce confusion
                    //
                    // Idle Process always has SessionId 0
                    //

                    ProcessInfo->HandleCount = 0;
                    ProcessInfo->SessionId = 0;
                }
            }

            //
            // Raise IRQL to SYNCH_LEVEL, acquire the kernel process lock, and
            // get information for each thread.
            //

            ThreadInfo = (PVOID)(ProcessInfo + 1);
            KeAcquireInStackQueuedSpinLockRaiseToSynch(&Process->Pcb.ProcessLock,
                                                       &LockHandle);

            NextThread = Process->Pcb.ThreadListHead.Flink;
            while (NextThread != &Process->Pcb.ThreadListHead) {
                NextEntryOffset += ThreadInfoSize;
                TotalSize += ThreadInfoSize;

                if (TotalSize > SystemInformationLength) {
                    status = STATUS_INFO_LENGTH_MISMATCH;
                    if (ARGUMENT_PRESENT(Length) == FALSE) {
                        KeReleaseInStackQueuedSpinLock(&LockHandle);
                        leave;
                    }

                } else {
                    Thread = (PETHREAD)(CONTAINING_RECORD(NextThread,
                                                          KTHREAD,
                                                          ThreadListEntry));

                    //
                    // Lock dispatcher database to get atomic view of thread
                    // attributes.
                    //

                    KiLockDispatcherDatabaseAtSynchLevel();
                    ExpCopyThreadInfo (ThreadInfo, Thread, ExtendedInformation);
                    KiUnlockDispatcherDatabaseFromSynchLevel();
                    ProcessInfo->NumberOfThreads += 1;
                    ThreadInfo = (PCHAR) ThreadInfo + ThreadInfoSize;
                }

                NextThread = NextThread->Flink;
            }

            //
            // Unlock kernel process lock and lower IRQL to its previous value.
            //

            KeReleaseInStackQueuedSpinLock(&LockHandle);

            //
            // Get the image name.
            //

            if (Process != PsIdleProcess) {

                //
                // Try to use the real image name if we can that not limited to 16 characters
                //

                Dst = (PWSTR)(ThreadInfo);
                status1 = SeLocateProcessImageName (Process, &pImageFileName);
                if (NT_SUCCESS (status1)) {
                    n = pImageFileName->Length;
                    if (n == 0) {
                        ExFreePool (pImageFileName);
                    }

                } else {
                    n = 0;
                }

                if (n) {
                    SrcW = pImageFileName->Buffer + n / sizeof (WCHAR);
                    while (SrcW != pImageFileName->Buffer) {
                        if (*--SrcW == L'\\') {
                            SrcW = SrcW + 1;
                            break;
                        }
                    }

                    nc = n - (ULONG)(SrcW -  pImageFileName->Buffer) * sizeof (WCHAR);
                    n = ROUND_UP (nc + 1, sizeof(LARGE_INTEGER));
                    TotalSize += n;
                    NextEntryOffset += n;
                    if (TotalSize > SystemInformationLength) {
                        status = STATUS_INFO_LENGTH_MISMATCH;
                        if (ARGUMENT_PRESENT(Length) == FALSE) {
                            ExFreePool (pImageFileName);
                            leave;
                        }
                    } else {
                        RtlCopyMemory (Dst, SrcW, nc);
                        Dst += nc / sizeof (WCHAR);
                        *Dst++ = L'\0';
                    }

                    ExFreePool (pImageFileName);

                } else {
                    Src = Process->ImageFileName;
                    n = (ULONG) strlen ((PCHAR)Src);
                    if (n != 0) {
                        n = ROUND_UP( ((n + 1) * sizeof( WCHAR )), sizeof(LARGE_INTEGER) );
                        TotalSize += n;
                        NextEntryOffset += n;
                        if (TotalSize > SystemInformationLength) {
                            status = STATUS_INFO_LENGTH_MISMATCH;
                            if (ARGUMENT_PRESENT(Length) == FALSE) {
                                leave;
                            }

                        } else {
                            WCHAR c;

                            while (1) {
                                c = (WCHAR)*Src++;
                                *Dst++ =  c;
                                if (c == L'\0') {
                                    break;
                                }
                            }
                        }
                    }
                }

                if (NT_SUCCESS (status)) {
                    ProcessInfo->ImageName.Length = (USHORT)((PCHAR)Dst -
                                                             (PCHAR)ThreadInfo - sizeof( UNICODE_NULL ));

                    ProcessInfo->ImageName.MaximumLength = (USHORT)n;

                    //
                    // Set the image name to point into the user's memory.
                    //

                    ProcessInfo->ImageName.Buffer = (PWSTR)
                                ((PCHAR)SystemInformation +
                                 ((PCHAR)(ThreadInfo) - (PCHAR)MappedAddress));
                }
            }

            //
            // Point to next process.
            //

            if (NT_SUCCESS (status)) {
                ProcessInfo->NextEntryOffset = NextEntryOffset;
            }
        }

        if (NT_SUCCESS(status)) {
            ProcessInfo->NextEntryOffset = 0;
        }

        if (ARGUMENT_PRESENT(Length)) {
            *Length = TotalSize;
        }

    } finally {

        if ((Process != NULL) && (Process != PsIdleProcess)) {
            PsQuitNextProcess (Process);
        }

        if (MappedAddress != NULL) {
            ExUnlockUserBuffer (LockVariable);
        }
    }

    return status;
}
2013-6-7 13:04
0
雪    币: 140
活跃值: (125)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
谢谢啦 哈哈~
2013-6-7 21:25
0
游客
登录 | 注册 方可回帖
返回
//