C++ DLL 注入:带有特殊字符的路径

Posted

技术标签:

【中文标题】C++ DLL 注入:带有特殊字符的路径【英文标题】:C++ DLL Injection: path with special characters 【发布时间】:2014-03-24 18:34:58 【问题描述】:

我正在尝试解决这种情况。 我有win32程序,等待特定进程启动“Example.exe”,然后程序将“my.dll”注入进程“Example.exe”

它可以正常工作,直到用户在具有特定但允许的字符的文件夹下有程序,例如在我的国家默认文件夹名称是“Nová složka”(新文件夹)

我尝试使用相对路径

"//my.dll"
"/my.dll"
"\\my.dll"
"\my.dll"

不成功...我也尝试了不同的方法将字符串(QString)转换为字符数组。

在 Qt 5.1.1 中开发

这是程序查找.dll路径的代码

QString actualPath(QDir::currentPath() + "/my.dll");
ui->lblDebug->setText(actualPath);
const char* myChar = QString(actualPath.toUtf8()).toStdString().c_str();
QString q = QString::fromStdString(myChar);
ui->lblDebug->setText(q);

这里是注入部分

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PE32.th32ProcessID);
hModule = (LPVOID)VirtualAllocEx(hProcess, NULL, 512, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, hModule, (LPVOID)myChar, 512, NULL);
CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32"), "LoadLibraryA"), hModule, NULL, NULL);
CloseHandle(hProcess);
CloseHandle(hSnapshot);
qDebug() << "INJECT:DONE!";
return true; ExitProcess(0);
break;

你有什么想法,如何将正确的字符传递给函数 WriteProcessMemory 正确的路径?谢谢。

【问题讨论】:

错误信息是什么?可能是字符编码问题。 没有错误信息,它编译程序没有错误,它也适用于“C:\my.dll”或“D:\Program Files\My files\my.dll”等路径。 dll”,但不使用“C:\Nová složka\my.dll” @AdamKennyŠmíd:这并没有解决 Drew MgGowen 所说的问题。仅仅因为代码编译只意味着代码在语法上是正确的。这并不意味着它会正确运行。暂时忘记 WriteProcessMemory。你能写一个简单的 Windows 程序来访问那个目录吗?也许从那开始,因为这看起来确实像一个编码问题。 例如,能否获取这个示例程序来判断路径是否存在? msdn.microsoft.com/en-us/library/windows/desktop/… 如果不是,那么问题出在编码上。要么是代码页问题,要么您需要正确转义字符串以解决这些外来字符。 现在我的程序非常大,我有很多功能可以处理文件、文件夹,并将它们上传到 FTP。如果我使用 Qt 函数,它会非常好用,但对于注入,我必须使用 windows 函数。 Project\Editor\Files 保存在 UTF-8 下 【参考方案1】:

您使用的是LoadLibrary 的ANSI 版本。然后您应该使用本地 8 位编码,not UTF-8。为获得路径的 ANSI 版本而进行的旋转是不必要的。您也不应该使用固定的缓冲区大小。

QString const actualPath(QDir::currentPath() + "/my.dll");
// This byte array must exist until the `WriteProcessMemory` call.
QByteArray const path = actualPath.toLocal8Bit();
int const bufLen = path.size() + 1;

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PE32.th32ProcessID);
hModule = VirtualAllocEx(hProcess, NULL, bufLen, 
                         MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, hModule, (LPVOID)path.constData(), bufLen, NULL);
CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)
  GetProcAddress(GetModuleHandle(L"kernel32"), "LoadLibraryA"),
  hModule, NULL, NULL);
CloseHandle(hProcess);

不过,您真正应该做的是使用带有 LoadLibraryW 的 UCS-2 编码:

QString const path(QDir::currentPath() + "/my.dll");
int const bufLen = (path.length()+1) * 2;

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PE32.th32ProcessID);
hModule = VirtualAllocEx(hProcess, NULL, bufLen,
                         MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, hModule, (LPVOID)path.constData(), bufLen, NULL);
CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)
  GetProcAddress(GetModuleHandle(L"kernel32"), "LoadLibraryW"),
  hModule, NULL, NULL);
CloseHandle(hProcess);

【讨论】:

以上是关于C++ DLL 注入:带有特殊字符的路径的主要内容,如果未能解决你的问题,请参考以下文章

PostMan发送请求参数带有路径特殊字符会返回400错误(与URL字符及URL编码值有关)

PostMan发送请求参数带有路径特殊字符会返回400错误(与URL字符及URL编码值有关)

带有包含特殊字符和空格的字符串的 MSAccess 更新语句

避免mysql注入应该避免都有哪些特殊字符

使用 URI 复制时不支持文件名中的特殊字符

http、https请求URL中带有&等特殊字符的解决方法