我的代码。
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;
}
以下是结果。 WriteProcessMemory
函数失败,错误487,表示地址无效。
但是地址是VirtualAllocEx
函数的返回值,返回值不为null,因此地址应该可用。我不知道问题出在哪里。
答案 0 :(得分:6)
遇到错误代码时,请查找。这里记录了: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(...);
然后当你致电WriteProcessMemory
时,传递该变量:
BOOL retval = WriteProcessMemory(..., lpBaseAddress, ...);
我不知道你为什么使用int
来获取变量来捕获WriteProcessMemory
的返回值。文档将其作为BOOL
。这传达了语义。您还可以使用int
作为PID。 PID的类型为DWORD
。
不知道你的功能长度可能是个问题。如果您无法阅读1024*1024
以外的create
个字节,该怎么办?
程序中的缺陷很简单。你传了错误的地址。但是,我认为你需要退一步。不要只是修复那个缺陷并继续前进。您真的需要花一些时间来了解Win32 API使用的类型。除非你戒掉这个习惯,否则你的肆意强制转变会一次又一次地伤害你。