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
|
||||
|
||||
PLUGINFUNCTIONSHORT(Free)
|
||||
{
|
||||
GlobalFree((HANDLE) popint64());
|
||||
}
|
||||
PLUGINFUNCTIONEND
|
||||
|
||||
PLUGINFUNCTION(Store)
|
||||
{
|
||||
TempStack *tmp;
|
||||
|
|
|
@ -42,6 +42,7 @@ int LastStackReal;
|
|||
DWORD LastError;
|
||||
volatile SystemProc *LastProc;
|
||||
int CallbackIndex;
|
||||
CallbackThunk* CallbackThunkListHead;
|
||||
HINSTANCE g_hInstance;
|
||||
|
||||
// Return to callback caller with stack restore
|
||||
|
@ -136,6 +137,36 @@ PLUGINFUNCTION(Debug)
|
|||
|
||||
#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)
|
||||
{
|
||||
SystemProc *proc = PrepareProc(FALSE);
|
||||
|
@ -917,13 +948,22 @@ HANDLE CreateCallback(SystemProc *cbproc)
|
|||
cbproc->CallbackIndex = ++(CallbackIndex);
|
||||
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
|
||||
*((int *)mem) = (int) cbproc;
|
||||
mem += sizeof(int);
|
||||
*(mem++) = (char) 0xe9; // Jmp relative
|
||||
*((int *)mem) = (int) RealCallBack;
|
||||
*((int *)mem) -= ((int) mem) + 4;
|
||||
#else
|
||||
#error "Asm thunk not implemeted for this architecture!"
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// Return proc address
|
||||
|
@ -1043,6 +1083,7 @@ BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
|
|||
LastError = 0;
|
||||
LastProc = NULL;
|
||||
CallbackIndex = 0;
|
||||
CallbackThunkListHead = NULL;
|
||||
retexpr[0] = (char) 0xC2;
|
||||
retexpr[2] = 0x00;
|
||||
}
|
||||
|
|
|
@ -101,6 +101,34 @@ struct tag_SystemProc
|
|||
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 HANDLE CreateCallback(SystemProc *cbproc);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue