我想我的代码现在终于可以工作了。唯一的问题是,由于某些原因,即使我用PROCESS_ALL_ACCESS打开了进程,CreateRemoteThread还是抛出了一个错误: ERROR_ACCESS_DENIED。
错误是用GetLastError检索到的,它会输出'5',翻译过来就是ERROR_ACCESS_DENIED。
#include <iostream>
#include <windows.h>
#include <TlHelp32.h>
char* dllPath = "C:\\Users\\Kalist\\Desktop\\Projects\\DLL\\bin\\Debug\\DLL.dll";
char* ProcToInject = "calc.exe";
int main(){
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE procSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(procSnap == INVALID_HANDLE_VALUE){
std::cout << "Snapshot function failed" << std::endl;
}
DWORD procID = 0;
if(Process32First(procSnap, &pe32)){
do{
if(!strcmp(pe32.szExeFile, ProcToInject)){
procID = pe32.th32ProcessID;
break;
}
}while(Process32Next(procSnap, &pe32));
}
CloseHandle(procSnap);
if(procID != 0){
HANDLE procAccess = OpenProcess(PROCESS_ALL_ACCESS, false, procID);
if(procAccess == NULL){
std::cout << "OpenProcess error: " << GetLastError() << std::endl;
}
LPVOID remoteString = (LPVOID)VirtualAllocEx(procAccess, NULL, strlen(dllPath)+1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if(remoteString == NULL){
std::cout << "VirtualAllocEx error: " << GetLastError() << std::endl;
}
bool memoryWritten = WriteProcessMemory(procAccess, (LPVOID)remoteString, dllPath, strlen(dllPath)+1, NULL);
if(memoryWritten == 0){
std::cout << "WriteProcessMemory error: " << GetLastError() << std::endl;
}
LPVOID getLibAdd = (LPVOID)GetProcAddress(GetModuleHandle("Kernel32.dll"), "LoadLibraryA");
if(getLibAdd == NULL){
std::cout << "GetProcAddress error: " << GetLastError() << std::endl;
}
HANDLE remoteThread = CreateRemoteThread(procAccess, NULL, 0, (LPTHREAD_START_ROUTINE)getLibAdd, (LPVOID)remoteString, 0, NULL);
if(remoteThread == NULL){
std::cout << "CreateRemoteThread error: " << GetLastError() << std::endl;
}
CloseHandle(procAccess);
}else{
std::cout << "Failed to retrieve procID" << std::endl;
}
}
发布于 2015-07-01 23:27:00
当您尝试从32位进程调用CreateRemoteThread
,但目标进程是64位进程时,您将收到此错误。我打赌这就是你要做的。
为了注入到一个64位的进程中,你需要你的注入进程也是64位的。显然,我相信你已经知道,你注入的DLL也必须是64位的。
无论如何,当您调用OpenProcess
时,您不需要要求太多。我相信你所需要的就是:
PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION
| PROCESS_VM_WRITE | PROCESS_VM_READ
发布于 2021-08-29 12:56:24
您编写的代码假设进程、运行代码、注入的动态链接库和calc.exe都是相同的位。
如果不满足这一点,则对CreateRemoteThread
的调用将失败。这是由于lpStartAddress
参数的限制。
以下报价来自CreateRemoteThread documentation
指向要由线程执行的LPTHREAD_START_ROUTINE类型的应用程序定义函数的指针,表示远程进程中线程的起始地址。该函数必须存在于远程进程中。有关详细信息,请参阅ThreadProc。
代码的假设是由于以下原因:
在比较x86和x64时,LoadLibraryA
函数位于不同的rva,因为当您使用x86进程与x64进程时,加载的是不同的rva文件。将Kernel32.dll
进程与x86进程进行比较时,也会在不同的基址加载不同的x64文件。你从GetProcAddr
得到的地址是rva + dll base address
。
目前我正在编写一个注入器,它也将能够x86到x64,并且已经验证了,所有传递到CreateRemoteThread
的地址都在目标进程的作用域中。此外,我还使用PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_READ| PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION
打开了该进程。但是我仍然有这个问题。
这是因为,x86的指针长度是32位。不过,CreateRemoteThread
的参数lpStartAddress
是一个指针。这意味着,您永远无法调用x64目标的所有函数,因为函数指针将被封顶为32位。这反过来意味着,在x86目标进程中,您最多可以从x86进程调用x64可寻址区域内的所有函数。
https://stackoverflow.com/questions/31165487
复制相似问题