Old 6th April 2016, 06:31   #1
Hugh
Junior Member
 
Join Date: Apr 2016
Posts: 11
Configuring $PLUGINSDIR and/or $TEMP

In an effort to combat malware, a customer has chosen to restrict read/write/execute access to their regular temp directory, and instead wishes to supply a custom temp directory for the installer to use. While this is fairly easy for the installer to do, it's another story when it comes to plug-ins. We are using MUI and System.dll, the former of which also relies on nsDialogs.dll. They all extract to $PLUGINSDIR (possibly before our script starts), which will fail in this scenario.

We are currently using NSIS 2.46.5, and are willing to upgrade if any of the newer builds feature configurable temp directories, though this functionality does not appear to be available yet. Earlier hacks such as using chngvrbl.dll do not appear to work. Any suggestions would be appreciated, thanks.
Hugh is offline   Reply With Quote
Old 6th April 2016, 11:36   #2
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,177
With NSIS3 you can do:
Quote:
Function .onInit
UnsafeStrCpy $pluginsdir "$localappdata\mytemp"
CreateDirectory $pluginsdir
FunctionEnd
Not sure if that is enough but you could try it in a non-solid installer...

For v2.x you can try the hack I posted in this thread.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 8th April 2016, 02:51   #3
Hugh
Junior Member
 
Join Date: Apr 2016
Posts: 11
Hi Anders, thanks for the quick reply. The approach seems to work, except a single System.dll is still being copied into the system temp directory, in a separate directory created (I assume by InitPluginsDir); System.dll is also extracted to the custom temp directory. I assume by solid/non-solid, you mean the compression method? In either case, it didn't seem to affect the outcome. The choice of temp directory is configurable, so we read it in using {$GetParameters} and {$GetOptions} first, thus UnsafeStrCpy isn't the first command being executed (but certainly comes shortly after we retrieve the custom temp directory). Could there be a race condition with InitPluginsDir? I assume if it works correctly, InitPluginsDir should create the temp plugins directory in the custom temp directory specified.

I did try your v2 hack, but this did not seem to change the temp dir behaviour of nsDialog and MUI. I'm not certain I understand the purpose of the second part of the hack ("Find the offset with:").
Hugh is offline   Reply With Quote
Old 8th April 2016, 12:45   #4
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,177
InitPluginsDir does not use the system plugin but those macros might, I don't remember.

$Temp can be set by doing Set Temp=c:\foo in cmd.exe and then running setup from the same console window.

For the v2 hack you need to first run the findoffset code on your machine and then replace the value in the first !define but if you are already on v3 you don't need it, it is just a hacky UnsafeStrCpy...

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 8th April 2016, 13:46   #5
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,363
Any reason why UnsafeStrCpy is undocumented?
Yathosho is offline   Reply With Quote
Old 8th April 2016, 16:49   #6
Hugh
Junior Member
 
Join Date: Apr 2016
Posts: 11
Getting closer: there were a number of conditionals using LogicLib in processing the command line, which I replaced with the built-in conditionals. This fixed the System.dll problem, however an ns*.tmp is still being created in the system temp directory. Is it possible to redirect the tmp file elsewhere prior to its creation?
Hugh is offline   Reply With Quote
Old 8th April 2016, 17:07   #7
Hugh
Junior Member
 
Join Date: Apr 2016
Posts: 11
I see, the ns*.tmp file is actually a function of solid vs. non-solid compression. I assume this is the limitation of altering $PLUGINSDIR using UnsafeStrCpy? Do you have a timeline for the release of NSIS 3.0?

Thanks for all the help so far, I appreciate it!
Hugh is offline   Reply With Quote
Old 8th April 2016, 20:28   #8
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,177
Quote:
Originally Posted by Yathosho View Post
Any reason why UnsafeStrCpy is undocumented?
Some of the constants documented in the help file are not actually constants ($PluginsDir, $ExePath etc.) and UnsafeStrCpy does allow you to set things StrCpy does not but that does not mean it is a good idea to modify them and they might not even be writable in the next version of NSIS.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 8th April 2016, 20:31   #9
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,177
Quote:
Originally Posted by Hugh View Post
I see, the ns*.tmp file is actually a function of solid vs. non-solid compression. I assume this is the limitation of altering $PLUGINSDIR using UnsafeStrCpy?
With the .onInit code I posted and using non-solid zlib compression there does not seem to be a ns*.tmp file nor folder in %temp% for me.


