System Plugin: Fixed callback proc numbers and memleak in Free()
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6016 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
a2b3b82ed9
commit
32fda4e830
3 changed files with 70 additions and 7 deletions
|
@ -56,12 +56,6 @@ PLUGINFUNCTIONSHORT(Copy)
|
||||||
}
|
}
|
||||||
PLUGINFUNCTIONEND
|
PLUGINFUNCTIONEND
|
||||||
|
|
||||||
PLUGINFUNCTIONSHORT(Free)
|
|
||||||
{
|
|
||||||
GlobalFree((HANDLE) popint64());
|
|
||||||
}
|
|
||||||
PLUGINFUNCTIONEND
|
|
||||||
|
|
||||||
PLUGINFUNCTION(Store)
|
PLUGINFUNCTION(Store)
|
||||||
{
|
{
|
||||||
TempStack *tmp;
|
TempStack *tmp;
|
||||||
|
|
|
@ -42,6 +42,7 @@ int LastStackReal;
|
||||||
DWORD LastError;
|
DWORD LastError;
|
||||||
volatile SystemProc *LastProc;
|
volatile SystemProc *LastProc;
|
||||||
int CallbackIndex;
|
int CallbackIndex;
|
||||||
|
CallbackThunk* CallbackThunkListHead;
|
||||||
HINSTANCE g_hInstance;
|
HINSTANCE g_hInstance;
|
||||||
|
|
||||||
// Return to callback caller with stack restore
|
// Return to callback caller with stack restore
|
||||||
|
@ -136,6 +137,36 @@ PLUGINFUNCTION(Debug)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PLUGINFUNCTIONSHORT(Free)
|
||||||
|
{
|
||||||
|
HANDLE memtofree = (HANDLE)popint64();
|
||||||
|
|
||||||
|
if (CallbackThunkListHead)
|
||||||
|
{
|
||||||
|
CallbackThunk *pCb=CallbackThunkListHead,*pPrev=NULL;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (GetAssociatedSysProcFromCallbackThunkPtr(pCb) == (SystemProc*)memtofree)
|
||||||
|
{
|
||||||
|
if (pPrev)
|
||||||
|
pPrev->pNext=pCb->pNext;
|
||||||
|
else
|
||||||
|
CallbackThunkListHead=pCb->pNext;
|
||||||
|
|
||||||
|
--(CallbackIndex);
|
||||||
|
VirtualFree(pCb,0,MEM_RELEASE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pPrev=pCb;
|
||||||
|
pCb=pCb->pNext;
|
||||||
|
}
|
||||||
|
while( pCb != NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalFree(memtofree);
|
||||||
|
}
|
||||||
|
PLUGINFUNCTIONEND
|
||||||
|
|
||||||
PLUGINFUNCTION(Get)
|
PLUGINFUNCTION(Get)
|
||||||
{
|
{
|
||||||
SystemProc *proc = PrepareProc(FALSE);
|
SystemProc *proc = PrepareProc(FALSE);
|
||||||
|
@ -917,13 +948,22 @@ HANDLE CreateCallback(SystemProc *cbproc)
|
||||||
cbproc->CallbackIndex = ++(CallbackIndex);
|
cbproc->CallbackIndex = ++(CallbackIndex);
|
||||||
cbproc->Options |= POPT_PERMANENT;
|
cbproc->Options |= POPT_PERMANENT;
|
||||||
|
|
||||||
mem = (char *) (cbproc->Proc = VirtualAlloc(NULL, 10, MEM_COMMIT, PAGE_EXECUTE_READWRITE));
|
mem = (char *) (cbproc->Proc = VirtualAlloc(NULL, sizeof(CallbackThunk), MEM_COMMIT, PAGE_EXECUTE_READWRITE));
|
||||||
|
|
||||||
|
((CallbackThunk*)mem)->pNext=CallbackThunkListHead;
|
||||||
|
CallbackThunkListHead=(CallbackThunk*)mem;
|
||||||
|
|
||||||
|
#ifdef SYSTEM_X86
|
||||||
*(mem++) = (char) 0xB8; // Mov eax, const
|
*(mem++) = (char) 0xB8; // Mov eax, const
|
||||||
*((int *)mem) = (int) cbproc;
|
*((int *)mem) = (int) cbproc;
|
||||||
mem += sizeof(int);
|
mem += sizeof(int);
|
||||||
*(mem++) = (char) 0xe9; // Jmp relative
|
*(mem++) = (char) 0xe9; // Jmp relative
|
||||||
*((int *)mem) = (int) RealCallBack;
|
*((int *)mem) = (int) RealCallBack;
|
||||||
*((int *)mem) -= ((int) mem) + 4;
|
*((int *)mem) -= ((int) mem) + 4;
|
||||||
|
#else
|
||||||
|
#error "Asm thunk not implemeted for this architecture!"
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return proc address
|
// Return proc address
|
||||||
|
@ -1043,6 +1083,7 @@ BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
|
||||||
LastError = 0;
|
LastError = 0;
|
||||||
LastProc = NULL;
|
LastProc = NULL;
|
||||||
CallbackIndex = 0;
|
CallbackIndex = 0;
|
||||||
|
CallbackThunkListHead = NULL;
|
||||||
retexpr[0] = (char) 0xC2;
|
retexpr[0] = (char) 0xC2;
|
||||||
retexpr[2] = 0x00;
|
retexpr[2] = 0x00;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,34 @@ struct tag_SystemProc
|
||||||
SystemProc *Clone;
|
SystemProc *Clone;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct tag_CallbackThunk CallbackThunk;
|
||||||
|
struct tag_CallbackThunk
|
||||||
|
{
|
||||||
|
#ifdef SYSTEM_X86
|
||||||
|
/*
|
||||||
|
#pragma pack(push,1)
|
||||||
|
char mov_eax_imm;
|
||||||
|
int sysprocptr;
|
||||||
|
char reljmp_imm;
|
||||||
|
int realprocaddr;
|
||||||
|
#pragma pack(pop)
|
||||||
|
*/
|
||||||
|
char asm[10];
|
||||||
|
#else
|
||||||
|
#error "Asm thunk not implemeted for this architecture!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CallbackThunk* pNext;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Free() only knows about pNext in CallbackThunk, it does not know anything about the assembly, that is where this helper comes in...
|
||||||
|
#ifdef SYSTEM_X86
|
||||||
|
# define GetAssociatedSysProcFromCallbackThunkPtr(pCbT) ( (SystemProc*) *(unsigned int*) (((char*)(pCbT))+1) )
|
||||||
|
#else
|
||||||
|
# error "GetAssociatedSysProcFromCallbackThunkPtr not defined for the current architecture!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern const int ParamSizeByType[]; // Size of every parameter type (*4 bytes)
|
extern const int ParamSizeByType[]; // Size of every parameter type (*4 bytes)
|
||||||
|
|
||||||
extern HANDLE CreateCallback(SystemProc *cbproc);
|
extern HANDLE CreateCallback(SystemProc *cbproc);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue