/************************************************************************/
/* Dll inject For VC x64                                                */
/* copyright 2004-2016 www.chinapyg.com                                 */
/* Code By PiaoYun/P.Y.G                                                */
/* Fixed 2016-10-08                                                     */
/************************************************************************/

// 头文件
#include <windows.h>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
#pragma comment(linker, "/EXPORT:GetFileVersionInfoA=ChinaPYG_GetFileVersionInfoA")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoByHandle=ChinaPYG_GetFileVersionInfoByHandle")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoExW=ChinaPYG_GetFileVersionInfoExW")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeA=ChinaPYG_GetFileVersionInfoSizeA")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeExW=ChinaPYG_GetFileVersionInfoSizeExW")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeW=ChinaPYG_GetFileVersionInfoSizeW")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoW=ChinaPYG_GetFileVersionInfoW")
#pragma comment(linker, "/EXPORT:VerFindFileA=ChinaPYG_VerFindFileA")
#pragma comment(linker, "/EXPORT:VerFindFileW=ChinaPYG_VerFindFileW")
#pragma comment(linker, "/EXPORT:VerInstallFileA=ChinaPYG_VerInstallFileA")
#pragma comment(linker, "/EXPORT:VerInstallFileW=ChinaPYG_VerInstallFileW")
#pragma comment(linker, "/EXPORT:VerLanguageNameA=ChinaPYG_VerLanguageNameA")
#pragma comment(linker, "/EXPORT:VerLanguageNameW=ChinaPYG_VerLanguageNameW")
#pragma comment(linker, "/EXPORT:VerQueryValueA=ChinaPYG_VerQueryValueA")
#pragma comment(linker, "/EXPORT:VerQueryValueW=ChinaPYG_VerQueryValueW")
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 宏定义
#define EXTERNC extern "C"
#define ALSTD EXTERNC void __stdcall
#define ALCDECL EXTERNC void __cdecl
#define PYG TEXT("PYG")
#define LOAD_ERROR TEXT("无法加载 %s,程序无法正常运行。")
#define FUN_ERROR TEXT("无法找到函数 %hs,程序无法正常运行。")
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 汇编函数声明
ALSTD GetRcx();
ALSTD JmpAddr(INT64 _addr);
ALSTD PatchBYTE(INT64 addr, byte data);
ALSTD PatchWORD(INT64 addr, WORD data);
ALSTD PatchDWORD(INT64 addr, DWORD data);
ALSTD PatchQWORD(INT64 addr, INT64 data);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ChinaPYG 命名空间
namespace ChinaPYG
{
    HMODULE m_hModule = NULL;    // 原始模块句柄
    DWORD m_dwReturn[5] = { 0 };    // 原始函数返回地址

                                    // 加载原始模块
    inline BOOL WINAPI Load()
    {
        TCHAR tzPath[MAX_PATH];
        TCHAR tzTemp[MAX_PATH * 2];

        GetSystemDirectory(tzPath, MAX_PATH);
        lstrcat(tzPath, TEXT("\\version.dll"));
        m_hModule = LoadLibrary(tzPath);
        if (m_hModule == NULL)
        {
            wsprintf(tzTemp, LOAD_ERROR, tzPath);
            MessageBox(NULL, tzTemp, PYG, MB_ICONSTOP);
        }
        return (m_hModule != NULL);
    }

    // 释放原始模块
    inline VOID WINAPI Free()
    {
        if (m_hModule)
        {
            FreeLibrary(m_hModule);
        }
    }

