-4

So my question is as follows: I have a program Main.exe(wich starts the game), i have a dll attached to it so i can load some functions. I have another program called StartGame.exe(launcher+autoupdater), now the question is, how can i make a function to make sure that Main.exe is runned only from StartGame.exe when the client pressed START? I cannot modify either Main.exe, nor StartGame.exe... I have made some simple check as follows:

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);
}

The problem is, that if they open startgame.exe, and leave it in the tray, they can load Main.exe without a problem. The MAIN problem is, if i cannot protect somehow Main.exe from launching without the launcher, clients/players use a cheat program loading Main.exe(injecting it or something, i don't really know as it just disappears and i can't find it)

LE: I cannot add command line arguments to StartGame.exe because it`s heavy protected...

Mr.Mecanik
  • 15
  • 6
  • Use a "secret" / internal command line option that is passed from "StartGame.exe" to "Main.exe", exit "Main.exe" immediately if that option is not passed. If a user starts Main.exe (say by double click, command line etc.) the option will not be present and it won't run. – Christian.K Jan 09 '15 at 07:40
  • I allready said, i cannot modify/add/alter StartGame.exe because it`s protected with VMProtect... i cannot pass a command line argument :( – Mr.Mecanik Jan 09 '15 at 07:42
  • Sorry, didn't see that part. I think there is no 100% reliable way in general, much less so if you try to control this dependency "from outside" the two programs... – Christian.K Jan 09 '15 at 07:43
  • Maybe some protection againts other stuff ataching to the Main.exe? I cannot find how the cheat(elite clicker) attaches to the game, i think it uses winapi... – Mr.Mecanik Jan 09 '15 at 07:44
  • 1
    You are asking about problem Y, but what you're really trying to solve is problem X, for which problem Y is just your approach to so solve it. Why not tell us about problem X in a different question? ("How can I avoid players cheating?") The solution might be completely different... – DevSolar Jan 09 '15 at 07:48
  • I can avoid players cheating, i have made a compete antihack system, but i cannot block this certain hack... it loads into the game and dissapears, that`s why i am trying to run the Main.exe trough StartGame.exe. You see, when you run that cheat, you must select the Main.exe Path, then press start, after that there is nothing i can do to detect it :( – Mr.Mecanik Jan 09 '15 at 07:51

1 Answers1

1

The standard Windows API does not allow you to directly find the parent of a process. But hopefully according to this other SO question, you have 2 other solutions (provided the parent process is not already terminated ...) :

  • use the native API. The function NtQueryInformationProcess can directly give you the information. but beware :

    • you have no import library so you must use explicitely call LoadLibrary and GetProcAddress
    • the parent process id is the undocumented field referenced Reserved3 in Microsoft SDK
    • Microsoft warns that this function is not part of public API and may change in future versions.

    If you still want to use it here is a full example getting the parent process executable name (you will have to link with 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;
    }
    
  • if you do not like using poorly documented native API functions, you can use the toolhelp32 library : the CreateToolhelp32Snapshot creates a snapshot of all running processes, that you can browse with Process32First and Process32Next. Hopefully, you get (documented) PROCESSENTRY32 structures containing executable name, process id and process parent id. It is heavily documented, and you will easily find many examples on StackOverflow (see referenced question)

Community
  • 1
  • 1
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thank you sir, i will try this. But i allready have a SystemProcessesScan() and ScanProcessMemory(HANDLE hProcess) with a defined list of executables dumps. It cannot detect this cheat. I tryed tracing it, take a closer look but nothing. In previous versions of this hack, the program masked itself as rundll32.dll so it was easy for me to detect it, and close it by it`s pid. But the new version is killing me and others too :( This is the program(hack): http://www.filedropper.com/muautoclicker maybe if you have some time you can take a look... – Mr.Mecanik Jan 09 '15 at 10:54
  • @Mr.Mecanik This posts answers the question *how to see what program launched another one*. But for the real problem of avoiding cheating, it is really a dirty hack and you should consider in a future version passing a secret, or better a hash of that secret and the time of launching to have a unique token. – Serge Ballesta Jan 09 '15 at 10:55
  • Thanks for answering me, but please if you have time, can you take a look at the cheat? it`s really advanced and interesting... – Mr.Mecanik Jan 09 '15 at 10:57
  • @Mr.Mecanik : it looks like an interesting problem, but DevSolar was right, I don't think it only depends on finding how a program was launched ... and I'm not sure it is really on-topic here :-(. My advice : clearly analyse how muautoclicker interacts with your program, but if it send keystrokes and mouse clicks to your program via the API, it will really be hard, to identify that ! – Serge Ballesta Jan 09 '15 at 11:12
  • I have managed to block some keys used by that, but that is not the main problem, the cheat has special commands like: //multihit, //stealth, if you type those in-game. I cannot block those because i don`t know how. Anyway the program send packets to the game, maybe if i could block that uhm – Mr.Mecanik Jan 09 '15 at 11:17