C++注入器运行但不注入DLL 我在Windows 10上使用Visual Studio 2017,我编写了一个C++程序来打开进程句柄。程序运行并打开进程。我在调试器中运行了这个程序,看起来所有的函数都通过了。但是我知道DLL没有注入,因为当我在32位游戏上运行这个应用程序时。我可以删除我使用的test.dll,这意味着它没有被使用。有什么建议可以解释为什么它运行良好,但不是注射
PS remThread的值为0x0000011cC++注入器运行但不注入DLL 我在Windows 10上使用Visual Studio 2017,我编写了一个C++程序来打开进程句柄。程序运行并打开进程。我在调试器中运行了这个程序,看起来所有的函数都通过了。但是我知道DLL没有注入,因为当我在32位游戏上运行这个应用程序时。我可以删除我使用的test.dll,这意味着它没有被使用。有什么建议可以解释为什么它运行良好,但不是注射,c++,windows,winapi,window-handles,C++,Windows,Winapi,Window Handles,PS remThread的值为0x0000011c // DLL Injector.cpp : Defines the entry point for the console application. #include "stdafx.h" int InjectDLL(DWORD, string*); int getDLLpath(string*); int getPID(int*); int getProc(HANDLE*, DWORD); void enableSeDebug(); in
// DLL Injector.cpp : Defines the entry point for the console application.
#include "stdafx.h"
int InjectDLL(DWORD, string*);
int getDLLpath(string*);
int getPID(int*);
int getProc(HANDLE*, DWORD);
void enableSeDebug();
int main()
{
//Escalate privlege
enableSeDebug();
system("title Dll Injector");
string dllPath = "";
int PID = -1;
getDLLpath(&dllPath);
getPID(&PID);
InjectDLL(PID, &dllPath);
system("pause");
return 0;
}
int getDLLpath(string* dllPath)
{
cout << "Please enter the path to your DLL file\n";
cin >> *dllPath;
return 1;
}
int getPID(int* PID)
{
cout << "Please enter the PID to your target process\n";
cin >> *PID;
return 1;
}
int getProc(HANDLE* handleToProc, DWORD pid)
{
//Create a handle to the process
*handleToProc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (*handleToProc != 0)
{
cout << "Unable to open process.\n";
return -1;
}
else
{
cout << "process opened.\n";
return 1;
}
}
int InjectDLL(DWORD PID, string* dllPath)
{
HANDLE handleToProc;
LPVOID LoadLibAddr;
LPVOID baseAddr;
HANDLE remThread;
//Get handle to process
if (getProc(&handleToProc, PID) < 0)
return -1;
//Load kernel32 library
LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
if (!LoadLibAddr)
return -1;
//Allocate memory for DLL injection
baseAddr = VirtualAllocEx(handleToProc, NULL, dllPath->length(), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!baseAddr)
return -1;
//Write dll path
if (!WriteProcessMemory(handleToProc, baseAddr, dllPath, dllPath->length(), NULL))
return -1;
//Create remote thread
remThread = CreateRemoteThread(handleToProc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, baseAddr, 0, NULL);
if (!remThread)
return -1;
//Wait untill DLL exits then deallocate memmory
WaitForSingleObject(remThread, INFINITE);
//Freing memmory
VirtualFreeEx(handleToProc, baseAddr, dllPath->length(), MEM_RELEASE);
//Closing handles
if (CloseHandle(remThread) == 0)
{
cout << "Failed to close handle to remote thread.\n";
return -1;
}
if (CloseHandle(handleToProc) == 0)
{
cout << "Failed to close handle to target process.\n";
return -1;
}
return 1;
}
void enableSeDebug()
{
/////////////////////////////////////////////////////////
// Note: Enabling SeDebugPrivilege adapted from sample
// MSDN @ http://msdn.microsoft.com/en-us/library/aa446619%28VS.85%29.aspx
// Enable SeDebugPrivilege
HANDLE hToken = NULL;
TOKEN_PRIVILEGES tokenPriv;
LUID luidDebug;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) != FALSE)
{
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug) != FALSE)
{
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Luid = luidDebug;
tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, 0, NULL, NULL) != FALSE)
{
// Always successful, even in the cases which lead to OpenProcess failure
cout << "SUCCESSFULLY CHANGED TOKEN PRIVILEGES" << endl;
}
else
{
cout << "FAILED TO CHANGE TOKEN PRIVILEGES, CODE: " << GetLastError() << endl;
}
}
}
CloseHandle(hToken);
// Enable SeDebugPrivilege
}
上面的代码可以打开一个32位进程并在函数调用没有失败的情况下运行,但DLL没有注入?嗯,我认为getProc中的测试应该是:
if (*handleToProc == 0)
...
加上其他人在关于测试和报告GetLastError的评论中所说的
可能还有其他问题,我只是略读了一下代码,你必须把它改写成更合适的代码。不是亲透。你在检查身体状况时遇到了一些问题。一切都对我有用
#include <windows.h>
#include <iostream>
#include <tlhelp32.h>
#include <string>
using namespace std;
void getPID(DWORD&);
int getProc(HANDLE&, DWORD);
int main()
{
cout << "title Dll Injector" << endl;
string dllPath = "";
DWORD PID = NULL;
HANDLE handleToProc = nullptr;
getPID(PID);
if (getProc(handleToProc, PID) < 0)
return -1;
//Lets check is the handle valid
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (hSnapshot) {
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnapshot, &pe32)) {
do {
if (pe32.th32ProcessID == GetProcessId(handleToProc))
{
wstring name = wstring(pe32.szExeFile);
wcout << "Process id: " << pe32.th32ProcessID << ", Exe filename: " << name << endl;
}
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
}
//Cleanup is a must!
CloseHandle(handleToProc);
return 0;
}
//Create a handle to process
int getProc(HANDLE& handleToProc, DWORD pid)
{
//Create a handle to the process
handleToProc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (handleToProc == nullptr)
{
DWORD error = GetLastError();
cout << "Unable to open process. Error: " << error << "\n";
return -1;
}
else
{
cout << "process opened.\n";
return 0;
}
}
//Get PID from user
void getPID(DWORD& PID)
{
cout << "Please enter the PID to your target process\n";
cin >> PID;
}
问题在于指向句柄分配的指针,然后检查有效句柄。我能够解决我的问题。在检查getProc时,我需要执行以下操作
int getProc(HANDLE* handleToProc, DWORD pid)
{
//Create a handle to the process
*handleToProc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (*handleToProc == NULL) //I changed this line to check for NULL
{
cout << "Unable to open process.\n";
return -1;
}
else
{
cout << "process opened.\n";
return 1;
}
}
我需要更改的第二部分是我的dllPath,它是一个字符串,必须是char*。因此,当我编写DLL字符串时,它是一种不同的编码。使用char*指针解决了这个问题,现在注入器工作。不确定原因-从GetLastErrorif开始!handleToProc==0测试始终为真,因为handleToProc是有效指针。你是想检查*handleToProc吗?我把条件改为*handleToProc!=0,但仍无法打开进程。我还使用了ifhandleToProc,结果是一样的。0xCCCC表示未初始化堆栈内存:您还没有调用GetLastError这并没有回答所问的问题。此外,一个好的答案至少应该解释,问题是什么,以及建议的解决方案是如何解决的。因为您没有识别问题,所以您提出的代码无法解决问题。请参阅以获取帮助。这样我就可以打开我假设的32位进程,因为我的应用程序是32位的。我在VS2017上运行了调试器,一切都运行了,我得到了正常值。我在关闭句柄之前放置了一个systempause,但我可以告诉你DLL没有注入,因为删除DLL文件并不能告诉我它正在使用。这现在是没有意义的,是吗?在Windows中使用字符并不能解决任何字符编码问题,只是巧合而已。字符是不明确的,可以是ASCII、ANSI、UTF-8或其他字符。使用wchar_t,它代表Windows中的UTF-16LE代码单元。我使用process hacker查看了进程内存。使用字符串导致数据被全部弄乱。当我使用char*时,我可以在目标进程内存中看到dll路径。如果我的解释是正确的,可以说是正确的,但是字符串不能为我工作。当然,STD::String是C++类模板。不能将其视为一个字符数组。将std::string替换为char*不会更改字符编码。它用一种类型替换另一种类型。我之前的评论仍然适用:不要在Windows中使用std::string或char*。使用std::wstring或wchar\u t*。好的,为什么不使用char*?这在我的第一条评论中解释过。它的编码本质上是模糊的。