Как получить доступ к памяти режима пользователя? - PullRequest
5 голосов
/ 11 июня 2011

Я пытаюсь прочитать PEB notepad.exe В настоящее время я пытаюсь получить доступ к PEB, регистрируя обратный вызов ProcessCreation и затем ожидая, пока не будет создан notepad.exe. Когда блокнот создан, я использую его PID, чтобы открыть процесс и найти PEB с ZwQuerryProcess (PROCESS_BASIC_INFORMATION).

Но когда я пытаюсь прочитать за пределами INFORMATION-> PEB, возникает исключение (я полагаю, это потому, что я не могу получить доступ к памяти)

Когда я впервые обнаружил это, я вспомнил, как кто-то упоминал KeStackAttachProcess и его аналог для доступа к адресам внутри другого контекста процесса.

Проблема в том, что я не знаю, как проверить, было ли изменение контекста успешным или нет. И как только я якобы нахожусь в другом контексте, я все еще не могу получить доступ к peb. Кто-нибудь знает, как я могу получить доступ к PEB блокнота?

Вот код, который я сейчас использую для поиска и доступа к PEB:

Предположим, hgtPid = PID блокнота

void ModuleDumperThread(){

NTSTATUS Status = STATUS_SUCCESS;
HANDLE hProcessHandle = NULL;
PLIST_ENTRY Next;
PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
CLIENT_ID clientID; 
ACCESS_MASK DesiredAccess = PROCESS_ALL_ACCESS;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hProcessId = hgtPid;
PROCESS_BASIC_INFORMATION BasicInfoReal;
ULONG SizeReturned;

PEPROCESS ep;
KAPC_STATE *ka_state = NULL;


InitializeObjectAttributes (&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

   clientID.UniqueProcess = hProcessId;  
   clientID.UniqueThread = NULL; 

__try{


Status = ZwOpenProcess(&hProcessHandle, DesiredAccess, &ObjectAttributes, &clientID);

                if(Status != STATUS_SUCCESS){
                        DbgPrint("Failed to open process\n");
                        DbgPrint("NtStatus: 0x%x", Status);
                        return;
                }

            Status = gZwQueryprocess(hProcessHandle, ProcessBasicInformation, (PVOID)&BasicInfoReal, sizeof(PROCESS_BASIC_INFORMATION), &SizeReturned);

                    if(Status != STATUS_SUCCESS){
                                DbgPrint("gZwQueryprocess failed\n");
                                DbgPrint("Size returned: 0x%x\nNtStatus: 0x%x\n", SizeReturned, Status);
                                ZwClose(hProcessHandle);
                                return;
                    }

            ZwClose(hProcessHandle);        

        Status = PsLookupProcessByProcessId(hProcessId, &ep);

                    if(Status != STATUS_SUCCESS){
                                DbgPrint("PsLookupProcessByProcessId failed\n");
                                DbgPrint("NtStatus: 0x%x\n", Status);
                                return;
                    }

ka_state = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC_STATE),'trak');

            KeStackAttachProcess(ep, ka_state);

__try{

                if(BasicInfoReal.PebBaseAddress->Ldr){

                           Next = BasicInfoReal.PebBaseAddress->Ldr->InLoadOrderModuleList.Blink;
                           LdrDataTableEntry = CONTAINING_RECORD( Next,
                                                                  LDR_DATA_TABLE_ENTRY,
                                                                  LoadOrder
                                                                );
                    DbgPrint("Module base address: 0x%x", LdrDataTableEntry->ModuleBaseAddress);
                } 
    }__except( EXCEPTION_EXECUTE_HANDLER ) {
        DbgPrint("Exception while trying to access the PEB\n");
       }

            KeUnstackDetachProcess(ka_state);
            ExFreePool(ka_state);


}__except( EXCEPTION_EXECUTE_HANDLER ) {
                DbgPrint("Exception in ModuleDumper\n");
        }

              if(ep){
                ObDereferenceObject(ep);        
              } 
return;
}

Кто-нибудь замечает какие-либо ошибки / неисправности?

Заранее спасибо

EDIT:

Я кое-что изменил, и вот тут это становится действительно странным. Чтобы быть уверенным, что я изменил 'ep' KeStackAttachProcess () на msdn, обозначенный тип PRKPROCESS, когда я вызываю KeStackAttachProcess (), теперь выполнение просто исчезает. До звонка все идет хорошо, после звонка просто ничего нет. Нет ошибок, нет исключений, нет BSOD: ничего. Что происходит?!?

Изменения:

    __asm{
        mov eax, ep
        mov eax, [eax]
        mov myPKPROCESS, eax  // just dereferencing my pointer (I don't have the structs)
    }

  DbgPrint("Test print\n");   // gets printed just fine

            KeStackAttachProcess(&myPKPROCESS, ka_state); 
