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 + -
显示快捷键?