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:
anders_k 2009-12-21 21:25:45 +00:00
parent a2b3b82ed9
commit 32fda4e830
3 changed files with 70 additions and 7 deletions

View file

@ -56,12 +56,6 @@ PLUGINFUNCTIONSHORT(Copy)
}
PLUGINFUNCTIONEND
PLUGINFUNCTIONSHORT(Free)
{
GlobalFree((HANDLE) popint64());
}
PLUGINFUNCTIONEND
PLUGINFUNCTION(Store)
{
TempStack *tmp;

View file

@ -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;
}

View file

@ -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);