跨进程内存读取,附源码_第1页
跨进程内存读取,附源码_第2页
跨进程内存读取,附源码_第3页
跨进程内存读取,附源码_第4页
跨进程内存读取,附源码_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、【原创】跨进程内存读取, 附源码标 题:【原创】跨进程内存读取, 附源码作 者:stnoe时 间: 2009-06-26,21:24:18 链 接: http:/ 在科锐学习的第4 阶段 , 保护模式课后作业, 跨进程内存读写的小工具. 第一次内核编程 , 代码写的比较乱 , 不免也有些错误. 各位牛哥们 , 见笑乐 ,! 时间仓促 , 也没对代码进程封装,和界面相关太多 . 1. 切换目标进程的cr3 通常 , 跨进程读写内存 , 用到 readprocessmemory, writeprocessmemory, 但需要进程句柄, 如果目标进程受到保护 , 可能获得进程句柄会失败. read

2、processmemory最后会调用到kestackattachprocess附加到目标进程上切换进程环境进行拷贝的, 所以想到拿到目标进程的虚拟内存内容, 可以将目标进程的页目录基地址放入cr3中即可 . 首先要获得目标进程的cr3 寄存器 , 即页目录基地址 ( 开启 pae, 页目录指针表 ), 每个进程在内核里都有一个eprocess 结构. 代码 : nt!_eprocess +0 x000 pcb : _kprocess +0 x06c processlock : _ex_push_lock +0 x070 createtime : _large_integer +0 x078 e

3、xittime : _large_integer +0 x080 rundownprotect : _ex_rundown_ref . pcb 中就有我们想要得到的cr3 代码 : nt!_kprocess +0 x000 header : _dispatcher_header +0 x010 profilelisthead : _list_entry +0 x018 directorytablebase : 2 uint4b +0 x020 ldtdescriptor : _kgdtentry +0 x028 int21descriptor : _kidtentry 那只需要获得目标进程ep

4、rocess 就可以得到 cr3了遍历 eprocess 里的 activeprocesslinks 的链表获取指定进程的eprocess 代码 : / 获得当前进程 eprocess信息 ulong ueprocess = 0; _asm mov eax, fs:0 x124 / _ethread mov eax, eax+0 x44 / _kprocess mov ueprocess, eax kdprint(eprocess: 0 x%08xn, ueprocess); list_entry listhead; initializelisthead(&listhead); ulo

5、ng ufirsteprocess = ueprocess; ulong ucount = 0; plist_entry pactiveprocesslinks; processinfolist *pprocsslist = null; ulong unameoffset = getplantformdependentinfo(file_name_offset); ulong upidoffset = getplantformdependentinfo(process_id_offset); ulong ulinkoffset = getplantformdependentinfo(proce

6、ss_link_offset); ulong uexittime = getplantformdependentinfo(exit_time_offset); / 遍历链表获得进程信息 do pprocsslist= (processinfolist *)exallocatepool(pagedpool, sizeof(processinfolist); if (pprocsslist = null) status = status_insufficient_resources; break; plarge_integer exittime; exittime = (plarge_intege

7、r)(ueprocess + uexittime); if (exittime-quadpart = 0) if (*(int *)(ueprocess + upidoffset) procinfo.uprocessid = 0; pprocsslist-procinfo.ueprocess = ueprocess; pprocsslist-procinfo.ucr3 = *(pulong)(ueprocess + 0 x18); rtlcopymemory(pprocsslist-procinfo.pszimagefilename, idle, 16); insertheadlist(&am

8、p;listhead, &pprocsslist-listentry); kdprint(pid: %d, eprocess: 0 x%08x, filename: %s, cr3: 0 x%08xn, pprocsslist-procinfo.uprocessid, pprocsslist-procinfo.ueprocess, pprocsslist-procinfo.pszimagefilename, pprocsslist-procinfo.ucr3); else pprocsslist-procinfo.ueprocess = ueprocess; pprocsslist-p

9、rocinfo.ucr3 = *(pulong)(ueprocess + 0 x18); pprocsslist-procinfo.uprocessid = *(pulong)(ueprocess + upidoffset); rtlcopymemory(pprocsslist-procinfo.pszimagefilename, (pvoid)(ueprocess + unameoffset), 16); insertheadlist(&listhead, &pprocsslist-listentry); kdprint(pid: %d, eprocess: 0 x%08x,

10、 filename: %s, cr3: 0 x%08xn, pprocsslist-procinfo.uprocessid, pprocsslist-procinfo.ueprocess, pprocsslist-procinfo.pszimagefilename, pprocsslist-procinfo.ucr3); ucount+; pactiveprocesslinks = (plist_entry)(ueprocess + ulinkoffset); ueprocess = (ulong)pactiveprocesslinks-blink - ulinkoffset; if (uep

11、rocess = ufirsteprocess) break; while (ueprocess != 0); 引用了北极星2003 大哥的 getplantformdependentinfo 获取 eprocess 的成员偏移下面是读写内存的: 代码 : _try writememoryinfo *pinfo = (writememoryinfo *)exallocatepool(pagedpool, sizeof(writememoryinfo); rtlcopymemory(pinfo, piobuffer, sizeof(writememoryinfo); pvoid pwrite =

12、 exallocatepool(pagedpool, pinfo-nwritesize); rtlcopymemory(pwrite, pinfo-pdata, pinfo-nwritesize); /pinfo-pdata = (pbyte)exallocatepool(pagedpool, pinfo-nwritesize); ulong uoldcr3 = 0; ulong ucurrentcr3 = *(pulong)(pinfo-neprocess + 0 x18); if (pinfo-nmemoryaddr = 0) status = status_unsuccessful; b

13、reak; _asm mov eax, cr3 mov uoldcr3, eax mov eax, ucurrentcr3 mov cr3, eax _asm cli push eax mov eax, cr0 and eax, not 10000h mov cr0, eax rtlcopymemory(pvoid)pinfo-nmemoryaddr, pwrite, pinfo-nwritesize); _asm mov eax, cr0 or eax, 10000h mov cr0,eax pop eax sti _asm mov eax, uoldcr3 mov cr3, eax uou

14、tsize = pinfo-nwritesize; if (pinfo != null) exfreepool(pinfo); pinfo = null; / return success status = status_success; _except(1) status = status_unsuccessful; 代码 : _try readmemoryinfo *pinfo = (readmemoryinfo *)exallocatepool(pagedpool, sizeof(readmemoryinfo); rtlcopymemory(pinfo, piobuffer, sizeo

15、f(readmemoryinfo); ulong uoldcr3 = 0; ulong ucurrentcr3 = *(pulong)(pinfo-neprocess + 0 x18); if (pinfo-nmemoryaddr = 0) status = status_unsuccessful; break; _asm mov eax, cr3 mov uoldcr3, eax mov eax, ucurrentcr3 mov cr3, eax rtlcopymemory(piobuffer, (pvoid)pinfo-nmemoryaddr ,pinfo-nreadsize); uout

16、size = pinfo-nreadsize; _asm mov eax, uoldcr3 mov cr3, eax if (pinfo != null) exfreepool(pinfo); pinfo = null; / return success status = status_success; _except(1) status = status_unsuccessful; 2. 根据分页机制 , 进行手工转换 , 得到虚拟地址的映射的物理地址, 读其物理地址得到目标进程虚拟地址的内容 . 详见附件分析 . 获得了 cr3, 接下来 , 就是根据分页机制, 把虚拟地址转换为物理地址勒

17、. 在转换之前要判断是否开启pae,非 pae和开启 pae的转换有所不同控制寄存器 cr4的第 5 位标记是否开启pae 代码 : / 获得 cr4的值_asm _emit 0 x0f _emit 0 x20 _emit 0 xe0 mov ucr4, eax 未开启 pae情况通过 cr3寄存器定位到页目录的基地址线性地址的高10 位作为获取页目录表项的索引, 获得一个页目录的一个表项注: windows的保护实现基本不使用分段机制, 主要是通过分页机制来实现保护, 这里的就线性地址等于虚拟地址 . 代码 : / 获得页目录表项 (pde) dwpagedirindex = (dwvirt

18、ualaddr & 0 xffc00000) 22; dword dwpagedirentry = readpagedirentrynopae(dwpagedirindex); if (dwpagedirentry = 0) return; 根据 pde获得页表基地址或者页基地址当没有开启 pae时, 有两种 pde格式 , 分别指向 4kb的页表 , 和 4mb的内存页页目录项的第7 位判断页大小代码 : / 获得页大小dword creadmemorydlg:getpagesizenopae(dword dwaddr) if (dwaddr & 0 x00000080) =

19、 0 x00000080) return mbsize; else return kbsize; 4kb时, 页目录项的高20 位为页表基地址 . 线性地址的12 位到 21 位作为选取页表的一个表项.(pte) 代码 : dwpagetableindex = (dwvirtualaddr & 0 x0003ff000) 12; dword dwpagetablebaseaddr = dwpagedirentry & 0 xfffff000; / 获得页表dword dwpagetable = readpagetablenopae(dwpagetablebaseaddr, dw

20、pagetableindex); if (dwpagetable = 0) return; if (ispresentnopae(dwpagetable) = false) return; 取 pte的高 20 位, 作为内存页的基地址, 线性地址的低12 作为页中偏移得到物理地址代码 : / 页的基地址dword dwpagebaseaddr = dwpagetable & 0 xfffff000; dwpageoffset = dwvirtualaddr & 0 x00000fff; 这时获得的物理地址就是想要的目标进程虚拟地址的映射的物理地址代码 : pvoid prea

21、dbuf = new bytedwreadsize; bool bret = readpagememorynopae(preadbuf, dwpageoffset, dwreadsize, dwpagebaseaddr); if (bret = false) return; 4mb时, 页目录项的高10 位作为页的基地址, 线性地址的低22 位在物理地址在页中的偏移代码 : / 线性地址的低 22 位是页内偏移dword dwpageoffsetmb = dwvirtualaddr & 0 x003fffff; / 高 10 位, 是页基地址dword dwpagebaseaddr =

22、 dwpagedirentry & 0 xffc00000; 这时获得的物理地址就是想要的目标进程虚拟地址的映射的物理地址代码 : pvoid preadbuf = new bytedwreadsize; bool bret = readpagememorypae(preadbuf, dwpageoffsetmb, dwreadsize, dwpagebaseaddr); if (bret = false) return; 开启 pae情况cr4中的物理地址扩展(pae)标志可以开启pae机制 , 将物理地址从32 位扩展到 36 位. 当开始 pae机制后 , 处理器支持两种尺寸的页

23、:4kb 和 2mb的页 . 增加了页目录指针表项. 表项的大小从32 位增加到了64 位表项中的物理基地址扩展到了24 位寄存器 cr3中的高位页目录基地址被换为27 位的页目录指针表基地址通过 cr3寄存器定位到页目录指针表起始地址,取线性地址的高2 位作为选取页目录指针表项的索引代码 : dword dwdirpointertableindex = (dwvirtualaddr & 0 xc0000000) 30; dword dwdirpointertablebaseaddr = m_ndirbase & 0 xffffffe0; / 获得页目录指针表_int64 np

24、agedirpointertable = readpagedirpae(dwdirpointertableindex, dwdirpointertablebaseaddr); if (npagedir = 0) return; 取线性地址的第21 位到 29 位作为页目录索引,页目录指针表项的第12 位到第 35 位为页目录基地址代码 : / 页目录基地址dword dwdirbaseaddr = (dword)(npagedirpointertable &0 x0000000ffffff000); / 页目录项索引dword dwpagedirindex = (dwvirtualad

25、dr & 0 x3fe00000) 21; _int64 npagedirentry = readpagedirentrypae(dwpagedirindex, dwdirbaseaddr); if (npagedirentry = 0) return; 根据页目录项的第7 位判断页大小 ,2mb, 还是 4kb 代码 : / 获得页大小dword creadmemorydlg:getpagesizepae(_int64 naddr) if (naddr & 0 x0000000000000080) = 0 x0000000000000080) return mbsize; else return kbsize; 4kb时,页目录项的第12位到 35位作为页表基地址的高24 位. 取线性地址第12 位到 20 位作为在页表中的偏移代码 : / 获得页表dword dwpagetablebaseaddr = (dword)(npagedirentry & 0 x0000000ffffff000); dword dwpagetableindex = (dwvirtualaddr & 0 x001ff000) 12; _int64 n

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论