- 注册时间
 - 2010-7-27
 
- 最后登录
 - 2017-5-30
 
- 在线时间
 - 3 小时
 
 
 
 
 
编程入门 
  
	- 魔鬼币
 - 2281 
 
 
 
 | 
 
    这里只是简单的实现下读取进程空间的数据...写操做也是一样的....比较简单... 
 
    这样你就可以在内核读用户空间了....哈哈 
 
    大家都知道在用户态我们常用 kernel32.dll中的ReadProcessMemory来读取进程...这个函数只是简单地对传入的参数进行处理然后调用了 ntdll.dll中的NtReadVirtualMemory/ZwReadVirtualMemory....ntdll中这俩个函数并没有什么区别...不过在内核就不一样了.....ntdll.dll中的NtReadVirtualMemory简单的把系统服务号放进EAX..然后调用某个地址的处理程序...处理程序实现用户和内核的切换...接着内核调用了内核态的NtReadVirtualMemory......NtReadVirtualMemory中又掉用了MmCopyVirtualMemory...接着难免少不了函数KeStackAttachProcess..这里我们用它来实现自己的NtReadVirtualMemory...只是简单的...我也没对一些错误进行处理....  
 
   ULONG MyReadMemory(IN PVOID BaseAddress,IN SIZE_T BufferSize,IN HANDLE pid) 
 
   BaseAddress---------->>>>你想读进程开始的地址 
   BufferSize ---------->>>>你想读取多少个字节的数据 
   pid------------------>>>>你想读取的进程的PID值 
 
   注:一般PID比进程名好..虽然进程名可以从EPROCESS中得到..但PID总是唯一的.所以这个参数我用 PID而不是进程名   
 
ULONG MyReadMemory(IN PVOID BaseAddress,IN SIZE_T BufferSize,IN HANDLE pid) 
{ 
PEPROCESS EProcess; 
KAPC_STATE ApcState; 
PVOID readbuffer; 
NTSTATUS status; 
 
status = PsLookupProcessByProcessId((HANDLE)pid,&EProcess); 
if(!NT_SUCCESS(status)) 
{ 
   DbgPrint("failed to get the EPROCESS!!/n"); 
   return 0; 
} 
 
readbuffer = ExAllocatePoolWithTag (NonPagedPool, BufferSize, 'Sys'); 
if(readbuffer==NULL) 
{ 
   DbgPrint("failed to alloc memory!/n"); 
   return 0; 
} 
 
*(ULONG*)readbuffer=(ULONG)0x1; 
 
KeStackAttachProcess (EProcess, &ApcState); 
 
       __try  
    { 
     ProbeForRead ((CONST PVOID)BaseAddress, BufferSize, sizeof(CHAR)); 
           RtlCopyMemory (readbuffer, BaseAddress, BufferSize); 
     KeUnstackDetachProcess (&ApcState); 
     
    } __except(EXCEPTION_EXECUTE_HANDLER) 
    { 
     KeUnstackDetachProcess (&ApcState); 
    } 
     
    DbgPrint("%x/n",*(ULONG*)readbuffer); 
    ExFreePool (readbuffer); 
    return 1; 
     
} 
 
实例:   MyReadMemory((PVOID)0x7c944000,0x4,(HANDLE)904); 
 |   
 
 
 
 |