NSIS Installation Protection

From NSIS Wiki
Jump to navigationJump to search
Author: Red Wine (talk, contrib)


Description

  • I copy here my last post from the forum.

I think the point is a research based on this:
Anything is possible. You just need to find a way to do it with the tools available. Just give it a good thinking.
Besides the fact that there is not uncracked software on the market, (even if they implement expensive protection schemes), the control of the usage on more than one machines, could be done only by a kind of an activation scheme. Any other protection is stuck on the local machine. The installer is not the "end user's software", is just the container, so the reasonable solution should be a kind of "user name-serial number" protection. Though, stick in "find a way to do it with the tools available", just carry out an experiment. An installer who counts the run times and expires after n times. No doubt that every user on this forum could easily break that scheme. Moreover, who really needs something like this? I think as a subject matter, has a point. With the tools available this is what I can do. In fact all the job is dependent on decrypt dll. And here comes where I end up. Download it and try it if you like. Probably, I'll post the code on wiki for reference.
P.S. even a system snapshot before/after is enough to break it.

  • Applies to NSIS 2.15

The Installer

!addplugindir 'plugin'  ; DcryptDll.dll makes all the job
 
!define guid '{8FA2807E-44D9-4A62-B399-D34D77EFFB91}'   ; fake not really needed
!define guid1 '{AE85911F-DCE0-4FF3-A771-3EEECBE831EC}'  ; also fake
 
outfile 'test.04.exe'
showinstdetails show
 
function .onInit  ; check if software is installed on this machine
SetShellVarContext all
ReadIniStr '$R1' '$WINDIR\decoder.dat' 'decode' 'mp3'
StrCmp '$R1' '' +1 +7
ReadRegStr '$R2' HKLM 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\encoder.exe' 'guid'
StrCmp '$R2' '' +1 +5
ReadRegStr '$R3' HKLM 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\decoder.exe' 'guid'
StrCmp '$R3' '' +1 +3
ReadIniStr '$R1' '$APPDATA\Microsoft\Media Player\encoder.dat' 'decode' 'mp3'
StrCmp '$R1' '' _notInstalled +1
IfFileExists '$SYSDIR\install.dat' _validate _nofile
 
_nofile: ; case is installed but missing install.dat
MessageBox MB_OK|MB_ICONSTOP 'Required file missing'
Quit
 
_notInstalled: ; see if really not installed check our secret record
ReadRegStr '$R2' HKLM 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\IEXPLORE.EXE' 'checksum'
strcmp '$R2' '' +3
messagebox mb_ok|mb_iconstop 'Hacked installation'
Quit
call notInstalled
 
_validate:
call validate
functionend
 
section -
DetailPrint 'counter is $R0'
strcmp $R0 '3' +1 +3
DetailPrint 'last run for this installation'
goto +2
DetailPrint 'you may proceed now'
sectionend
 
function notInstalled ; prepare a file that hold md5 checksum for counter's value
GetTempFileName $1
WriteIniStr '$1' 'decode' 'mp3' '1'
Rename $1 '$WINDIR\decoder.dat'
SetFileAttributes '$WINDIR\decoder.dat' HIDDEN
 
GetTempFileName $1  ; prepare the file that hold the counter and encrypt
WriteIniStr '$1' 'INSTALL' 'counter' '0'
DcryptDll::HexEncoder "FF" "$1" "$SYSDIR\install.dat" "--End--"
Delete $1
SetFileAttributes '$SYSDIR\install.dat' HIDDEN
 
GetTempFileName $1 ; decrypt counter and read value
DcryptDll::HexDecoder "FF" "$SYSDIR\install.dat" "$1" "--End--"
ReadIniStr $R0 "$1" 'INSTALL' 'counter'
Delete $1
 
DcryptDll::MD5Hash "SS" "$R0" "--End--"  ; create md5 checksum for value
 pop $4
 pop $5
    ; write checksum to holder and copy to other place
WriteIniStr '$WINDIR\decoder.dat' 'decode' 'format' '$5'
CopyFiles /SILENT '$WINDIR\decoder.dat' '$APPDATA\Microsoft\Media Player\encoder.dat'
SetFileAttributes '$APPDATA\Microsoft\Media Player\encoder.dat' HIDDEN
    ; write some reg check points
WriteRegStr HKLM 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\encoder.exe' '' ''
WriteRegStr HKLM 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\encoder.exe' 'guid' '${guid}'
WriteRegStr HKLM 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\decoder.exe' '' ''
WriteRegStr HKLM 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\decoder.exe' 'guid' '${guid1}'
functionend
 
Function validate ; decrypt counter and read value
GetTempFileName $1
DcryptDll::HexDecoder "FF" "$SYSDIR\install.dat" "$1" "--End--"
ReadIniStr $R0 "$1" 'INSTALL' 'counter'
 
DcryptDll::MD5Hash "SS" "$R0" "--End--"      ; create md5 checksum for value
 pop $4
 pop $5
           ; check points
ReadIniStr '$R1' '$APPDATA\Microsoft\Media Player\encoder.dat' 'decode' 'format'
strcmp '$R1' '$5' +1 _hacked
ReadIniStr '$R1' '$WINDIR\decoder.dat' 'decode' 'format'
strcmp '$R1' '$5' _prevalid _hacked
 
_hacked:
messagebox mb_ok|mb_iconstop 'Hacked installation'
Delete $1
quit
 
_prevalid: ; one more check point to our secret record
IntCmp '$R0' '2' _valid _valid +1
ReadRegStr '$R2' HKLM 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\IEXPLORE.EXE' 'checksum'
strcmp '$R2' '$5' _valid _stop
 
_valid:
Intcmp $R0 '2' +1 +1 _stop
Intop $R0 $R0 + 1
WriteIniStr "$1" 'INSTALL' 'counter' '$R0'
 
DcryptDll::MD5Hash "SS" "$R0" "--End--"
 pop $4
 pop $5
          ; in case we are captured on first run...
IntCmp '$R0' '2' +1 +2 +1 ; create the secret record after first run
WriteRegStr HKLM 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\IEXPLORE.EXE' 'checksum' '$5'
 
WriteIniStr '$APPDATA\Microsoft\Media Player\encoder.dat' 'decode' 'format' '$5'
WriteIniStr '$WINDIR\decoder.dat' 'decode' 'format' '$5'
Delete "$SYSDIR\install.dat"
DcryptDll::HexEncoder "FF" "$1" "$SYSDIR\install.dat" "--End--"
SetFileAttributes '$SYSDIR\install.dat' HIDDEN
Delete $1
goto _end
 
_stop:
messagebox mb_ok|mb_iconstop 'Installation expired'
Delete $1
Quit
 
_end:
FunctionEnd

License

This example NSIS script is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this script.

Permission is granted to anyone to use this script for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

  1. The origin of this script must not be misrepresented; you must not claim that you wrote the original code. If you use this script in a product, an acknowledgment in the product documentation would be appreciated but is not required.
  2. Altered versions must be plainly marked as such, and must not be misrepresented as being the original header file.
  3. This notice may not be removed or altered from any distribution.