Quote:
Originally Posted by Hugh View Post
Do you have a timeline for the release of NSIS 3.0?
If there are no new bugs in rc1 after a couple of weeks then hopefully soon. Ideally we would wait until MS can clarify what to do about the GDI+ issue but that could take months.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 8th April 2016, 22:53   #10
Hugh
Junior Member
 
Join Date: Apr 2016
Posts: 11
Right, I just wanted to verify that only if using non-solid compression do you remove the reliance on the ns*.tmp file being generated. I'll assume the way it works now doesn't allow for the system temp directory used by the compression scheme to be modified before the script starts.

An issue I just noticed is that I'm also detecting an ~nsuA.tmp/Un_A.exe being created in the system temp directory on uninstall. Can this be modified using the same code (UnsafeStrCpy)?
Hugh is offline   Reply With Quote
Old 9th April 2016, 00:14   #11
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,177
First off I would like to say that I think this %temp% restriction is silly. Malware can just search the disks for a place where it is allowed to write.

The uninstaller is hardcoded to use %temp% to store a copy of itself (so you can delete the one in $instdir). The only way around it is to start it with the special _?= parameter. You could perhaps create a little app that copies the real uninstaller to $localappdata and then starts it with that parameter: Exec '"$localappdata\uninsthack.exe" _?=$exedir'

Edit:

The mini uninstaller might look something like this:

PHP Code:
!define MyTemp "$LocalAppData\MyTempHack"
SilentInstall silent
InstallDir $ExeDir


Section
CopyFiles 
/SILENT "$ExeDir\Uninst.bin" "${MyTemp}\Uninst.exe" Uninst.bin comes from WriteUninstaller in your installer
Exec 
'"${MyTemp}\Uninst.exe" /whatever _?=$ExeDir'
Quit
SectionEnd 

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 9th April 2016, 01:04   #12
Hugh
Junior Member
 
Join Date: Apr 2016
Posts: 11
I agree, but as this is a customer request, we would like to investigate its feasibility. A configurable temp directory isn't a terrible idea neither, given how historically Cryptolocker and a few other malware seem fairly inflexible in this regard. That could certainly change, but most of them continue to rely on the system temp dirs and this 'fix' seems to provide some comfort to these companies.

I'm trying to understand how the _?= parameter works...is it part of the script, or supplied via the command line? I assume you supply a path following '=', what path should be supplied? I've tried supplying the installation dir in the command line, and while it does prevent the creation of the temp uninstaller in the system temp directory, it also messes up the uninstallation source directory. If I provide the correct directory (with spaces) with quotes (single or double), it fails to start; if I provide it without quotes, it appears to be entered correctly but the uninstallation actually fails to remove most of the files. The uninstaller also takes a parameter to specify the temp directory used by the script, which hopefully doesn't interfere with this parameter.

When you mention to start 'Exec '"$localappdata\uninsthack.exe" _?=$instdir'', do you mean to insert the line at the beginning of a different script?
Hugh is offline   Reply With Quote
Old 9th April 2016, 11:39   #13
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,177
_?= is documented in the helpfile. It sets the value of $instdir in the uninstaller. It must be the last parameter and never quoted.

The Exec line was a example for a different script, a mini uninstall launcher that you build manually on your machine. Store the real uninstaller as uninst.dat or something like that, copy it to your temp and start it, and then quit. $exedir might come in handy here as the value for _?=.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 11th April 2016, 18:10   #14
Hugh
Junior Member
 
Join Date: Apr 2016
Posts: 11
Using _?=<path to uninstaller executable> appeared to do what I needed, while using my command line argument for setting a temp path to extract uninstaller dll's. There might be a more elegant solution, but since this currently works, I'll make a note that this is viable and conclude my investigation.

If I run into any further issues with this, I'll first try the mini-uninstall launcher before checking in again with any additional questions. Thanks for the assist Anders, I hope you continue your great work on NSIS and we'll be watching for the 3.0 release!
Hugh is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Tags
pluginsdir

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump