ReadProcessMemory使用问题

lwdlcb 2008-01-06 12:32:44
BYTE *lpBuf;
lpBuf=(BYTE*)malloc(10);

int i;
for(i=0;i<10;i++){
lpBuf[i]='0'+i;
}

STARTUPINFO si;
memset(&si,0,sizeof(si));
si.cb=sizeof(si);

PROCESS_INFORMATION pi;
memset(&pi,0,sizeof(pi));

TCHAR thrFile[50];
GetModuleFileName(NULL,thrFile,50);

CreateProcess(NULL,thrFile,0,0,false,CREATE_SUSPENDED,0,0,&si,&pi);
HANDLE hProc;
HANDLE hThr;
hProc=pi.hProcess;
hThr=pi.hThread;

CONTEXT ctx;
ctx.ContextFlags=CONTEXT_FULL;
GetThreadContext(hThr,&ctx);

unsigned long lpBase;
ReadProcessMemory(hProc,(void*)(ctx.Ebx+8),&lpBase,sizeof(unsigned long),NULL);

unsigned long (_stdcall *pFun)(unsigned long,unsigned long);
pFun=(unsigned long(_stdcall *)(unsigned long,unsigned long))GetProcAddress(LoadLibrary(L"ntdll.dll"),"ZwUnmapViewOfSection");

pFun((unsigned long)hProc,lpBase);