    // 获取原始函数地址
    FARPROC WINAPI GetAddress(PCSTR pszProcName)
    {
        FARPROC fpAddress;
        CHAR szProcName[16];
        TCHAR tzTemp[MAX_PATH];

        if (m_hModule == NULL)
        {
            if (Load() == FALSE)
            {
                ExitProcess(-1);
            }
        }

        fpAddress = GetProcAddress(m_hModule, pszProcName);
        if (fpAddress == NULL)
        {
            if (HIWORD(pszProcName) == 0)
            {
                wsprintf(szProcName, "%d", pszProcName);
                pszProcName = szProcName;
            }
            wsprintf(tzTemp, FUN_ERROR, pszProcName);
            MessageBox(NULL, tzTemp, PYG, MB_ICONSTOP);
            ExitProcess(-2);
        }

        return fpAddress;
    }
}
using namespace ChinaPYG;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void PatchIt()
{
    // 写自己的Patch代码

    DWORD dwOldProtect;
    HMODULE BaseAddr;
    INT64 PatchAddr;

    BaseAddr = GetModuleHandle(NULL);
    PatchAddr = (INT64)BaseAddr + 0x1ABA;
    VirtualProtect((LPVOID)PatchAddr, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect);
    //*(PWORD)PatchAddr = 0x9090;
    PatchWORD(PatchAddr, 0x9090);

}

INT64 g_GetFileVersionInfoA = NULL;
INT64 g_GetFileVersionInfoByHandle = NULL;
INT64 g_GetFileVersionInfoExW = NULL;
INT64 g_GetFileVersionInfoSizeA = NULL;
INT64 g_GetFileVersionInfoSizeExW = NULL;
INT64 g_GetFileVersionInfoSizeW = NULL;
INT64 g_GetFileVersionInfoW = NULL;
INT64 g_VerFindFileA = NULL;
INT64 g_VerFindFileW = NULL;
INT64 g_VerInstallFileA = NULL;
INT64 g_VerInstallFileW = NULL;
INT64 g_VerLanguageNameA = NULL;
INT64 g_VerLanguageNameW = NULL;
INT64 g_VerQueryValueA = NULL;
INT64 g_VerQueryValueW = NULL;

