From f43be4183aa78f79b989aecd53472b6b151cd8c2 Mon Sep 17 00:00:00 2001 From: kichik Date: Fri, 23 Jul 2004 17:23:34 +0000 Subject: [PATCH] - fixes by brainsucker: * Bug with proc call parts redefinition, # for example * Bug with memory protection during callback processing (XP SP2) - updated documentation: * all examples now work, thanks to brainsucker's fixes * visual improvements * pointer information git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3590 212acab6-be3b-0410-9dea-997c60f758d6 --- Contrib/System/Source/System.c | 61 +++++++++++++++++++-------------- Contrib/System/System.html | 39 +++++++++++++-------- Contrib/System/WhatsNew.txt | 6 ++-- Plugins/System.dll | Bin 9216 -> 9216 bytes 4 files changed, 64 insertions(+), 42 deletions(-) diff --git a/Contrib/System/Source/System.c b/Contrib/System/Source/System.c index 2b204a43..1ce962f2 100644 --- a/Contrib/System/Source/System.c +++ b/Contrib/System/Source/System.c @@ -316,6 +316,7 @@ SystemProc *PrepareProc(BOOL NeedForCall) while (SectionType != -1) { // Check for Section Change + BOOL changed = TRUE; ChangesDone = SectionType; switch (*ib) { @@ -329,10 +330,12 @@ SystemProc *PrepareProc(BOOL NeedForCall) break; case ')': SectionType = PST_RETURN; temp3 = temp = 0; break; case '?': SectionType = PST_OPTIONS; temp = 1; break; + default: + changed = FALSE; } // Check for changes - if (ChangesDone != SectionType) + if (changed) { switch (ChangesDone) { @@ -366,9 +369,10 @@ SystemProc *PrepareProc(BOOL NeedForCall) if (proc != NULL) GlobalFree(proc); // Get already defined proc proc = (SystemProc *) myatoi(cbuf); + if (!proc) break; // Find the last clone at proc queue - while (proc->Clone != NULL) proc = (pr = proc)->Clone; + while (proc && (proc->Clone != NULL)) proc = (pr = proc)->Clone; // Clear parents record for child callback proc if (pr != NULL) pr->Clone = NULL; @@ -385,20 +389,21 @@ SystemProc *PrepareProc(BOOL NeedForCall) break; case PT_PROC: case PT_VTABLEPROC: - lstrcpy(proc->ProcName, cbuf); lstrcpy(proc->DllName, sbuf); - break; case PT_STRUCT: lstrcpy(proc->ProcName, cbuf); break; } - continue; + break; case PST_PARAMS: proc->ParamCount = ParamIndex; case PST_RETURN: case PST_OPTIONS: - continue; - } + break; + } + ib++; + cb = cbuf; + continue; } // Parse the section @@ -703,31 +708,32 @@ void ParamsIn(SystemProc *proc) i = (proc->ParamCount > 0)?(1):(0); while (TRUE) { + ProcParameter *par = &proc->Params[i]; // Step 1: retrive value - if ((proc->Params[i].Input == IOT_NONE) || (proc->Params[i].Input == IOT_INLINE)) + if ((par->Input == IOT_NONE) || (par->Input == IOT_INLINE)) realbuf = AllocStr(""); - else if (proc->Params[i].Input == IOT_STACK) realbuf = popstring(); - else if ((proc->Params[i].Input > 0) && (proc->Params[i].Input <= __INST_LAST)) - realbuf = getuservariable(proc->Params[i].Input - 1); + else if (par->Input == IOT_STACK) realbuf = popstring(); + else if ((par->Input > 0) && (par->Input <= __INST_LAST)) + realbuf = getuservariable(par->Input - 1); else { // Inline input, will be freed as realbuf - realbuf = (char*) proc->Params[i].Input; - proc->Params[i].Input = IOT_INLINE; + realbuf = (char*) par->Input; + par->Input = IOT_INLINE; } // Retreive pointer to place - if (proc->Params[i].Option == -1) place = (int*) proc->Params[i].Value; - else place = (int*) &(proc->Params[i].Value); + if (par->Option == -1) place = (int*) par->Value; + else place = (int*) &(par->Value); // by default no blocks are allocated - proc->Params[i].allocatedBlock = NULL; + par->allocatedBlock = NULL; // Step 2: place it - switch (proc->Params[i].Type) + switch (par->Type) { case PAT_VOID: - proc->Params[i].Value = 0; + par->Value = 0; break; case PAT_INT: *((int*) place) = (int) myatoi(realbuf); @@ -736,18 +742,18 @@ void ParamsIn(SystemProc *proc) *((__int64*) place) = myatoi(realbuf); break; case PAT_STRING: -/* if (proc->Params[i].Input == IOT_NONE) +/* if (par->Input == IOT_NONE) *((int*) place) = (int) NULL; else*/ - *((int*) place) = (int) (proc->Params[i].allocatedBlock = AllocStr(realbuf)); + *((int*) place) = (int) (par->allocatedBlock = AllocStr(realbuf)); break; case PAT_WSTRING: case PAT_GUID: - wstr = (LPWSTR) (proc->Params[i].allocatedBlock = GlobalAlloc(GPTR, g_stringsize*2)); + wstr = (LPWSTR) (par->allocatedBlock = GlobalAlloc(GPTR, g_stringsize*2)); MultiByteToWideChar(CP_ACP, 0, realbuf, g_stringsize, wstr, g_stringsize); - if (proc->Params[i].Type == PAT_GUID) + if (par->Type == PAT_GUID) { - *((HGLOBAL*)place) = (proc->Params[i].allocatedBlock = GlobalAlloc(GPTR, 16)); + *((HGLOBAL*)place) = (par->allocatedBlock = GlobalAlloc(GPTR, 16)); CLSIDFromString(wstr, *((LPCLSID*)place)); GlobalFree((HGLOBAL) wstr); } else @@ -756,7 +762,7 @@ void ParamsIn(SystemProc *proc) case PAT_CALLBACK: // Generate new or use old callback if (lstrlen(realbuf) > 0) - proc->Params[i].Value = (int) CreateCallback((SystemProc*) myatoi(realbuf)); + par->Value = (int) CreateCallback((SystemProc*) myatoi(realbuf)); break; } GlobalFree(realbuf); @@ -765,7 +771,7 @@ void ParamsIn(SystemProc *proc) { char buf[1024]; wsprintf(buf, "\t\t\tParam In %d: type %d value 0x%08X value2 0x%08X\n", i, - proc->Params[i].Type, proc->Params[i].Value, proc->Params[i]._value); + par->Type, par->Value, par->_value); SYSTEM_LOG_ADD(buf); } #endif @@ -1218,7 +1224,7 @@ HANDLE CreateCallback(SystemProc *cbproc) cbproc->CallbackIndex = ++(CallbackIndex); cbproc->Options |= POPT_PERMANENT; - mem = (char *) (cbproc->Proc = GlobalAlloc(GPTR, 10)); + mem = (char *) (cbproc->Proc = VirtualAlloc(NULL, 10, MEM_COMMIT, PAGE_EXECUTE_READWRITE)); *(mem++) = 0xB8; // Mov eax, const *(((int *)mem)++) = (int) cbproc; *(mem++) = 0xe9; // Jmp relative @@ -1323,6 +1329,9 @@ BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lp 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; diff --git a/Contrib/System/System.html b/Contrib/System/System.html index 5daeb37b..a41f9443 100644 --- a/Contrib/System/System.html +++ b/Contrib/System/System.html @@ -29,7 +29,7 @@

