📄 system.c
字号:
push ebp // Save previous stack location mov LastStackReal, esp } if (LastStackPlace == 0) { _asm { // Create new stack mov eax, NEW_STACK_SIZE call _alloca_probe mov LastStackPlace, esp } } else _asm { // Move stack pointer mov esp, LastStackPlace } } // Push arguments to stack for (z1 = proc->ParamCount; z1 > 0; z1--) { // Long types if (proc->Params[z1].Size == 2) { z2 = proc->Params[z1]._value; _asm push z2; } // Default z2 = proc->Params[z1].Value; _asm push z2; } // Call the proc and save return z1 = (int) proc->Proc; // Save proc proc->Clone = (SystemProc *) LastProc; _asm { mov eax, proc mov LastProc, eax } //LastProc = proc; SYSTEM_EVENT("\n\t\t\tNear call ") SYSTEM_LOG_POST; // workaround for bug #1535007 // http://sf.net/tracker/index.php?func=detail&aid=1535007&group_id=22049&atid=373085 // // If a function returns short and doesn't clear eax in the process, // it will only set 2 bytes of eax, and the other 2 bytes remain // "random". In this case, they'll be part of the proc pointer. // // To avoid this, eax is cleared before the function is called. This // makes sure the value eax will contain is only what the function // actually sets. _asm xor eax, eax _asm { // Call call z1 // Return mov z1, eax mov z2, edx } SYSTEM_LOG_ADD("Back from "); SYSTEM_LOG_ADD(LastProc->ProcName); SYSTEM_EVENT("\n\t\t\tShort-After call ") if ((CallbackIndex) && (!(LastProc->Options & POPT_GENSTACK))) { _asm { // Restore real stack location mov LastStackPlace, esp mov esp, LastStackReal pop ebp } } // Restore proc _asm { mov eax, LastProc mov proc, eax }// proc = LastProc; LastProc = proc->Clone; // In case of cdecl convention we should clear stack if ((proc->Options & POPT_CDECL) != 0) { if ((CallbackIndex > 0) && ((proc->Options & POPT_GENSTACK) == 0)) { // In case of temporary stack for (z3 = 1; z3 <= proc->ParamCount; z3++) LastStackPlace += 4*proc->Params[z3].Size; } else { // in case of real stack for (z3 = 1; z3 <= proc->ParamCount; z3++) { if (proc->Params[z3].Size == 2) _asm pop edx; _asm pop edx; } } } // In case of cleared call-proc-queue -> clear allocated stack place (more flexible) if (LastProc == NULL) LastStackPlace = (int) NULL; // Save return proc->Params[0].Value = z1;// if (proc->Params[0].Size == 2) proc->Params[0]._value = z2; // Proc result: OK proc->ProcResult = PR_OK; // In case of POPT_ERROR -> GetLastError if ((proc->Options & POPT_ERROR) != 0) { LastError = GetLastError(); } SYSTEM_EVENT("\n\t\t\tAfter call ")#ifdef SYSTEM_LOG_DEBUG { char buf[1024]; wsprintf(buf, "\n\t\t\tReturn 0x%08X 0x%08X", z1, z2); SYSTEM_LOG_ADD(buf); }#endif SYSTEM_LOG_POST; _asm { // Return mov eax, proc // Restore registers pop esi pop edi pop ebx // Restore stack pointer mov esp, ebp pop ebp // Return ret }}SystemProc __declspec(naked) *RealCallBack(){ SystemProc *proc; _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 // Arguments pointer mov z2, esp // 1-st arg - 4*4 (pushes) - 4 (return) - __LOCAL_SIZE add z2, __LOCAL_SIZE add z2, 5*4 // Our callback proc mov proc, eax } SYSTEM_LOG_ADD("Called callback from "); SYSTEM_LOG_ADD(LastProc->ProcName); SYSTEM_EVENT("\n\t\t\tShort-After call ") SYSTEM_LOG_POST; // Find last unused clone while ((proc->Clone != NULL)) proc = proc->Clone; // 2. Create new clone proc = (proc->Clone = GlobalCopy(proc)); // 3. Set clone option proc->Options |= POPT_CLONE; // Read arguments proc->ArgsSize = 0; for (z1 = 1; z1 <= proc->ParamCount; z1++) { // Default proc->Params[z1].Value = *(((int*)z2)++); proc->ArgsSize += 4; // Long only if (proc->Params[z1].Size == 2) { proc->Params[z1]._value = *(((int*)z2)++); proc->ArgsSize += 4; } } proc->ProcResult = PR_CALLBACK; _asm { // Return mov eax, proc // Save temporary stack info push ebp// push LastStackPlace mov LastStackPlace, esp // Restore real stack mov esp, LastStackReal pop ebp// pop LastStackReal } _asm { // Fake return from System::Call // Restore registers pop esi pop edi pop ebx // Restore stack pointer mov esp, ebp pop ebp // Return ret }}SystemProc __declspec(naked) *CallBack(SystemProc *proc){ _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 } // MessageBox(NULL, "cool1", "Cool", MB_OK); SYSTEM_LOG_ADD("\t\tReturn from callback:\n"); SYSTEM_EVENT("\t\t\tBefore call-back "); SYSTEM_LOG_POST; //z1 = proc->Params[0].Value; //z2 = proc->Params[0]._value; //z1 = &(proc->Params[0].Value); _asm { mov eax, proc add eax, SYSTEM_ZERO_PARAM_VALUE_OFFSET push [eax] push [eax+4] } // Adjust return statement if ((proc->Options & POPT_CDECL) == 0) retexpr[1] = proc->ArgsSize; else retexpr[1] = 0x0; // Right return statement address retaddr = (HANDLE) retexpr; // Remove unneeded callback proc GlobalFree((HANDLE) proc);// MessageBox(NULL, "cool2", "Cool", MB_OK); _asm { // Prepare return // callback proc result pop edx pop eax // Restore temporary stack and return // Save real stack info // Save previous stack location// push LastStackReal push ebp mov LastStackReal, esp // Move stack pointer mov esp, LastStackPlace// pop LastStackPlace pop ebp } #ifdef SYSTEM_LOG_DEBUG _asm { push eax push edx } SYSTEM_EVENT("\n\t\t\tSh-Before call-back"); SYSTEM_LOG_POST; _asm { // callback proc result pop edx pop eax }#endif // Fake return from Callback _asm { // Restore registers pop esi pop edi pop ebx // Restore stack pointer mov esp, ebp pop ebp // Return jmp retaddr }}HANDLE CreateCallback(SystemProc *cbproc){ char *mem; if (cbproc->Proc == NULL) { // Set callback index cbproc->CallbackIndex = ++(CallbackIndex); cbproc->Options |= POPT_PERMANENT; mem = (char *) (cbproc->Proc = VirtualAlloc(NULL, 10, MEM_COMMIT, PAGE_EXECUTE_READWRITE)); *(mem++) = (char) 0xB8; // Mov eax, const *(((int *)mem)++) = (int) cbproc; *(mem++) = (char) 0xe9; // Jmp relative *((int *)mem) = (int) RealCallBack; *((int *)mem) -= ((int) mem) + 4; } // Return proc address return cbproc->Proc;}void CallStruct(SystemProc *proc){ BOOL ssflag; int i, structsize = 0, size = 0; char *st, *ptr; SYSTEM_LOG_ADD("\t\tStruct..."); // Calculate the structure size for (i = 1; i <= proc->ParamCount; i++) if (proc->Params[i].Option < 1) structsize += proc->Params[i].Size * 4; else structsize += proc->Params[i].Option-1; // Struct exists? if (proc->Proc == NULL) // No. Allocate struct memory proc->Proc = (HANDLE) GlobalAlloc(GPTR, structsize); else // In case of zero size defined structure use mapped size if (structsize == 0) structsize = (int) GlobalSize((HANDLE) proc->Proc); // Pointer to current data st = (char*) proc->Proc; for (i = 1; i <= proc->ParamCount; i++) { ssflag = FALSE; // Normal or special block? if (proc->Params[i].Option < 1) { // Normal size = proc->Params[i].Size*4; ptr = (char*) &(proc->Params[i].Value); } else { int intmask[4] = {0xFFFFFFFF, 0x000000FF, 0x0000FFFF, 0x00FFFFFF}; // Special size = proc->Params[i].Option-1; switch (proc->Params[i].Type) { case PAT_VOID: ptr = NULL; break; case PAT_LONG: // real structure size proc->Params[i].Value = structsize; proc->Params[i]._value = 0; ssflag = TRUE; case PAT_INT: // clear unused value bits proc->Params[i].Value &= intmask[((size >= 0) && (size < 4))?(size):(0)]; // pointer ptr = (char*) &(proc->Params[i].Value); break; case PAT_STRING: case PAT_GUID: case PAT_WSTRING: ptr = (char*) proc->Params[i].Value; break; } } // Process them! if (ptr != NULL) { // Input if ((proc->Params[i].Input != IOT_NONE) || (ssflag)) copymem(st, ptr, size); // Output if (proc->Params[i].Output != IOT_NONE) copymem(ptr, st, size); } // Skip to next data block st += size; } SYSTEM_LOG_POST; // Proc virtual return - pointer to memory struct proc->Params[0].Value = (int) proc->Proc;}#endif /* __GNUC__ */BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved){ g_hInstance=hInst; if (ul_reason_for_call == DLL_PROCESS_ATTACH) { // change the protection of return command VirtualProtect(&retexpr, sizeof(retexpr), PAGE_EXECUTE_READWRITE, &LastStackPlace); // initialize some variables LastStackPlace = 0; LastStackReal = 0; LastError = 0; LastProc = NULL; CallbackIndex = 0; retexpr[0] = (char) 0xC2; retexpr[2] = 0x00; } return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -