system.c

来自「NullSofts criptable install system2.28源代」· C语言 代码 · 共 1,412 行 · 第 1/3 页

C
1,412
字号
                } else  *sbuf = 0; // No dll - system proc
                
                // Ok
                ChangesDone = PCD_DONE;
                break;
            case '*':
                // Structure defenition
                ProcType = PT_STRUCT;
                ChangesDone = PCD_DONE;
                break;
            }          
            break;

        // Params and return sections parser
        case PST_RETURN:
            ParamIndex = 0; // Uses the same logic as PST_PARAMS section
        case PST_PARAMS:
            temp2 = -1; temp4 = 0; // Our type placeholder
            switch (*ib)
            {
            case ' ':
                break;
            case '_': // No param cutting specifier
                if (proc->ParamCount > ParamIndex) ParamIndex = proc->ParamCount;
                temp3 = temp = 0; // Clear parameter options
                if (proc->ParamCount != ((ProcType == PT_VTABLEPROC) ? 1 : 0))
                {
                  // only define params if the last count wasn't zero
                  // this prevents errornous param count for:
                  //   'user32::CloseClipboard()(_)'
                  // for vtable calls, param count should not be one
                  param_defined = TRUE;
                }
                break;
            case ',': // Next param
                temp3 = temp = 0; // Clear parameter options
                ParamIndex++;
                param_defined = TRUE;
                break;
            case '&':
                temp = 1; break; // Special parameter option
            case '*':
                temp = -1; break; // Pointer parameter option

            // Types
            case 'v':
            case 'V': temp2 = PAT_VOID; break;
            case 'i':
            case 'I': temp2 = PAT_INT; break;
            case 'l':
            case 'L': temp2 = PAT_LONG; break;
            case 't':
            case 'T': temp2 = PAT_STRING; break;
            case 'g':
            case 'G': temp2 = PAT_GUID; break;
            case 'w':
            case 'W': temp2 = PAT_WSTRING; break;
            case 'k':
            case 'K': temp2 = PAT_CALLBACK; break;

            // Input output specifiers
            case '.': temp3++; break; // skip specifier

            case 'R':
                temp4 = ((int) GetIntFromString(&ib))+1;
                if (temp4 < 11) temp4 += 10; 
                break;
            case 'r': temp4 = ((int) GetIntFromString(&ib))+1; break; // Register

            case '-':
            case '0': case '1': case '2': case '3': case '4':
            case '5': case '6': case '7': case '8': case '9':
                // Numeric inline
                if (temp3 == 0)
                {
                    ib--;
                    // It's stupid, I know, but I'm too laze to do another thing
                    myitoa64(GetIntFromString(&(ib)),(char *)(temp4 = (int) AllocString()));
                }
                break;

            case '\"': case '\'': case '`':
                // Character inline
                {
                    char start = *ib;
                    cb = cbuf;
                    // copy inline
                    while (!((*(++ib) == start) && (*(ib+1) != start)) && (*ib))
                    {
                        if ((*ib) == start) ++ib;
                        *(cb++) = *(ib);
                    }
                    // finish and save
                    *cb = 0; 
                    temp4 = (int) AllocStr(cbuf);
                }
                break;

            case 's':
            case 'S': temp4 = -1; break;    // Stack
            case 'c':
            case 'C': temp4 = INST_CMDLINE+1; break;
            case 'd':
            case 'D': temp4 = INST_INSTDIR+1; break;
            case 'o':
            case 'O': temp4 = INST_OUTDIR+1; break;
            case 'e':
            case 'E': temp4 = INST_EXEDIR+1; break;
            case 'a':
            case 'A': temp4 = INST_LANG+1; break;
            }

            // Param type changed?
            if (temp2 != -1)
            {
                param_defined = TRUE;
                proc->Params[ParamIndex].Type = temp2;
                proc->Params[ParamIndex].Size = // If pointer, then 1, else by type
                    (temp == -1)?(1):((ParamSizeByType[temp2]>0)?(ParamSizeByType[temp2]):(1));
                // Get the parameter real special option value
                if (temp == 1) temp = ((int) GetIntFromString(&ib)) + 1;
                proc->Params[ParamIndex].Option = temp;
                proc->Params[ParamIndex].Value = 0;
                proc->Params[ParamIndex].Input = IOT_NONE;
                proc->Params[ParamIndex].Output = IOT_NONE;
            }
          
            // Param source/dest changed?
            if (temp4 != 0)
            {
                param_defined = TRUE;
                if (temp3 == 0)
                {
                    // it may contain previous inline input
                    if (!((proc->Params[ParamIndex].Input > -1) && (proc->Params[ParamIndex].Input <= __INST_LAST)))
                        GlobalFree((HANDLE) proc->Params[ParamIndex].Input);
                    proc->Params[ParamIndex].Input = temp4;
                }
                if (temp3 == 1)
                    proc->Params[ParamIndex].Output = temp4;
                // Next parameter is output or something else
                temp3++;
            }

            ChangesDone = PCD_DONE;
            break;

        // Options sections parser
        case PST_OPTIONS:
            temp2 = 0;
            switch (*ib)
            {
            case ' ':
                break;
            case '!': temp = -temp; break;
            case 'c':
                temp2 = POPT_CDECL;
                break;
            case 'r':
                temp2 = POPT_ALWRETURN;
                break;
            case 'n':
                temp2 = POPT_NEVERREDEF;
                break;
            case 's':
                temp2 = POPT_GENSTACK;
                break;
            case 'e':
                temp2 = POPT_ERROR;
                break;
            case 'u':
                temp2 = POPT_UNLOAD;
                break;
            }

            // New Options
            if (temp2 != 0)
            {
                if (temp == 1) proc->Options |= temp2;
                else proc->Options &= ~temp2;
                // Back to default (turn on nothing) state
                temp = 1; temp2 = 0;
            }

            ChangesDone = PCD_DONE;
            break;
        }

        // Nothing done, just copy char to buffer
        if (ChangesDone == PCD_NONE) *(cb++) = *(ib);
        // Something done, buffer = ""
        else cb = cbuf;

        // Increase input pointer
        ib++;
    }

    GlobalFree(ibuf);
    GlobalFree(cbuf);
    GlobalFree(sbuf);

    // Ok, the final step: check proc for existance
    if (proc != NULL && proc->Proc == NULL)
    {
        switch (proc->ProcType)
        {
        case PT_NOTHING: break;
        case PT_VTABLEPROC:
            {
                // Use direct system proc address
                int addr;

                proc->Dll = (HANDLE) myatoi(proc->DllName);
  
                if (proc->Dll == 0)
                {
                    proc->ProcResult = PR_ERROR;
                    break;
                }

                addr = (int) proc->Dll;

                // fake-real parameter: for COM interfaces first param is Interface Pointer
                proc->Params[1].Output = IOT_NONE;
                proc->Params[1].Input = (int) AllocStr(proc->DllName);
                proc->Params[1].Size = 1;
                proc->Params[1].Type = PAT_INT;
                proc->Params[1].Option = 0;

                // addr - pointer to interface vtable
                addr = *((int *)addr);
                // now addr contains the pointer to first item at VTABLE
                // add the index of proc
                addr = addr + (int)(myatoi(proc->ProcName)*4);
                proc->Proc = *((HANDLE*)addr);
            }
            break;
        case PT_PROC:
            if (*proc->DllName == 0)
            {
                // Use direct system proc address
                if ((proc->Proc = (HANDLE) myatoi(proc->ProcName)) == 0)
                    proc->ProcResult = PR_ERROR;
            } else
            {
                // Get DLL address
                if ((proc->Dll = GetModuleHandle(proc->DllName)) == NULL)
                    if ((proc->Dll = LoadLibrary(proc->DllName)) == NULL)
                    {
                        proc->ProcResult = PR_ERROR;
                        break;
                    }

                // Get proc address
                if ((proc->Proc = GetProcAddress(proc->Dll, proc->ProcName)) == NULL)
                {
                    // automatic A discover
                    lstrcat(proc->ProcName, "A");
                    if ((proc->Proc = GetProcAddress(proc->Dll, proc->ProcName)) == NULL)
                        proc->ProcResult = PR_ERROR;                            
                }                    
            }
            break;
        case PT_STRUCT:
            if (*(proc->ProcName) != 0) proc->Proc = (HANDLE) myatoi(proc->ProcName);
            break;
        }
    }

    return proc;
}

