version.dll劫持注入模版(支持x64)
version.dll劫持是经常用到的技术,但是我用c写劫持dll时总是得把所有导出函数都写一遍version.dll劫持注入模版_version.dll 劫持源代码-CSDN博客
网上能搜到的只能支持32位
其实这事说简单也简单,没啥技术含量;说难也难,有十几个函数得按着签名写一遍...非常浪费时间,故把通用模板放到论坛上以备我自己和大家取用
#include <Windows.h>
// 处理MSVC下wcscat警告
#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif
// 全局原始version.dll句柄
static HMODULE hVersion;
// 辅助取函数地址
PVOID GetVersionFuncAddress(LPCSTR FuncName)
{
if(!hVersion)
{
wchar_t systemDirectory;
if (!::GetSystemDirectory(systemDirectory, MAX_PATH))
return nullptr;
wcscat(systemDirectory, L"\\System32\\version.dll");
hVersion = ::LoadLibraryW(systemDirectory);
if (!hVersion)
return nullptr;
}
return GetProcAddress(hVersion, FuncName);
}
// 导出
#pragma comment(linker, "/EXPORT:GetFileVersionInfoA=P_GetFileVersionInfoA,@1")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoByHandle=P_GetFileVersionInfoByHandle,@2")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoExA=P_GetFileVersionInfoExA,@3")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoExW=P_GetFileVersionInfoExW,@4")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeA=P_GetFileVersionInfoSizeA,@5")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeExA=P_GetFileVersionInfoSizeExA,@6")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeExW=P_GetFileVersionInfoSizeExW,@7")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeW=P_GetFileVersionInfoSizeW,@8")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoW=P_GetFileVersionInfoW,@9")
#pragma comment(linker, "/EXPORT:VerFindFileA=P_VerFindFileA,@10")
#pragma comment(linker, "/EXPORT:VerFindFileW=P_VerFindFileW,@11")
#pragma comment(linker, "/EXPORT:VerInstallFileA=P_VerInstallFileA,@12")
#pragma comment(linker, "/EXPORT:VerInstallFileW=P_VerInstallFileW,@13")
#pragma comment(linker, "/EXPORT:VerLanguageNameA=P_VerLanguageNameA,@14")
#pragma comment(linker, "/EXPORT:VerLanguageNameW=P_VerLanguageNameW,@15")
#pragma comment(linker, "/EXPORT:VerQueryValueA=P_VerQueryValueA,@16")
#pragma comment(linker, "/EXPORT:VerQueryValueW=P_VerQueryValueW,@17")
// 原始函数
extern "C" BOOL P_GetFileVersionInfoA(
LPCSTR lptstrFilename,
DWORD dwHandle,
DWORD dwLen,
LPVOID lpData
) {
BOOL(*pGetFileVersionInfoA)(LPCSTR, DWORD, DWORD, LPVOID) = (BOOL(*)(LPCSTR, DWORD, DWORD, LPVOID)) (GetVersionFuncAddress("GetFileVersionInfoA"));
return pGetFileVersionInfoA(lptstrFilename, dwHandle, dwLen, lpData);
}
extern "C" BOOL P_GetFileVersionInfoByHandle(
DWORD dwFlags,
HANDLE hFile,
PDWORD pdwLen
) {
BOOL(*pGetFileVersionInfoByHandle)(DWORD, HANDLE, PDWORD) = (BOOL(*)(DWORD, HANDLE, PDWORD)) (GetVersionFuncAddress("GetFileVersionInfoByHandle"));
return pGetFileVersionInfoByHandle(dwFlags, hFile, pdwLen);
}
extern "C" BOOL P_GetFileVersionInfoExA(
DWORD dwFlags,
LPCSTR lpwstrFilename,
DWORD dwHandle,
DWORD dwLen,
LPVOID lpData
) {
BOOL(*pGetFileVersionInfoExA)(DWORD, LPCSTR, DWORD, DWORD, LPVOID) = (BOOL(*)(DWORD, LPCSTR, DWORD, DWORD, LPVOID)) (GetVersionFuncAddress("GetFileVersionInfoExA"));
return pGetFileVersionInfoExA(dwFlags, lpwstrFilename, dwHandle, dwLen, lpData);
}
extern "C" BOOL P_GetFileVersionInfoExW(
DWORD dwFlags,
LPCWSTR lpwstrFilename,
DWORD dwHandle,
DWORD dwLen,
LPVOID lpData
) {
BOOL(*pGetFileVersionInfoExW)(DWORD, LPCWSTR, DWORD, DWORD, LPVOID) = (BOOL(*)(DWORD, LPCWSTR, DWORD, DWORD, LPVOID)) (GetVersionFuncAddress("GetFileVersionInfoExW"));
return pGetFileVersionInfoExW(dwFlags, lpwstrFilename, dwHandle, dwLen, lpData);
}
extern "C" DWORD P_GetFileVersionInfoSizeA(
LPCSTR lptstrFilename,
LPDWORD lpdwHandle
) {
DWORD(*pGetFileVersionInfoSizeA)(LPCSTR, LPDWORD) = (DWORD(*)(LPCSTR, LPDWORD)) (GetVersionFuncAddress("GetFileVersionInfoSizeA"));
return pGetFileVersionInfoSizeA(lptstrFilename, lpdwHandle);
}
extern "C" DWORD P_GetFileVersionInfoSizeExA(
DWORD dwFlags,
LPCSTR lpwstrFilename,
LPDWORD lpdwHandle
) {
DWORD(*pGetFileVersionInfoSizeExA)(DWORD, LPCSTR, LPDWORD) = (DWORD(*)(DWORD, LPCSTR, LPDWORD)) (GetVersionFuncAddress("GetFileVersionInfoSizeExA"));
return pGetFileVersionInfoSizeExA(dwFlags, lpwstrFilename, lpdwHandle);
}
extern "C" DWORD P_GetFileVersionInfoSizeExW(
DWORD dwFlags,
LPCWSTR lpwstrFilename,
LPDWORD lpdwHandle
) {
DWORD(*pGetFileVersionInfoSizeExW)(DWORD, LPCWSTR, LPDWORD) = (DWORD(*)(DWORD, LPCWSTR, LPDWORD)) (GetVersionFuncAddress("GetFileVersionInfoSizeExW"));
return pGetFileVersionInfoSizeExW(dwFlags, lpwstrFilename, lpdwHandle);
}
extern "C" DWORD P_GetFileVersionInfoSizeW(
LPCWSTR lptstrFilename,
LPDWORD lpdwHandle
) {
DWORD(*pGetFileVersionInfoSizeW)(LPCWSTR, LPDWORD) = (DWORD(*)(LPCWSTR, LPDWORD)) (GetVersionFuncAddress("GetFileVersionInfoSizeW"));
return pGetFileVersionInfoSizeW(lptstrFilename, lpdwHandle);
}
extern "C" BOOL P_GetFileVersionInfoW(
LPCWSTR lptstrFilename,
DWORD dwHandle,
DWORD dwLen,
LPVOID lpData
) {
BOOL(*pGetFileVersionInfoW)(LPCWSTR, DWORD, DWORD, LPVOID) = (BOOL(*)(LPCWSTR, DWORD, DWORD, LPVOID)) (GetVersionFuncAddress("GetFileVersionInfoW"));
return pGetFileVersionInfoW(lptstrFilename, dwHandle, dwLen, lpData);
}
extern "C" DWORD P_VerFindFileA(
DWORD uFlags,
LPCSTR szFileName,
LPCSTR szWinDir,
LPCSTR szAppDir,
LPSTR szCurDir,
PUINT puCurDirLen,
LPSTR szDestDir,
PUINT puDestDirLen
) {
DWORD(*pVerFindFileA)(DWORD, LPCSTR, LPCSTR, LPCSTR, LPSTR, PUINT, LPSTR, PUINT) = (DWORD(*)(DWORD, LPCSTR, LPCSTR, LPCSTR, LPSTR, PUINT, LPSTR, PUINT)) (GetVersionFuncAddress("VerFindFileA"));
return pVerFindFileA(uFlags, szFileName, szWinDir, szAppDir, szCurDir, puCurDirLen, szDestDir, puDestDirLen);
}
extern "C" DWORD P_VerFindFileW(
DWORD uFlags,
LPCWSTR szFileName,
LPCWSTR szWinDir,
LPCWSTR szAppDir,
LPWSTR szCurDir,
PUINT puCurDirLen,
LPWSTR szDestDir,
PUINT puDestDirLen
) {
DWORD(*pVerFindFileW)(DWORD, LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, PUINT, LPWSTR, PUINT) = (DWORD(*)(DWORD, LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, PUINT, LPWSTR, PUINT)) (GetVersionFuncAddress("VerFindFileW"));
return pVerFindFileW(uFlags, szFileName, szWinDir, szAppDir, szCurDir, puCurDirLen, szDestDir, puDestDirLen);
}
extern "C" DWORD P_VerInstallFileA(
DWORD uFlags,
LPCSTR szSrcFileName,
LPCSTR szDestFileName,
LPCSTR szSrcDir,
LPCSTR szDestDir,
LPCSTR szCurDir,
LPSTR szTmpFile,
PUINT puTmpFileLen
) {
DWORD(*pVerInstallFileA)(DWORD, LPCSTR, LPCSTR, LPCSTR, LPCSTR, LPCSTR, LPSTR, PUINT) = (DWORD(*)(DWORD, LPCSTR, LPCSTR, LPCSTR, LPCSTR, LPCSTR, LPSTR, PUINT)) (GetVersionFuncAddress("VerInstallFileA"));
return pVerInstallFileA(uFlags, szSrcFileName, szDestFileName, szSrcDir, szDestDir, szCurDir, szTmpFile, puTmpFileLen);
}
extern "C" DWORD P_VerInstallFileW(
DWORD uFlags,
LPCWSTR szSrcFileName,
LPCWSTR szDestFileName,
LPCWSTR szSrcDir,
LPCWSTR szDestDir,
LPCWSTR szCurDir,
LPWSTR szTmpFile,
PUINT puTmpFileLen
) {
DWORD(*pVerInstallFileW)(DWORD, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, PUINT) = (DWORD(*)(DWORD, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, PUINT)) (GetVersionFuncAddress("VerInstallFileW"));
return pVerInstallFileW(uFlags, szSrcFileName, szDestFileName, szSrcDir, szDestDir, szCurDir, szTmpFile, puTmpFileLen);
}
extern "C" DWORD P_VerLanguageNameA(
DWORD wLang,
LPSTR szLang,
DWORD cchLang
) {
DWORD(*pVerLanguageNameA)(DWORD, LPSTR, DWORD) = (DWORD(*)(DWORD, LPSTR, DWORD)) (GetVersionFuncAddress("VerLanguageNameA"));
return pVerLanguageNameA(wLang, szLang, cchLang);
}
extern "C" DWORD P_VerLanguageNameW(
DWORD wLang,
LPWSTR szLang,
DWORD cchLang
) {
DWORD(*pVerLanguageNameW)(DWORD, LPWSTR, DWORD) = (DWORD(*)(DWORD, LPWSTR, DWORD)) (GetVersionFuncAddress("VerLanguageNameW"));
return pVerLanguageNameW(wLang, szLang, cchLang);
}
extern "C" BOOL P_VerQueryValueA(
LPCVOID pBlock,
LPCSTR lpSubBlock,
LPVOID lplpBuffer,
PUINT puLen
) {
BOOL(*pVerQueryValueA)(LPCVOID, LPCSTR, LPVOID, PUINT) = (BOOL(*)(LPCVOID, LPCSTR, LPVOID, PUINT)) (GetVersionFuncAddress("VerQueryValueA"));
return pVerQueryValueA(pBlock, lpSubBlock, lplpBuffer, puLen);
}
extern "C" BOOL P_VerQueryValueW(
LPCVOID pBlock,
LPCWSTR lpSubBlock,
LPVOID lplpBuffer,
PUINT puLen
) {
BOOL(*pVerQueryValueW)(LPCVOID, LPCWSTR, LPVOID, PUINT) = (BOOL(*)(LPCVOID, LPCWSTR, LPVOID, PUINT)) (GetVersionFuncAddress("VerQueryValueW"));
return pVerQueryValueW(pBlock, lpSubBlock, lplpBuffer, puLen);
}
另外,这里是一个读取文件中函数原型生成形如上的劫持代码的小工具,上面的代码是用这个小工具根据提取的函数原型生成的
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <regex>
// 将函数签名字符串分解为函数返回类型、函数名、参数类型等
struct FuncSignature
{
std::string returnType;
std::string funcName;
std::vector<std::string> paramTypes;
std::vector<std::string> paramNames;
};
// 使用正则表达式解析函数签名
FuncSignature parseFunctionSignature(const std::string& signature)
{
std::regex re(R"((\w+)\s+(\w+)\((.*?)\))");
std::smatch match;
if (std::regex_search(signature, match, re))
{
FuncSignature funcSig;
funcSig.returnType = match;
funcSig.funcName = match;
// 解析参数列表
std::string params = match;
std::regex paramRe(R"((\w+)\s+(\w+))");
auto paramBegin = std::sregex_iterator(params.begin(), params.end(), paramRe);
auto paramEnd = std::sregex_iterator();
for (auto it = paramBegin; it != paramEnd; ++it)
{
funcSig.paramTypes.push_back(it->str(1));// 参数类型
funcSig.paramNames.push_back(it->str(2));// 参数名
}
return funcSig;
}
throw std::invalid_argument("Invalid function signature.");
}
// 生成导出函数代码
std::string generateExportFunctionCode(const FuncSignature& sig)
{
std::ostringstream code;
// 构造新的函数名
std::string newFuncName = "P_" + sig.funcName;
// 函数签名的代码
// code << "#pragma comment(linker, \"/EXPORT:" << sig.funcName << "=" << newFuncName << ",@1\")\n\n";
code << "extern \"C\" " << sig.returnType << " " << newFuncName << "(\n";
// 参数代码
for (size_t i = 0; i < sig.paramTypes.size(); ++i)
{
code << "" << sig.paramTypes << " " << sig.paramNames;
if (i < sig.paramTypes.size() - 1)
code << ",\n";
else
code << "\n";
}
code << ") {\n";
code << "" << sig.returnType << " (*p" << sig.funcName << ")(";
// 参数类型列表
for (size_t i = 0; i < sig.paramTypes.size(); ++i)
{
code << sig.paramTypes;
if (i < sig.paramTypes.size() - 1)
code << ", ";
}
code << ") = (" << sig.returnType << "(*)(";
// 再次列出参数类型
for (size_t i = 0; i < sig.paramTypes.size(); ++i)
{
code << sig.paramTypes;
if (i < sig.paramTypes.size() - 1)
code << ", ";
}
code << ")) (GetVersionFuncAddress(\"" << sig.funcName << "\"));\n";
// 调用原函数
code << "return p" << sig.funcName << "(";
for (size_t i = 0; i < sig.paramNames.size(); ++i)
{
code << sig.paramNames;
if (i < sig.paramNames.size() - 1)
code << ", ";
}
code << ");\n";
code << "}\n";
return code.str();
}
int main()
{
// 输入函数签名
std::string funcSig;
std::ifstream inf;
inf.open("cilp_r.txt");
while (std::getline(inf, funcSig))
{
try
{
// 解析函数签名
FuncSignature sig = parseFunctionSignature(funcSig);
// 生成导出函数代码
std::string exportCode = generateExportFunctionCode(sig);
// 输出生成的代码
std::cout << exportCode << std::endl;
}
catch (const std::exception& e)
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
读取文件cilp_r.txt示例:
BOOL GetFileVersionInfoA(LPCSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData);
BOOL GetFileVersionInfoByHandle(DWORD dwFlags, HANDLE hFile, LPVOID * lplpData, PDWORD pdwLen );
BOOL GetFileVersionInfoExA(DWORD dwFlags, LPCSTR lpwstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData);
BOOL GetFileVersionInfoExW(DWORD dwFlags, LPCWSTR lpwstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData);
DWORD GetFileVersionInfoSizeA(LPCSTR lptstrFilename, LPDWORD lpdwHandle);
DWORD GetFileVersionInfoSizeExA(DWORD dwFlags, LPCSTR lpwstrFilename, LPDWORD lpdwHandle);
DWORD GetFileVersionInfoSizeExW(DWORD dwFlags, LPCWSTR lpwstrFilename, LPDWORD lpdwHandle);
DWORD GetFileVersionInfoSizeW(LPCWSTR lptstrFilename, LPDWORD lpdwHandle);
BOOL GetFileVersionInfoW(LPCWSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData);
DWORD VerFindFileA(DWORD uFlags, LPCSTR szFileName, LPCSTR szWinDir, LPCSTR szAppDir, LPSTR szCurDir, PUINT puCurDirLen, LPSTR szDestDir, PUINT puDestDirLen);
DWORD VerFindFileW(DWORD uFlags, LPCWSTR szFileName, LPCWSTR szWinDir, LPCWSTR szAppDir, LPWSTR szCurDir, PUINT puCurDirLen, LPWSTR szDestDir, PUINT puDestDirLen);
DWORD VerInstallFileA(DWORD uFlags, LPCSTR szSrcFileName, LPCSTR szDestFileName, LPCSTR szSrcDir, LPCSTR szDestDir, LPCSTR szCurDir, LPSTR szTmpFile, PUINT puTmpFileLen);
DWORD VerInstallFileW(DWORD uFlags, LPCWSTR szSrcFileName, LPCWSTR szDestFileName, LPCWSTR szSrcDir, LPCWSTR szDestDir, LPCWSTR szCurDir, LPWSTR szTmpFile, PUINT puTmpFileLen);
DWORD VerLanguageNameA(DWORD wLang, LPSTR szLang, DWORD cchLang);
DWORD VerLanguageNameW(DWORD wLang, LPWSTR szLang, DWORD cchLang);
BOOL VerQueryValueA(LPCVOID pBlock, LPCSTR lpSubBlock, LPVOID lplpBuffer, PUINT puLen);
BOOL VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID lplpBuffer, PUINT puLen); aheadlib了解一下 https://wwgz.lanzouw.com/b00mowf4la
密码:1dzb
很好奇大家要完整的工程文件干啥...只是一个用来重定向某个软件写入配置文件的dll
主贴中第一段代码是模板文件,第二、三段代码是用来生成模板文件的程序
如果要使用模板文件,只需要将包含第一段代码的文件包括到工程中即可
如果要创建其他dll劫持的模板文件才需要用到第二、三段代码
@wszjf @朱朱你堕落了 @redapple2015 感谢分享技术贴。。。 这个文件能不能打包一下?谢谢! 感谢分享技术贴。。。 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息
错误 C1010 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "pch.h"”? PS_SFM_HOOK
不会C,这是差什么文件么?
感谢分享。虽然不会C++ aheadlib和baymax patch tools 了解一下 lml0126 发表于 2024-11-18 19:04
严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息
错误 C1010 在查找预编译头时遇到意外的文件结尾。 ...
是少了头文件pch.h 吧