zoukankan      html  css  js  c++  java
  • 驱动编程:NtReadVirtualMemory

    NtReadVirtualMemory函数位于ntdll中,作用就是把用户态的函数调用翻译成相应的系统调用,进入内核态。内核中一般有一个相同名字的处理函数,接收到该类型的系统调用后做实际的工作。

    NTSTATUS STDCALL NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN ULONG NumberOfBytesToRead, OUT PULONG NumberOfBytesRead) { NTSTATUS Status; PMDL Mdl; PVOID SystemAddress; PEPROCESS Process; DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, " "Buffer %x, NumberOfBytesToRead %d) ",ProcessHandle,BaseAddress, Buffer,NumberOfBytesToRead); Status = ObReferenceObjectByHandle(ProcessHandle, PROCESS_VM_WRITE, NULL, UserMode, (PVOID*)(&Process), NULL);
     
       if (Status != STATUS_SUCCESS)
       {
          return(Status);
       }

    }
    struct _EPROCESS
    {
      /* Microkernel specific process state. */
      KPROCESS Pcb;
    }
    typedef struct _KPROCESS 
    {
      DISPATCHER_HEADER 	DispatcherHeader;             /* 000 */
      LIST_ENTRY            ProfileListHead;              /* 010 */
      PHYSICAL_ADDRESS      DirectoryTableBase;           /* 018 这是cr3*/
    }
       Mdl = MmCreateMdl(NULL,Buffer, NumberOfBytesToRead);
        MmProbeAndLockPages(Mdl,UserMode,IoWriteAccess);
      KeAttachProcess(Process);
      SystemAddress = MmGetSystemAddressForMdl(Mdl);
       memcpy(SystemAddress, BaseAddress, NumberOfBytesToRead);
      KeDetachProcess();
      if (Mdl->MappedSystemVa != NULL)
       {
          MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
       }
       MmUnlockPages(Mdl);
       ExFreePool(Mdl);
    
       ObDereferenceObject(Process);
    
       *NumberOfBytesRead = NumberOfBytesToRead;
       return(STATUS_SUCCESS);
    }
     memcpy(Buffer, BaseAddress, NumberOfBytesToRead);
    VOID STDCALL
    KeAttachProcess (PEPROCESS Process)
    {
       KIRQL oldlvl;
       PETHREAD CurrentThread;
       PULONG AttachedProcessPageDir;
       ULONG PageDir;
       
       DPRINT("KeAttachProcess(Process %x)
    ",Process);
       
       CurrentThread = PsGetCurrentThread();
    
       if (CurrentThread->OldProcess != NULL)
         {
    	DbgPrint("Invalid attach (thread is already attached)
    ");
    	KEBUGCHECK(0);
         }
       
       KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
    
       KiSwapApcEnvironment(&CurrentThread->Tcb, &Process->Pcb);
     /* The stack of the current process may be located in a page which is
          not present in the page directory of the process we're attaching to.
          That would lead to a page fault when this function returns. However,
          since the processor can't call the page fault handler 'cause it can't
          push EIP on the stack, this will show up as a stack fault which will
          crash the entire system.
          To prevent this, make sure the page directory of the process we're
          attaching to is up-to-date. */
    
       AttachedProcessPageDir = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase);
       MmUpdateStackPageDir(AttachedProcessPageDir, &CurrentThread->Tcb);
       ExUnmapPage(AttachedProcessPageDir);
     CurrentThread->OldProcess = PsGetCurrentProcess();
       CurrentThread->ThreadsProcess = Process;
       PageDir = Process->Pcb.DirectoryTableBase.u.LowPart;
       DPRINT("Switching process context to %x
    ",PageDir);
       Ke386SetPageTableDirectory(PageDir);
       KeLowerIrql(oldlvl);
    }
  • 相关阅读:
    关于工作流的思考
    RssBandit.net应用示例(RSS聚集器)[暂未完成]
    前端是否应该将css和js分开设置两个不同岗位
    初中级工程师是否应急于学习html5?
    招聘条件中的学历问题
    禁止拖动屏幕
    html5全屏api
    html5兼容陷阱合集
    borderimage试用心得
    web app的一些特殊meta和link标签
  • 原文地址:https://www.cnblogs.com/alsofly/p/3734814.html
Copyright © 2011-2022 走看看