void ParamAllocate(SystemProc *proc)
{
    int i;

    for (i = 0; i <= proc->ParamCount; i++)
        if (((HANDLE) proc->Params[i].Value == NULL) && (proc->Params[i].Option == -1))
        {
            proc->Params[i].Value = (int) GlobalAlloc(GPTR, 4*ParamSizeByType[proc->Params[i].Type]);
        }
}

void ParamsIn(SystemProc *proc)
{
    int i, *place;
    char *realbuf;
    LPWSTR wstr;

    i = (proc->ParamCount > 0)?(1):(0);
    while (TRUE)
    {
        ProcParameter *par = &proc->Params[i];
        // Step 1: retrive value
        if ((par->Input == IOT_NONE) || (par->Input == IOT_INLINE)) 
            realbuf = AllocStr("");
        else if (par->Input == IOT_STACK) realbuf = popstring();
        else if ((par->Input > 0) && (par->Input <= __INST_LAST)) 
            realbuf = getuservariable(par->Input - 1);
        else 
        {
            // Inline input, will be freed as realbuf
            realbuf = (char*) par->Input;
            par->Input = IOT_INLINE;
        }

        // Retreive pointer to place
        if (par->Option == -1) place = (int*) par->Value;
        else place = (int*) &(par->Value);

        // by default no blocks are allocated
        par->allocatedBlock = NULL;

        // Step 2: place it
        switch (par->Type)
        {
        case PAT_VOID:
            par->Value = 0;
            break;
        case PAT_INT:
            *((int*) place) = (int) myatoi(realbuf);
            break;
        case PAT_LONG:
            *((__int64*) place) = myatoi(realbuf);
            break;
        case PAT_STRING:
/*            if (par->Input == IOT_NONE) 
                *((int*) place) = (int) NULL;
            else*/
            *((int*) place) = (int) (par->allocatedBlock = AllocStr(realbuf));
            break;
        case PAT_WSTRING:
        case PAT_GUID:
            wstr = (LPWSTR) (par->allocatedBlock = GlobalAlloc(GPTR, g_stringsize*2));
            MultiByteToWideChar(CP_ACP, 0, realbuf, g_stringsize, wstr, g_stringsize);
            if (par->Type == PAT_GUID)
            {
                *((HGLOBAL*)place) = (par->allocatedBlock = GlobalAlloc(GPTR, 16));
                CLSIDFromString(wstr, *((LPCLSID*)place));
                GlobalFree((HGLOBAL) wstr);
            } else
                *((LPWSTR*)place) = wstr;
            break;
        case PAT_CALLBACK:
            // Generate new or use old callback
            if (lstrlen(realbuf) > 0)
                par->Value = (int) CreateCallback((SystemProc*) myatoi(realbuf));
            break;
        }
        GlobalFree(realbuf);

#ifdef SYSTEM_LOG_DEBUG
        {
            char buf[1024];
            wsprintf(buf, "\t\t\tParam In %d:    type %d value 0x%08X value2 0x%08X\n", i, 
                par->Type, par->Value, par->_value);
            SYSTEM_LOG_ADD(buf);
        }
#endif

        if (i == 0) break;
        if (i == proc->ParamCount) i = 0;
        else i++;
    } 
}

