【问题标题】:Check if program is runned trough another one检查程序是否通过另一个运行
【发布时间】:2015-01-09 07:37:19
【问题描述】:

所以我的问题如下:我有一个程序 Main.exe(启动游戏),我有一个附加的 dll,所以我可以加载一些功能。我有另一个名为 StartGame.exe(launcher+autoupdater) 的程序,现在的问题是,当客户端按下 START 时,如何创建一个函数以确保 Main.exe 仅从 StartGame.exe 运行? 我无法修改 Main.exe,也无法修改 StartGame.exe... 我做了一些简单的检查,如下所示:

if(FindWindow(NULL,"LiveMU") == NULL) //LiveMU is the name of window StartGame.exe
{
    MessageBoxA(0,"English: Please use the Launcher! \nRomanian: Va rugam sa folositi Launcher-ul!", TitleMsgBox,MB_ICONERROR);
    ExitProcess(0);
}

问题是,如果他们打开 startgame.exe 并将其留在托盘中,他们可以毫无问题地加载 Main.exe。主要问题是,如果我无法以某种方式保护 Main.exe 在没有启动器的情况下启动,则客户端/玩家使用加载 Main.exe 的作弊程序(注入它或其他东西,我真的不知道,因为它只是消失了,我可以'没找到)

LE:我无法向 StartGame.exe 添加命令行参数,因为它受到重度保护...

【问题讨论】:

  • 使用从“StartGame.exe”传递到“Main.exe”的“秘密”/内部命令行选项,如果该选项未通过,则立即退出“Main.exe”。如果用户启动 Main.exe(例如通过双击、命令行等),则该选项将不存在并且不会运行。
  • 我已经说过,我无法修改/添加/更改 StartGame.exe,因为它受 VMProtect 保护...我无法传递命令行参数 :(
  • 抱歉,没看到那部分。我认为一般来说没有 100% 可靠的方法,更不用说如果你试图“从外部”控制这两个程序的依赖...
  • 也许有一些保护措施可以防止附加到 Main.exe 的其他内容?我找不到作弊器(精英点击器)是如何附加到游戏中的,我认为它使用的是 winapi...
  • 你在问问题 Y,但你真正想要解决的是问题 X,问题 Y 只是你解决它的方法。为什么不在另一个问题中告诉我们问题 X? (“我怎样才能避免玩家作弊?”)解决方案可能完全不同......

标签: c++ windows


【解决方案1】:

标准的 Windows API 不允许您直接查找进程的父进程。但希望根据this other SO question,您还有其他 2 个解决方案(前提是父进程尚未终止...):

  • 使用原生 API。功能NtQueryInformationProcess可以直接给你信息。但要注意:

    • 你没有导入库所以你必须使用明确调用LoadLibraryGetProcAddress
    • 父进程 ID 是 Microsoft SDK 中引用 Reserved3 的未记录字段
    • Microsoft 警告说,此函数不是公共 API 的一部分,可能会在未来的版本中发生变化。

    如果您仍然想使用它,这里有一个获取父进程可执行文件名称的完整示例(您必须使用psapi.lib 链接):

    #include <windows.h>
    #include <psapi.h>
    #include <TCHAR.h>
    
    typedef struct _PROCESS_BASIC_INFORMATION {
        PVOID Reserved1;
        PVOID PebBaseAddress;
        PVOID Reserved2[2];
        ULONG_PTR UniqueProcessId;
        PVOID Reserved3;
    } PROCESS_BASIC_INFORMATION;
    
    DWORD getParentProcessId(HANDLE process) {
        LONG (WINAPI *NtQueryInformationProcess)(HANDLE ProcessHandle,
            ULONG ProcessInformationClass, PVOID ProcessInformation,
            ULONG ProcessInformationLength, PULONG ReturnLength) = NULL;
        HMODULE ntDll = ::LoadLibrary(_T("NTDLL.DLL"));
        FARPROC ntQueryInformationProcess = ::GetProcAddress(ntDll,
            "NtQueryInformationProcess");
        NtQueryInformationProcess =
            (LONG (WINAPI *)(HANDLE,ULONG,PVOID,ULONG,PULONG))ntQueryInformationProcess;
        if (NtQueryInformationProcess == NULL) {
            ::FreeLibrary(ntDll);
            return -1;
        }
        PROCESS_BASIC_INFORMATION pi;
        ULONG piLen;
        NtQueryInformationProcess(process, 0, &pi, sizeof(pi), & piLen);
        DWORD ppid = (DWORD) pi.Reserved3;
        ::FreeLibrary(ntDll);
        return ppid;
    }
    
    int main() {
        DWORD cr;
        HANDLE proc = ::GetCurrentProcess();
        DWORD ppid = getParentProcessId(proc);
    
        HANDLE pproc = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ppid);
        TCHAR pFile[MAX_PATH];
        cr = ::GetModuleFileNameEx(pproc, NULL, pFile, sizeof(pFile));
        ::CloseHandle(pproc);
        if (cr == 0) {
            LPTSTR pBuff;
            DWORD error = ::GetLastError();
            ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error, 0,
                (LPWSTR) &pBuff, 1, NULL);
            ::MessageBox(NULL, pBuff, _T("Error"), MB_OK | MB_ICONERROR);
        }
        ::MessageBox(NULL, pFile, _T("Parent process"), MB_OK);
        return 0;
    }
    
  • 1234563希望您得到(记录在案的)PROCESSENTRY32 结构,其中包含可执行名称、进程 ID 和进程父 ID。它有大量文档,您可以在 StackOverflow 上轻松找到许多示例(请参阅参考问题)

【讨论】:

  • 谢谢先生,我会试试这个。但是我已经有了一个 SystemProcessesScan() 和 ScanProcessMemory(HANDLE hProcess) ,其中包含已定义的可执行文件转储列表。它无法检测到这种作弊。我试着追踪它,仔细看看,但什么也没有。在这个 hack 的早期版本中,该程序将自己伪装成 rundll32.dll,因此我很容易检测到它,并通过它的 pid 关闭它。但是新版本也杀死了我和其他人:(这是程序(hack):filedropper.com/muautoclicker也许如果你有时间你可以看看......
  • @Mr.Mecanik 这篇文章回答了如何查看哪个程序启动了另一个问题。但是对于避免作弊的真正问题,这确实是一种肮脏的黑客攻击,您应该考虑在未来的版本中传递一个秘密,或者更好的是该秘密的哈希值和启动时间以获得唯一令牌。
  • 谢谢你的回答,但是如果你有时间,你能看看作弊吗?真的很高级也很有趣……
  • @Mr.Mecanik :这看起来是一个有趣的问题,但 DevSolar 是对的,我认为这不仅仅取决于找到一个程序是如何启动的......而且我不确定在这里真的很重要:-(。我的建议:清楚地分析 muautoclicker 如何与您的程序交互,但是如果它通过 API 向您的程序发送击键和鼠标点击,那么识别它真的很困难!
  • 我已经设法阻止了它使用的一些键,但这不是主要问题,作弊有特殊的命令,例如://multihit,//stealth,如果你在游戏中键入这些。我无法阻止这些,因为我不知道如何。无论如何,程序会向游戏发送数据包,也许我可以阻止那个 uhm
猜你喜欢
  • 1970-01-01
  • 2012-03-17
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
  • 2015-07-21
  • 1970-01-01
  • 2011-06-05
  • 2016-04-28
相关资源
最近更新 更多