お互いのカーネルPID_HANDLE_OBJECTの変換

ディアンプロフィール

カーネルでは、一般的に、さまざまなハンドルオブジェクトのIDを使用して、というように。
だから、時々 、あなたはお互いを変換する必要があります。ここに記録されました。

一例として、以下のプロセス。

1.プロセスは、ハンドルへのpid

原理はRING3と同じである。ハンドルを取得するためのプロセスを開くために関数を使用します

コア原則はカーネルを使用することであるZwOpenProcess入ってくるPIDはHANDLEが来ました。

コードは以下の通りであります:

    ULONG pid;
    HANDLE hProcessHandle;
    OBJECT_ATTRIBUTES obj;
    CLIENT_ID clientid;
    //必须初始化
    pid = 2378;
    clientid.UniqueProcess = (HANDLE)pid;
    clientid.UniqueThread = 0;
    InitializeObjectAttributes(&obj, 0, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0);
    ZwOpenProcess(&hProcessHandle, PROCESS_ALL_ACCESS, &obj, &clientid);
        

この時点でProcessHandleで我々はハンドル欲しいもの
ファイルにあなたはZwOpenFileまたはZwCreateFile同様のレジストリを使用することができます。

PIDに2.Handle -------->

独自のPIDに扱うことは、関連するプロセスとAPIを使用する必要があります。

プロセスが使用される** ZwQueryInformationProcess **横断プロセスの基本的な情報は、PIDによって得ることができます

それは文書化されていないの関数であるので注意が、しかし、この機能はカーネルに直接使用することはできませんので、我々は宣言されなければならない。そして、カーネルAPIを使用すると、動的にのみ、この関数のアドレスを取得します

コードは次のとおりです。
宣言と定義を:

typedef NTSTATUS(*PfnZwQueryInformationProcess) (
    __in HANDLE ProcessHandle,
    __in PROCESSINFOCLASS ProcessInformationClass,
    __out_bcount(ProcessInformationLength) PVOID ProcessInformation,
    __in ULONG ProcessInformationLength,
    __out_opt PULONG ReturnLength
    );

PfnZwQueryInformationProcess ZwQueryInformationProcess;

コア実装、ProcessHandleはあなたが得るハンドルです。


PROCESS_BASIC_INFORMATION ProcessBasicInfor;
    //动态获取.
    UNICODE_STRING UtrZwQueryInformationProcessName =
        RTL_CONSTANT_STRING(L"ZwQueryInformationProcess");
    ZwQueryInformationProcess = 
        (PfnZwQueryInformationProcess)MmGetSystemRoutineAddress(&UtrZwQueryInformationProcessName);
    //check...
    //核心代码
    /*
    1.利用PID
    */
    PROCESS_BASIC_INFORMATION ProcessBasicInfor;
    ZwQueryInformationProcess(
        ProcessHndle, 
        ProcessBasicInformation,
        (PVOID)&ProcessBasicInfor,
        sizeof(ProcessBasicInfor),
        NULL);
    /*
    ProcessBasicInfor.UniqueProcessId; 则为你所求
    */

3.Pid ------>オブジェクト(EPROCESS)

EPROCESSへのpidは、原則の下にあると述べました。

原理はであるPsLookUpProcessByProcessId入ってくるPID。発信EPROCESS。

しかし、カーネルは、この機能を使用しています。だから、EPROCESSは、オブジェクト指向の設計に基づいて、カーネル間接参照にあなたが持っている参照カウント+ 1を得るでしょう。だから、APIの間接参照を必要とします

コアのコードは次の通りであります:

PEPROCESS pEpro;
PsLookUpProcessByProcessId((HANDLE)pid,&pEpro);
ObDereferenceObject(pEpro);
PEpro即为你所求.

4. HANDLE -------------> EPROCESS

あなたが最初にすべてのハンドルを取得対応するオブジェクトのオブジェクトにそれを作るときはこれが。カーネルプログラミングでは非常に一般的です。

カーネル関数はまた、私たちを提供します。

次のように:

ObReferenceObjectByHandle(ProcessHandle, GENERIC_ALL,*PsProcessType,KernelMode,&pEprocess,NULL);

5.EPROCESS ---------> pidを

EPROCESSでは、それ自体では...とPID PID直接アクセスの記録です
EPROCESS.UniqueProcessId。

6.EPROCESS ---------> HANDLE

これは一般的なことはありませんでした。しかし、カーネルはまた私達の使用のためのAPIを提供します

ObOpenObjectByPoint(Process,attributes,&AccessState,0,*PsProcessType,PreviousMode,&Handle);

おすすめ

転載: www.cnblogs.com/iBinary/p/11370584.html