void ParamsDeAllocate(SystemProc *proc)
{
    int i;

    for (i = proc->ParamCount; i >= 0; i--)
        if (((HANDLE) proc->Params[i].Value != NULL) && (proc->Params[i].Option == -1))
        {
            GlobalFree((HANDLE) (proc->Params[i].Value));
            proc->Params[i].Value = (int) NULL;
        }
}

void ParamsOut(SystemProc *proc)
{
    int i, *place;
    char *realbuf;
    LPWSTR wstr;

    i = proc->ParamCount;
    do
    {
        // Retreive pointer to place
        if (proc->Params[i].Option == -1) place = (int*) proc->Params[i].Value;
        else place = (int*) &(proc->Params[i].Value);

        realbuf = AllocString();

        // Step 1: retrive value
        switch (proc->Params[i].Type)
        {
        case PAT_VOID:
            lstrcpy(realbuf,"");
            break;
        case PAT_INT:
            wsprintf(realbuf, "%d", *((int*) place));
            break;
        case PAT_LONG:
            myitoa64(*((__int64*) place), realbuf);
            break;
        case PAT_STRING:
            {
                int num = lstrlen(*((char**) place));
                if (num >= g_stringsize) num = g_stringsize-1;
                lstrcpyn(realbuf,*((char**) place), num+1);
                realbuf[num] = 0;                
            }
            break;
        case PAT_GUID:
            wstr = (LPWSTR) GlobalAlloc(GPTR, g_stringsize*2);
            StringFromGUID2(*((REFGUID*)place), wstr, g_stringsize*2);
            WideCharToMultiByte(CP_ACP, 0, wstr, g_stringsize, realbuf, g_stringsize, NULL, NULL); 
            GlobalFree((HGLOBAL)wstr);
            break;
        case PAT_WSTRING:
            wstr = *((LPWSTR*)place);
            WideCharToMultiByte(CP_ACP, 0, wstr, g_stringsize, realbuf, g_stringsize, NULL, NULL);             
            break;
        case PAT_CALLBACK:
            wsprintf(realbuf, "%d", proc->Params[i].Value);
            break;
        }

        // memory cleanup
        if ((proc->Params[i].allocatedBlock != NULL) && ((proc->ProcType != PT_STRUCT)
            || (proc->Params[i].Option > 0)))
            GlobalFree(proc->Params[i].allocatedBlock);

        // Step 2: place it
        if (proc->Params[i].Output == IOT_NONE);
        else if (proc->Params[i].Output == IOT_STACK) pushstring(realbuf);
        else if (proc->Params[i].Output > 0) setuservariable(proc->Params[i].Output - 1, realbuf);

        GlobalFree(realbuf);

        i--;
    } 
    while (i >= 0);
}

void _alloca_probe();

SystemProc __declspec(naked) *CallProc(SystemProc *proc)
{
    int z3;

    _asm
    {
        // Save stack
        push    ebp
        mov     ebp, esp
        // Stack space for local variables
        sub     esp, __LOCAL_SIZE   
        // Save all usable registers to free our hands
        push    ebx
        push    edi
        push    esi
    }

    SYSTEM_LOG_ADD("\t\tCall:\n");
    SYSTEM_EVENT("\t\t\tBefore call        ")

    if (CallbackIndex && (!(proc->Options & POPT_GENSTACK)))
    {
        _asm
        {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?