DbgPrint("Test print\n");  // nothing happens

EDIT2:

Я решил проблему. Я все еще не знаю, что пошло не так в приведенном выше коде, однако этот код работает:

void ModuleDumperThread(){

NTSTATUS Status = STATUS_SUCCESS;
HANDLE hProcessHandle = NULL;
PLIST_ENTRY Next;
PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
CLIENT_ID clientID; 
ACCESS_MASK DesiredAccess = PROCESS_ALL_ACCESS;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hProcessId = hgtPid;
PROCESS_BASIC_INFORMATION BasicInfoReal;
ULONG SizeReturned;
PEPROCESS ep = NULL;
unsigned int Index = 0;
InitializeObjectAttributes (&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

   clientID.UniqueProcess = hProcessId;  
   clientID.UniqueThread = NULL; 


__try{

    Status = ZwOpenProcess(&hProcessHandle, DesiredAccess, &ObjectAttributes, &clientID);

                if(Status != STATUS_SUCCESS){
                        DbgPrint("Failed to open process\n");
                        DbgPrint("NtStatus: 0x%x", Status);
                        return;
                }

            Status = gZwQueryprocess(hProcessHandle, ProcessBasicInformation, (PVOID)&BasicInfoReal, sizeof(PROCESS_BASIC_INFORMATION), &SizeReturned);

                    if(Status != STATUS_SUCCESS){
                                DbgPrint("gZwQueryprocess failed\n"); 
                                DbgPrint("Size returned: 0x%x\nNtStatus: 0x%x\n", SizeReturned, Status);
                                ZwClose(hProcessHandle);
                                return;
                    }

    //DbgPrint("Basic info: 0x%x\n", BasicInfoReal);
    //DbgPrint("BasicInfoReal->PebBaseAddress: 0x%x\n", BasicInfoReal->PebBaseAddress);
    //DbgPrint("RealPeb: 0x%x\n", RealPeb);
    //DbgPrint("gZwReadVirtualMemory: 0x%x\n", gZwReadVirtualMemory);

                    Status = PsLookupProcessByProcessId(hProcessId, &ep);

                    if(Status != STATUS_SUCCESS){
                                DbgPrint("PsLookupProcessByProcessId failed\n");
                                DbgPrint("NtStatus: 0x%x\n", Status);
                                ZwClose(hProcessHandle);
                                return;
                    }
Timeout((INT64)0x1FFFFFF);

KeAttachProcess(ep);
__try{
   DbgPrint("ImageBaseAddress of notepad.exe: 0x%x\n", BasicInfoReal.PebBaseAddress->ImageBaseAddress);

    Next = BasicInfoReal.PebBaseAddress->Ldr->InLoadOrderModuleList.Blink;
    LdrDataTableEntry = CONTAINING_RECORD( Next, LDR_DATA_TABLE_ENTRY, LoadOrder);


    for(Index = 0; Index != 17; Index++){
       DbgPrint("%d: ImageBase of %wZ in Notepad.exe: 0x%x\n", Index, &(LdrDataTableEntry->ModuleName), LdrDataTableEntry->ModuleBaseAddress);
       Next = Next->Blink;
       LdrDataTableEntry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, LoadOrder);
    }


   }__except( EXCEPTION_EXECUTE_HANDLER ) {
                DbgPrint("Exception while accessing the LDR\n");
        }

KeDetachProcess();

    }__except( EXCEPTION_EXECUTE_HANDLER ) {
                DbgPrint("Exception in ModuleDumper\n");
        }
        ObDereferenceObject((PVOID)ep);
        ZwClose(hProcessHandle);    


return;
}

Ответы [ 2 ]

2 голосов
/ 15 июня 2011

Вы можете использовать PPEB PsGetProcessPeb ( IN PEPROCESS Process ). Вам нужно использовать MmGetSystemRoutineAddress, чтобы получить адрес этого API. Взгляните на функцию GetDllByPeb в этом файле: http://code.google.com/p/arkitlib/source/browse/trunk/ARKitDrv/Ps.c

0 голосов
/ 17 июля 2014

Это ваш PsGetProcessPeb:

/base/ntos/ps/pshelper.c

PPEB
PsGetProcessPeb(
    __in PEPROCESS Process
    )
{
    return Process->Peb;
}

Нет необходимости выполнять дополнительную работу для извлечения указателя PEB из структуры EPROCESS (что очень похожедля всех версий Windows, кроме 32/64-bit разница)

И вы можете получить EPROCESS на PsLookupProcessByProcessId, используя ID=4 (системный процесс).

...