void *pt;
pt=VirtualAllocEx(hProc,0,10,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
memset(pt,0,10);

unsigned long old;
WriteProcessMemory(hProc,pt,lpBuf,10,&old);

//memmove(pt,lpBuf,10);

for(i=0;i<10;i++)
printf("%d---%d\n",lpBuf[i],*((BYTE *)pt+i));

TerminateProcess(hProc,0);
CloseHandle(hProc);
CloseHandle(hThr);

free(lpBuf);

大家运行一下这个代码,为什么没有将lpBuf的内容拷贝到pt中去呢?
如果使用memmove就可以

...全文
276 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
阿呆_ 2008-01-12
  • 打赏
  • 举报
回复
1, 先确定你的程序对对方进程具有PROCESS_VM_WRITE和PROCESS_VM_OPERATION权限
2, 再确定调用VirtualAllocEx是否成功了
3, 如果调用WriteProcessMemory失败, 察看GetLastError()返回的错误 (先别管对方进程是否弹出错误框)
阿呆_ 2008-01-10
  • 打赏
  • 举报
回复
memcpy, memmove不出错并不表示成功。 只是一种巧合而已, 说明你的进程内相对于对方进程的那个地址已经分配过了, 但并不表示那里就是有效地址(很可能是你进程内其他变量使用的地址, 或者仅仅被你进程内的内存管理单元从系统内分配出来但标记为未使用), 你对那个地址进行写操作出现的后果有很大的可能是破坏了内存管理单元对堆空间的管理, 然后你的程序可能出现莫名其妙的错误(比如某个系统函数运行出错),而且绝对是误导性的错误。
lwdlcb 2008-01-10
  • 打赏
  • 举报
回复
现在
pt=VirtualAllocEx(hProc,10000,10,MEM_COMMIT ¦MEM_RESERVE,PAGE_EXECUTE_READWRITE);

unsigned long old;
WriteProcessMemory(hProc,pt,lpBuf,10,&old); //出错,怎么解决?
lwdlcb 2008-01-09
  • 打赏
  • 举报
回复
ding
阿呆_ 2008-01-08
  • 打赏
  • 举报
回复
注意VirtualAllocEx返回的地址只在对方进程内有效, 不是本进程的有效地址. 所以对它读写需要ReadProcessMemory/WriteProcessMemory, 貌似你memset就不合法了
lwdlcb 2008-01-08
  • 打赏
  • 举报
回复
成功了
阿呆_ 2008-01-08
  • 打赏
  • 举报
回复
你先加上代码判断一下VirtualAllocEx是否成功吧, 如果不成功(== NULL )那么可以用GetLastError看一下到底什么问题
lwdlcb 2008-01-08
  • 打赏
  • 举报
回复
起始地址改为0,pt得到的值并不是0,可以说系统还是自动为其分配了一个值
lwdlcb 2008-01-08
  • 打赏
  • 举报
回复
void *pt=VirtualAllocEx(hProc,(void*)pBase,4096,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
memset(pt,0,4096);

这样就报错了,我已经将起始地址改为进程原地址

但是我如果将起始地址改为0,并使用memmove来赋值就没错,为什么?
阿呆_ 2008-01-08
  • 打赏
  • 举报
回复
调用UnmapViewOfSection的目的就是为了释放原来app占用的地址, 为了能将那个地址(也就是你代码中的lpBase)传递给VirtualAllocEx, 重新分配一块和原始app相同起始地址的内存(因为绝大部分exe的起始地址都是0x00400000(32bit)或者0x0000000100400000(64bit), 重新占用0x00400000作为新exe的基址的话, exe中的代码就不需要重定位了).

另外, 地址不可能小于64k(我记得哪本书上说1M以下地址都被系统保留了, 动态分配只可能得到这个范围以上的地址)。 所以你设默认地址是10明显是错的。 默认地址不可用系统不可能自动给你分配一个, 否则如果某个程序需要加载在某几个特定地址才能运行的话就没办法处理了, 比如第一个默认地址已经被用了, 程序必须知道加载失败并且尝试加载到第二个默认地址运行, 如果此时你不返回失败确随便分配了一个地址并且返回成功的话... ?
lwdlcb 2008-01-08
  • 打赏
  • 举报
回复
不对,memmove就可以,为什么?
而且现在的问题就是使用WriteProcessMemory不能往该空间内写东西
lwdlcb 2008-01-07
  • 打赏
  • 举报
回复
ding
lwdlcb 2008-01-07
  • 打赏
  • 举报
回复
还有,VirtualAllocEx(hProc,10,100000000,MEM_COMMIT¦MEM_RESERVE,PAGE_READWRITE);
只要设置了第二个参数,那么在该空间写入内容就回出错
阿呆_ 2008-01-07
  • 打赏
  • 举报
回复
我遇到过这问题, 改成VirtualAllocEx(hProc,0,100000000,MEM_COMMIT ¦MEM_RESERVE,PAGE_READWRITE); 就能够分配成功了, 然后用VirtualProtectEx修改保护成PAGE_EXECUTE_READWRITE;
lwdlcb 2008-01-07
  • 打赏
  • 举报
回复
ding
lwdlcb 2008-01-07
  • 打赏
  • 举报
回复
VirtualAllocEx返回值不为空
第二个参数一旦设置,就会报错,应该是使用了不能使用的地址,但是我的理解是:如果默认起始地址不可用,那它应该自动分配一个地址呀,为什么就会出错呢
阿呆_ 2008-01-07
  • 打赏
  • 举报
回复
第二个参数是默认起始地址吧? 第三个参数才是分配长度。 起始地址如果为0(NULL)则表明让系统自己决定合适的地址进行分配, 否则必须位于4k页边界, 也就是说必须能够整除4096, 而且对方进程内这个地址没有被使用, 否则分配失败。 所以用VirtualAlloc或VirtualAllocEx分配必须判断是否成功(返回值是否不为空)
另外分配长度最好也是4k的倍数(只是一个建议), 因为哪怕你只分配1个字节, 底层也是1页(4096字节)
lwdlcb 2008-01-07
  • 打赏
  • 举报
回复
ding
lwdlcb 2008-01-06
  • 打赏
  • 举报
回复
ding
lwdlcb 2008-01-06
  • 打赏
  • 举报
回复
不是吧
pt=VirtualAllocEx(hProc,0,100000000,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
也不行呀
加载更多回复(1)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