📄 system.c
字号:
} 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -