system.c
来自「NullSofts criptable install system2.28源代」· C语言 代码 · 共 1,412 行 · 第 1/3 页
C
1,412 行
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 + =
减小字号Ctrl + -
显示快捷键?