The System plug-in also allows the developer to allocate, free and copy memory; interact with COM objects and perform mathematical operations on 64-bit integers.

-

Programming knowledge is highly recommended in order to understand the System plug-in.

+

Programming knowledge is highly recommended for good understanding of the System plug-in.

Usage Examples From The Archive

@@ -173,9 +173,9 @@ DetailPrint $4

PARAMS, RETURN and OPTIONS can be repeated many times in one Get/Call line. When repeating, a lot can be omitted, and only what you wish to change can be used. Type, source and/or destination can be omitted for each parameter, even the return value. Options can be added or removed. This allows you to define function prototypes and save on some typing. The last two examples show this.

-

(can't get a working example) PROC can also be repeated but must be prefixed with a hash sign (`#').

+

PROC can also be repeated but must be prefixed with a hash sign (`#').

-

Possible PROC values and Meanings

+

Possible PROC Values and Meanings

@@ -284,6 +284,7 @@ DetailPrint $4
N bytes of GUID (structures only)
+

Additionally, each type can be prefixed with an asterisk to denote a pointer. When using an asterisk, the System plug-in still expects the value of the parameter, rather than the pointer's address. To pass a direct address, use `i' with no asterisk. A usage example is available. Alloc returns addresses and its return value should therefore be used with `i', without an asterisk.

Available Sources and Destinations

@@ -370,9 +371,10 @@ StrCmp $R0 "callback1" 0 +2 DetailPrint "UseCallback passed ($0, $1) to the callback" -

After you've processed the callback call, you should use Call, passing it the value returned by Get - the callback. This tells System to return from the callback. If you've specified a source for the return "parameter" when the callback was created, you should fill that source with the appropriate return value.

+

After you've processed the callback call, you should use Call, passing it the value returned by Get - the callback. This tells System to return from the callback. If you've specified a source for the return "parameter" when the callback was created, you should fill that source with the appropriate return value. Callbacks are not automatically freed, don't forget to free it after you've finished using it.

-
System::Call "(i .r0, i .r1) isR0"
+
SetPluginUnload alwaysoff
+System::Call "(i .r0, i .r1) isR0"
 Pop $0
 System::Call "dll::UseCallback(k r0)"
 loop:
@@ -382,6 +384,8 @@ loop:
 	System::Call $0 # tell system to return from the callback
 	Goto loop
 done:
+SetPluginUnload manual
+System::Free $0
 

A complete working example is available in the usage examples section.

@@ -456,6 +460,12 @@ Pop $0 System::Call "$0(, 'This is a System::Get test', 'NSIS System Plug-in',)"
+System::Call "advapi32::GetUserName(t .r0, *i ${NSIS_MAX_STRLEN} r1) i.r2"
+DetailPrint "User name - $0"
+DetailPrint "String length - $1"
+DetailPrint "Return value - $2"
+
+
 System::Alloc 4
 Pop $0
 System::Call "*$0(i 5)"
@@ -519,8 +529,8 @@ System::Call "${MB}(,'another message',,) i.r0"
 MessageBox MB_OK "last call returned $0"
 
-System::Call "user32::MessageBox(i $HWNDPARENT, t 'test', t 'test', i 0) i.s ? \
-	e (,t'test replacement',,) i.r0 ? !e"
+System::Call "user32::SendMessage(i $HWNDPARENT, t 'test', t 'test', i 0) i.s ? \
+	e (,t'test replacement',,) i.r0 ? !e #user32::MessageBox"
 DetailPrint $0
 ClearErrors
 Pop $0
@@ -593,12 +603,14 @@ DetailPrint "0x89498A198E4566C % 157 = $0" # 118
 
 System::Int64Op 0xF0F0F0F | 0xF0F0FFF
 Pop $0
+# IntFmt is 32-bit, this is just for the example
 IntFmt $0 "0x%X" $0
 DetailPrint "0xF0F0F0F | 0xF0F0FFF = $0" # 0xF0F0FFF
 
 System::Int64Op 0x12345678 & 0xF0F0F0F0
 Pop $0
+# IntFmt is 32-bit, this is just for the example
 IntFmt $0 "0x%X" $0
 DetailPrint "0x12345678 & 0xF0F0F0F0 = $0" # 0x10305070
 
@@ -618,9 +630,9 @@ Pop $0 DetailPrint "1 && 0 = $0" # 0
-System::Int64Op 5168 < 89873
+System::Int64Op 9302157012375 < 570197509190760
 Pop $0
-DetailPrint "5168 < 89873 = $0" # 1
+DetailPrint "9302157012375 < 570197509190760 = $0" # 1
 
 System::Int64Op 5168 > 89873
@@ -633,10 +645,9 @@ Pop $0
 DetailPrint "189189 = 189189 = $0" # 1
 
-System::Int64Op 1 ~
+System::Int64Op 156545668489 ~
 Pop $0
-IntFmt $0 "0x%X" $0
-DetailPrint "1 ~ = $0" # 0xFFFFFFFE
+DetailPrint "1 ~ = $0" # -156545668490
 
 System::Int64Op 1 !
@@ -670,7 +681,7 @@ System::Alloc 16
 
-System::Call "*(i, i, i, t).s"
+System::Call "*(i, i, i, t)i.s"
 
@@ -680,7 +691,7 @@ System::Call "*(i, i, i, t).s"

Setting data can be done using Call. It can be done in the allocation stage, or in another stage using the struct handling syntax.

-System::Call "*(i 5, i 2, i 513, t 'test')"
+System::Call "*(i 5, i 2, i 513, t 'test')i.s"
 
diff --git a/Contrib/System/WhatsNew.txt b/Contrib/System/WhatsNew.txt
index eb3042f4..068613e5 100644
--- a/Contrib/System/WhatsNew.txt
+++ b/Contrib/System/WhatsNew.txt
@@ -39,6 +39,8 @@ release 5, 11 september 2003.
 
 bug-fix-release, 4.06.2004
 1. System::Copy /SIZE fixed (Kichik).
-2. System::Alloc with destination auto-allocation now pushes destination
+2. System::Copy with destination auto-allocation now pushes destination
 address on stack.
-3. Callbacks fixed (Kichik's kick is awesome).
\ No newline at end of file
+3. Callbacks fixed (Kichik's kick is awesome).
+4. Bug with proc call parts redefinition, # for example (pointed by Kichik).
+5. Bug with memory protection during callback processing (Kichik).
\ No newline at end of file
diff --git a/Plugins/System.dll b/Plugins/System.dll
index c6c205560ff23fbf671007c3cbf6518f42d1b020..a6c7f440ee0346a2f060971b8757f7b6d77fcd0c 100644
GIT binary patch
delta 2661
zcmcImjdK&n72lI(>m+}i43e>p!ICi_!9e6YNj8$Pgz*`f!9k$dMhzG!0UX6`2t5&!
zU|ZxY!}($cX2Y~;T0W9Ev}q?Pb%sf&tt%jWbYK|TFb%0`aHs>PIUr6kpn~E0?!Yto
z2f8yqz4w0mcHi#Xce{!OVu3xe&IS8ky!+~CdfzxAV=Mb!2m3zA?HaG|i-6=Wu$sL+
zwXv@q?Cq&=-!@II(d3F3*0-v2peHTJBD9pyqrzJW|2Q{MeYPD9%7ZgnmolmvxNZfzZmm_R07HK@$JMUlKD32PSmO2&sR$?xCI-
zz{?DkL>%ujR1pDu($E7=L9&fp=|JY7Vy(rWkuT2Wz-U&iSs>&Yd`gKLTH91z=2Jw}
zsvP~91)_&}Ot1|^68FA+6{q}3EcVe!&k
z-V9sOH*r%#QV_2*EwQI(LPvxQ_eO_q_sNEkG-?8Ze_cqFz55Hr}+EUX^J>$0uOCFw^gMG@G`Qe2Z41vVwJ!(w}?
zXOh5Pq6UtOXUfiUAwD^ctK*aDTvdmSA(pUuNY?WW!-~jWDm%eh162H<;3Bf4LbnArm^=rT_qNDN_>G*>&N{Mp
zfYc)-Li#S!oAFtKOh5mAMm^jrpl#Ho6X&5d$OLg7RAyiLwO@;k~uxKK_406OvcCMb6
zYB*mYz}b1p$mR2ro}&UB83;t_h+oc$m}OH$FK0wZzpRVcRx*EGIKN?xivI;{8;izYW5Q83C&68Y~LLF-^o9
zf$nV~L(=qnu(MQL2@3;iZmF&cb)6psL5Jcjy^B-SjH)Yl6(t-NDN(;88HEY%U9f9Q
z5gNvlwGc~KJ<2D(Vg~tCBefH9tx!i}8;ap9O5;ZS19RaF6L9>7F~n~eK?*yXybmjU
zQZLC{pz{r5O7a{0bMus-Av~DP
zow?}42eA4}i}(kb?Q#BuNsg&*`yP|Y&1%s05k$r1hoCm3q|KwMyXx~Y_^b$uC#2W#
z$GL98g|Fp4-PsbmKbJGb?t7wZL5t@0E+%4?)luVVb_kLJpQlE6qBW}D0$|kw*FF`=
z%ih>(fzpFIg;IQ6iOB*8E3%h?OXh$I10Z)OsncjlVWnN>Bm$$iTP^cgW+kNmP4Eax
zYw)27MMMoAn6QLcg^d$uh4B<*{$UX^{}`|WunFu!z`p^X1HJ%U0nmUFfCn%eFbJpt
zoCVASyaHq0AS*yNgItAsCT=ITVS{B#r?|9~WD@gtsNZ6UI*@3D8=|(Si=5f|92~0j
zHh6^j4!t5uy&Ys!FBZ!>@rsziZ!ALb1l9HIN!UBwmQ>d#nxdn+eyJ&GR981B)b7KY
zncgv*Pi0W?x4~*utaG%2p?3GErj!p+!{Uh4kPb&$vUsiO4z+HrGc~v<=O8_eY8v$DY9e_6h2LZnW90!~S3|@?z
ze$9Nu9A!>0XPAF5mzl4b>&ytFFzL=rXR)*18FC8Fz0RM8obNgR=u9}jbY5{@bJ|@l
zSDkBxYom*E#augGzi_?ly6hTu$*yl*DHq{3xGnB!?pf|ScZ>VD`wRDA#nlSA;=77e
V#ls3+rJ*vbazbT(CH#AP_J1V1w=Mtx

delta 2664
zcmb_ejdK&%5r0n~Se8Fd*p@N2@dt?51p|^!l4Z-W#K%nqjf+6oMhpf+pfv^(XeCId
z_$wy~j*A`WOFC&f4NRwov@;}~dP>5y52(DZe>+Iw3a8o!
zQa|WF2=;+gsQ*W*+^Wj;yIyRgYoM7cz#;Sk)}gY#gzp(Qin7ZyaGDVn0%K5FEy}4R
z8vOmNRy#r`fqLDFP=NH{VtoLi_b}P7VRe)`US345U;}N516dLC(vSuM9=ZRC&UK1$U{6ic`4@&(ELLu?$
zecl95qiYJ61f{phHshM|h754D8$!L2(Qo_Zw4hW+3H~QKyd~@rFG&vuJ~LvBx01^l
z>+lj%mbq1vHJkKgR^gAy`&r}x^eGNi*1&3emOy?CX(-(((L{3^f
z%tWUkho6aBU}+GAs)#k~z(2%GyhGz;7bng~JP*U#0Mp7{)Bn;BJFwq+D@WxXCFkq~o+#_Ew
z&vl)Hs8C2`L|sqvAgu7}XNJN}CZ9Y}l$j|^-UXd+m{yWWP+V+6Y?vInrRO`Q
zmEJm=aJT^03ulPB*gj}MEYYQf3V{;~hbzGo$?WA)QVBU@T8ewfh-n3`C#AD1Rz|1b
zVXv;_r!qQX{IF5(reQBXC6oK;ZaOB=Oi>$B(wa#cPGi0YG3x{3u(W{)vt5`WiP_7#
zTDu=D2^+f~)ke017RiC5=IeIXN765FqfkU7o1ZeZkrg!Zd7xo7k$Nb{Jlyz!JZKk8
zB<+_va>*j-rpS!|mo$M2H$bgXQm4{m3O9DdlvJh_MV;v^)a{0Ty$%rpshYf+Q;ZAA
z&vMq_4dhl%W$4^IWI9reOm6~S0rZ0H1EiNA(?gJt0ea9kg7gDg0RaF8t_|cJzy`oC
z;oi+4TR?VzjFauThwwgfGk0EBu(63vG>eBU1vQ6hhnW)zVU@)sZUzhwjp}%dL@A;ZOJ$9CQ;fezr+`1@fM3YKME?O2UeiqU6IIbL(KD)|WugQWrtd@5
z)ORl7Q?r=ZZ@_9)%vI_HF@5h)Q@TZSiWAZnJ#;E986#!+d1N$?X&Izx6mum+^Mf?8
zKC+fayNO`H?kry>eeG_m-)QFIvmFG4}tu&3G6@ofB
zqfuHVcP@uB%9rB8Khi2$DxnZ`eA1+8#
zM+)*6;ZW
zn0EYm_04D*z2MhxK4j2X82hb}IKJE0X
z2U$hdm8`5CfiL>AYZmo_T`&_(`7+?@fGhhSE&$vr>+$mZ|KnbqrMHN?Z1VzyN@xD2
zT!t+4FsIGn2-v>{B*-7iN(--nb`vlLNCLhA+yy+c4}4RWi%GY}sxu)pLiF>6dB~$!
zw0~~@%C2WK*-AFR9$?>K-(pX*AFyArSJ{8DGJA);&pu%@941GJ!{YdkW7#%`+womT
zgCpqpq2svY7mmLvrt#++-ZFcQ;?Q