• 驱动编程: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);
    }
  • 相关阅读:
    文件管理
    字符编码
    字典练习,统计字符串中单词出现次数
    字典有关练习:购物车
    列表及列表操作方法
    字符串及用法
    变量,程序交互,基本数据类型
    /usr/bin/ld: i386:x86-64 architecture of input file `command.o' is incompatible with i386 output
    混合云存储系统开发总结
    小记6月27
  • 原文地址:https://www.cnblogs.com/alsofly/p/3734814.html
Copyright © 2020-2023  润新知