fre*_*ngs 2 c c++ memory winapi
我的代码.
int main()
{
HANDLE hTargetHandle;
int TargetProcessId=GetTargetProcessId();
hTargetHandle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,TargetProcessId);
if(hTargetHandle==INVALID_HANDLE_VALUE)
{
DWORD d=GetLastError();
printf("openprocess fail\n");
printf("the TargetProcessId is: %d\n",TargetProcessId);
printf("the result of getlast is: %d\n",d);
system("PAUSE");
exit(-1);
}
DWORD dwBufferSize=(DWORD)GetTargetProcessId-(DWORD)create;
DWORD dwProcBaseAddress=(DWORD)VirtualAllocEx(hTargetHandle,NULL,1024*1024,MEM_COMMIT,PAGE_EXECUTE_READWRITE); //the size here is 1024*1024,I don't know the size of the function I am going to inject to another process,so I use 1024*1024 here.I have ever tried to use 1024*1024*10,but it is the same error.
if(dwProcBaseAddress==NULL)
{
DWORD d=GetLastError();
printf("virtualallocex has fail\n");
printf("the last error is:%d\n",d);
system("PAUSE");
exit(-1);
}
int a=WriteProcessMemory(hTargetHandle,&dwProcBaseAddress,create,1024*1024,NULL); //create is a function I defined,used to inject to another process.
if(a==0)
{
DWORD d=GetLastError();
printf("writeprocessmemory has fail\n");
printf("the last error is %d\n",d);
system("PAUSE");
exit(-1);
}
DWORD dwThreadId;
HANDLE hRemoteThreadHandle=CreateRemoteThread(hTargetHandle,NULL,NULL,(LPTHREAD_START_ROUTINE)dwProcBaseAddress,NULL,0,&dwThreadId);
if(hRemoteThreadHandle!=INVALID_HANDLE_VALUE)
{
printf("succeed\n");
system("PAUSE");
exit(-1);
}
system("PAUSE");
return 1;
}
Run Code Online (Sandbox Code Playgroud)
结果如下.WriteProcessMemory函数失败,错误487,表示地址无效.

但是地址是VirtualAllocEx函数的返回值,返回值不为null,因此地址应该可用.我不知道问题出在哪里.
遇到错误代码时,请查找.它在此处记录:https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382.aspx.你有487,是ERROR_INVALID_ADDRESS.相关描述是:
尝试访问无效地址.
所以,让我们深入挖掘.如果地址无效,可能是什么?传递给函数的两个地址位于第二个和第三个参数中.当然第一个,lpBaseAddress是错的.您打算传递您分配的内存的地址.而是传递包含该地址的变量的地址.
我怀疑你的部分问题是你错误的类型转换.VirtualAllocEx回报LPVOID.转换DWORD为32位进程可能没问题,但肯定不适用于64位进程.但是你为什么要施展呢?LPVOID正是你需要传递给你的东西WriteProcessMemory.您的代码中充斥着错误的强制转换.作为一个广泛的规则,对你的方式进行类型转换是一种代码气味,表明存在错误.按照您的方式进行转换会阻止编译器键入检查代码.
这是应该声明基址变量的方式:
LPVOID lpBaseAddress = VirtualAllocEx(...);
Run Code Online (Sandbox Code Playgroud)
然后当你打电话时WriteProcessMemory,传递那个变量:
BOOL retval = WriteProcessMemory(..., lpBaseAddress, ...);
Run Code Online (Sandbox Code Playgroud)
我不知道为什么你用int变量来捕获返回值WriteProcessMemory.文档将其作为BOOL.这传达了语义.您还可以使用intPID.PID具有类型DWORD.
不知道你的功能的长度可能是一个问题.如果你不能读取1024*1024超出的字节create怎么办?
程序中的缺陷很简单.你传了错误的地址.但是,我认为你需要退一步.不要只是修复那个缺陷并继续前进.您真的需要花一些时间来了解Win32 API使用的类型.除非你戒掉这个习惯,否则你的肆意强制转变会一次又一次地伤害你.
| 归档时间: |
|
| 查看次数: |
563 次 |
| 最近记录: |