欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

关于在Ring0中读取/修改PEB

关于在Ring0中读取/修改PEB

文章很菜,大牛飘过,如有纰漏,欢迎指正。   
上次看到http://bbs.pediy.com/showthread.php?t=69730中的一些回复,说是在驱动中修改PEB是不行的。
我寻思着NtReadProcessMemory/NtWriteProcessMemory读写用户空间也是KeStackAttachProcess到目标进程然后RtlCopyMemory的,所以在驱动中,Attach到目标进程然后读取/写入PEB应该是可行的,许多Ring3的程序不就这么做么?
另外对用户空间的操作应该使用ProbeForRead/ProbeForWrite来检查一下~
本程序省略此步骤。
经过实验,证明是可行的。
代码如下:
//===============================
NTKERNELAPI
NTSTATUS
PsLookupProcessByProcessId(
         HANDLE ProcessId,
         PEPROCESS *Process
         );
NTKERNELAPI
VOID
KeAttachProcess (
     PEPROCESS Process
     );
NTKERNELAPI
VOID
KeDetachProcess (
     VOID
     );

typedef struct _PEB_LDR_DATA {
  ULONG                   Length;
  BOOLEAN                 Initialized;
  PVOID                   SsHandle;
  LIST_ENTRY              InLoadOrderModuleList;
  LIST_ENTRY              InMemoryOrderModuleList;
  LIST_ENTRY              InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct _LDR_DATA_TABLE_ENTRY {
  LIST_ENTRY InLoadOrderLinks;
  LIST_ENTRY InMemoryOrderLinks;
  LIST_ENTRY InInitializationOrderLinks;
  PVOID DllBase;
  PVOID EntryPoint;
  ULONG SizeOfImage;
  UNICODE_STRING FullDllName;
  UNICODE_STRING BaseDllName;
  ULONG Flags;
  USHORT LoadCount;
  USHORT TlsIndex;
  union {
    LIST_ENTRY HashLinks;
    struct {
      PVOID SectionPointer;
      ULONG CheckSum;
    };
  };
  union {
    struct {
      ULONG TimeDateStamp;
    };
    struct {
      PVOID LoadedImports;
    };
  };
  struct _ACTIVATION_CONTEXT * EntryPointActivationContext;
  PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

NTSTATUS ModifyModuleName()
{
  NTSTATUS status;
  PEPROCESS Process;
  ULONG ulPEB;
  PPEB_LDR_DATA pLdr;
  PLDR_DATA_TABLE_ENTRY pLdt = NULL;
  PLIST_ENTRY pList,pHead;
  wchar_t wszFakePath[] = L"0GiNr.com";

  status = PsLookupProcessByProcessId(
    (HANDLE)1356,
    &Process);//exporer.exe的pid
  if ( !NT_SUCCESS(status) ) {
    dprintf("PsLookupProcessByProcessId = 0x%08lX",status);
    return status;
  }
  ObDereferenceObject(Process);
  
  KeAttachProcess(Process);
  dprintf("Process : 0x%08lX. \n",Process);
  ulPEB = *(ULONG *)((ULONG)Process + 0x1B0);
  dprintf("PEB : 0x%08lX. \n",ulPEB);
  
  __try {
    pLdr = *(PPEB_LDR_DATA *)(ulPEB + 0x00C);
    dprintf("Ldr : 0x%08lX. \n",pLdr);
    pHead = pLdr->InLoadOrderModuleList.Flink;
    pList = pHead;
    do {
      pLdt = CONTAINING_RECORD(
        pList,
        LDR_DATA_TABLE_ENTRY,
        InLoadOrderLinks);
      if ( pLdt->EntryPoint && 
        pLdt->FullDllName.Buffer &&
        pLdt->BaseDllName.Buffer &&
        pLdt->DllBase )
      {
        dprintf("FullDllName : %S \n",pLdt->FullDllName.Buffer);
        dprintf("BaseDllName : %S \n",pLdt->BaseDllName.Buffer);
        dprintf("DllBase : 0x%08lX. \n",pLdt->DllBase);
        dprintf("DllSize : 0x%08lX. \n",pLdt->SizeOfImage);
        dprintf("--------------");
        //DllBase : 0x7C800000. 
        if ( (ULONG)pLdt->DllBase == 0x7C800000 ) {
          dprintf("Modify.");
          dprintf("--------------");
          wcscpy(pLdt->FullDllName.Buffer,wszFakePath);
          wcscpy(pLdt->BaseDllName.Buffer,wszFakePath);
                                                            //断链也是可以的。
          /*pLdt->InLoadOrderLinks.Blink->Flink =
            pLdt->InLoadOrderLinks.Flink;
          pLdt->InLoadOrderLinks.Flink->Blink =
            pLdt->InLoadOrderLinks.Blink;
          pLdt->InInitializationOrderLinks.Blink->Flink =
            pLdt->InInitializationOrderLinks.Flink;
          pLdt->InInitializationOrderLinks.Flink->Blink =
            pLdt->InInitializationOrderLinks.Blink;
          pLdt->InMemoryOrderLinks.Blink->Flink =
            pLdt->InMemoryOrderLinks.Flink;
          pLdt->InMemoryOrderLinks.Flink->Blink =
            pLdt->InMemoryOrderLinks.Blink;*/
        }
      }
      pList = pList->Flink;
    } while ( pList != pHead );
  } __except(EXCEPTION_EXECUTE_HANDLER) {
    status = GetExceptionCode();
    dprintf("GetExceptionCode() = 0x%08lX. \n",status );
  }
  KeDetachProcess();
  return status;
}

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功