VOID InitFun()
{
    g_GetFileVersionInfoA = (INT64)GetAddress("GetFileVersionInfoA");
    g_GetFileVersionInfoByHandle = (INT64)GetAddress("GetFileVersionInfoByHandle");
    g_GetFileVersionInfoExW = (INT64)GetAddress("GetFileVersionInfoExW");
    g_GetFileVersionInfoSizeA = (INT64)GetAddress("GetFileVersionInfoSizeA");
    g_GetFileVersionInfoSizeExW = (INT64)GetAddress("GetFileVersionInfoSizeExW");
    g_GetFileVersionInfoSizeW = (INT64)GetAddress("GetFileVersionInfoSizeW");
    g_GetFileVersionInfoW = (INT64)GetAddress("GetFileVersionInfoW");

    g_VerFindFileA = (INT64)GetAddress("VerFindFileA");
    g_VerFindFileW = (INT64)GetAddress("VerFindFileW");
    g_VerInstallFileA = (INT64)GetAddress("VerInstallFileA");
    g_VerInstallFileW = (INT64)GetAddress("VerInstallFileW");
    g_VerLanguageNameA = (INT64)GetAddress("VerLanguageNameA");
    g_VerLanguageNameW = (INT64)GetAddress("VerLanguageNameW");
    g_VerQueryValueA = (INT64)GetAddress("VerQueryValueA");
    g_VerQueryValueW = (INT64)GetAddress("VerQueryValueW");
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 入口函数
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
    switch (dwReason)
    {
    case  DLL_PROCESS_ATTACH:
    {
        DisableThreadLibraryCalls(hModule);
        if (Load())
        {
            InitFun();
            //PatchIt();
        }
        else
            return FALSE;

        break;
    }
    case DLL_PROCESS_DETACH:
    {
        Free();
        break;
    }
    }

    return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_GetFileVersionInfoA(void)
{
    GetRcx();
    JmpAddr(g_GetFileVersionInfoA);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_GetFileVersionInfoByHandle(void)
{
    GetRcx();
    JmpAddr(g_GetFileVersionInfoByHandle);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_GetFileVersionInfoExW(void)
{
    GetRcx();
    JmpAddr(g_GetFileVersionInfoExW);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_GetFileVersionInfoSizeA(void)
{
    GetRcx();
    JmpAddr(g_GetFileVersionInfoSizeA);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_GetFileVersionInfoSizeExW(void)
{
    GetRcx();
    JmpAddr(g_GetFileVersionInfoSizeExW);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_GetFileVersionInfoSizeW(void)
{
    GetRcx();
    JmpAddr(g_GetFileVersionInfoSizeW);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_GetFileVersionInfoW(void)
{
    GetRcx();
    JmpAddr(g_GetFileVersionInfoW);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_VerFindFileA(void)
{
    GetRcx();
    JmpAddr(g_VerFindFileA);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_VerFindFileW(void)
{
    GetRcx();
    JmpAddr(g_VerFindFileW);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_VerInstallFileA(void)
{
    GetRcx();
    JmpAddr(g_VerInstallFileA);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_VerInstallFileW(void)
{
    GetRcx();
    JmpAddr(g_VerInstallFileW);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_VerLanguageNameA(void)
{
    GetRcx();
    JmpAddr(g_VerLanguageNameA);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_VerLanguageNameW(void)
{
    GetRcx();
    JmpAddr(g_VerLanguageNameW);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_VerQueryValueA(void)
{
    GetRcx();
    JmpAddr(g_VerQueryValueA);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL ChinaPYG_VerQueryValueW(void)
{
    GetRcx();
    JmpAddr(g_VerQueryValueW);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


// ASM obj部分源代码:

https://www.dllhook.com/post/12.html

评论区

已有14位网友发表了看法:

1L 希望帮忙解决  2014-05-19 18:37:37 回复
希望帮忙解决一下,没有编译成功呢?是用的vs2010
unresolved external symbol JmpAddr referenced in function
1L piaoyun  2014-05-19 19:50:33 回复
@希望帮忙解决 https://www.dllhook.com/?id=12
还有个obj要编译,看上面汇编代码
1L piaoyun  2014-05-19 19:51:14 回复
@希望帮忙解决 另外2010你要自己配置x64编译器,否则通不过的
1L 访客  2014-11-03 10:05:00 回复
@piaoyun piaoyun朋友,vs2010怎么自己配置x64能编译成功.求帮助.
1L piaoyun  2014-11-03 14:22:52 回复
@访客 配置管理器中添加x64~~
2L 希望帮忙解决  2014-05-20 14:02:42 回复
在谢谢您了,对我非常有用,希望我们能交个朋友。谢谢您。
3L wahnn  2014-12-08 15:39:38 回复
原装代码+OBJ...编译成功...但放入EXE执行目录下却没有成功.调试了一下OBJ写法没有错.能进去原始函数执行原始函数.但原始函数执行返回错误代码.程序没有能正常运行...
3L wahnn  2014-12-08 15:41:30 回复
@wahnn 忘记说环境了.win7sp1+x64+vs2008
3L piaoyun  2014-12-09 10:31:21 回复
@wahnn 一步步注释、排除掉 看哪里错了。
4L 请教个问题  2016-08-12 14:52:48 回复
我用上面的代码生成dll后,程序不能正常运行,后来调试发现是在JmpAddr((INT64)GetAddress("GetFileVersionInfoSizeA")),程序提示unable to read file version information
4L piaoyun  2016-08-14 20:11:17 回复
@请教个问题 各种平台的version32导出函数有些许不同,得兼容一下~
你先注释掉这个函数直接转发~~
4L 请教个问题  2016-08-14 20:27:34 回复
@piaoyun 我的是开发环境是win7sp1+x64+vs2012,注释掉就会报错无法定位程序输入点GetFileVersionInfoSizeA于动态链接库
4L piaoyun  2016-08-14 23:19:36 回复
@请教个问题 有可能 JmpAddr 函数破坏了堆栈(毕竟那段汇编是不安全的~) 没法重现不好判断~ 你到PYG论坛x64版块寻找其他解决方案~~
5L 访客  2019-05-30 19:31:27 回复
飘大,这个好像不通用啊,我换来其他dll,比如msimg32.dll就不行了。

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。