https://www.dropbox.com/sh/b52w1i6aa8pq ... bWweCqPILa
June 30 - Fixed Dropbox Link
Updated August 12, 2013 - Version 1.4
Many Changes - Many thanks to Kilmatead from the xplorer2 forum and JHPJHP from the PureBasic forum.
* Unlock Dialog - Initially, the password dialog is forced to be in focus which means you can't do anything else until you close the dialog.
* A lot of tweaks and optimization. It should not feel very polished.
* Verify 7-zip encrypted file integrity before wiping the configuration file. If it fails for any reason, XYplorer.ini will not be wiped.
* Full Unicode support
* 7za.exe is now fully integrated into XYKeyCrypt. It will automatically unpack 7za.exe and then delete it when it finish. 7za.exe is also UPX compressed to reduce the size. XYKeyCrypt itself (not the embedded 7za.exe) however is not UPX compressed to prevent any possible false positives with AV software.
* Fully supports XYplorer command-line arguments. Any arguments you want to use for XYplorer can be passed directly to XYKeyCrypt.exe and it will pass it to XYplorer.
* Much better way of finding if XYplorer is launched or quit. It will now check the path of the process to find if it matches with the path that XYKeyCrypt launches itself. Basically you can use it at your friend's house and if they have their own process running, XYKeyCrypt can differentiate between them and will encrypt XYplorer.ini only when YOUR process ends.
Updated August 02, 2013 - Version 1.2
* Change wipe algorithm to something simple (3 pass vs 7 pass) but is standardized. Should also reduce wearing of flash drives.
* Added some extra password checks and input dialogs.
* Optimize code. Should perform a bit better.
* Added an extra 250 ms wait for a total of 1 second wait after XYplorer supposed quit to make sure XYploer really did quit (instead of restarting) before attempting to re-encrypt XYplorer.ini and then wiping the file.
Updated August 02, 2013 - Version 1.1
* Small bug fix.
Updated August 02, 2013 - Version 1.0
* Initial Release
XYplorer is portable so it's great to be able to bring it everywhere with you. However it would be nice to be able to protect the license key in case you lost your USB drive. Anyway I wrote this because I wanted to try PureBasic, the programming language this was written in. Anyway I don't guarantee anything but I hope you do at least find it somewhat useful. I most likely won't work on it anymore since it pretty much works.
"Why would you want to use file encryption when you could simply use whole disk encryption?"
Admin access. There are many places where you don't have admin access to the computer. Whole disk file encryption require admin access to install the drivers. With file encryption, you don't need admin access. I use XYplorer daily in school so admin access are generally really hard to get. I do have admin access in the lab that I work in for my thesis but that's 2 computers out of many computers. Therefore file encryption is the only way to go.
"Why should I encrypt XYplorer.ini anyways?
Good point. You don't. I just provide this simply because of how bare the license keys are for XYplorer and xplorer2 are. With xplorer2, if someone steaks the file and distribute the key, your key is going to get blacklisted sooner or later. With XYplorer, it won't but you're helping Don so that he has less headaches. Plus just in case you uhh... were surfing inappropriate files with rather raunchy names, you and sort of hide it.
Features
☆ Encrypt XYplorer.ini - Protects License Key
☆ Automatic Decryption & Re-Encryption - Can automatically decrypt XYplorer.ini and start XYplorer. Will automatically re-encrypt XYplorer.ini when you quit XYplorer.
☆ Use 7-Zip's Built-In AES256 Encryption
☆ Does Not Require Admin Access - Unlike Full Disk Encryption which requires Admin access due to loading drivers, this is a file type encryption method so no need for admin access. Can be used anywhere!
☆ Full Unicode Support
☆ Completely Support Command-Line Arguments - Any command-line arguments you want to pass to XYplorer can simply be passed on to XYKeyCrypt. Try it:
Code: Select all
XYKeyCrypt.exe /script="::msg 'Hello! XYKeyCrypt Success! ';"Setup
Put XYKeyCrypt to the root of XYplorer (together with XYplorer.exe). Now from now on, always run XYKeyCrypt.exe.
Code: Select all
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;XYKeyCrypt - Allows the Automatical Encryption and Decryption of XYplorer.ini to Protect License Key.
;Use 7-Zip Built-In AES256 Encryption
;1. Encrypt XYplorer.ini to XYplorer.dat
;2. Automatically Decrypt XYplorer.dat and Start XYplorer.exe
;3. Automatically Re-Encrypt XYplorer.ini After XYplorer Ends
;
;Icon Source: Icon Source: https://www.iconfinder.com/icondetails/12578/48/key_lock_password_icon
;7za.exe (7-Zip) Igor Pavlov. http://www.7-zip.org/
;http://www.pazera-software.com/products/free-upx/ UPX GUI - Used to Compress Executable and 7za.exe
;http://forums.purebasic.com/english/viewtopic.php?p=36475
;http://forum.purebasic.com/english/viewtopic.php?p=179733
;http://forum.purebasic.com/english/viewtopic.php?t=55806 - Major Thanks to JHPJHP
;
;Instructions: Extract 7za.exe and XYKeyCrypt.exe in Root Directory of XYplorer
;
;Thread at xplorer2 Support Forum: http://netez.com/bbs/viewtopic.php?f=18&t=10212
;Major Thanks to Kilmatead for all the help, suggestions, testing, and time.
;Thread at XYPlorer Support Forum: http://www.xyplorer.com/xyfc/viewtopic.php?t=10039
;
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
DataSection
SevenZipExe:
IncludeBinary "7za.exe"
SevenZipExe_E:
EndDataSection
RunFile.s = GetCurrentDirectory()+"\7za.exe"
CreateDirectory(GetPathPart(RunFile))
File.l = CreateFile(#PB_Any, RunFile)
WriteData(File, ?SevenZipExe, ?SevenZipExe_E-?SevenZipExe)
CloseFile(#PB_Any)
;http://forums.purebasic.com/english/viewtopic.php?p=129817
Procedure.s InputBox(txtw, txth, title$, prompt$, def$="", flags=0)
; A version of InputRequester() by BackupUser
; Modified by AKJ 18-Oct-06
; Downloaded: www.purebasic.fr/english/viewtopic.php?t=2412
; textw and txth are the outer dimensions of the prompt text gadget
; Available flags are:
; #PB_String_{BorderLess LowerCase Numeric Password ReadOnly Uppercase}
Protected winBox, txtPrompt, strInput, butOK, butCancel ; Gadgets
Protected box, ev, id, ret, esc, a, thread1, thread2, text$=""
If txtw<128 : txtw=128 : EndIf ; To show buttons correctly
If txth<20 : txth = 20 : EndIf ; Height of a normal text line
winBox=OpenWindow(#PB_Any,0,0,txtw+13,txth+20+23+8*4,title$,#PB_Window_ScreenCentered)
box=WindowID(winBox)
If winBox And UseGadgetList(box)
txtPrompt=TextGadget(#PB_Any,6,8,txtw,txth,prompt$)
If flags&#PB_String_Password=0 : flags|#ES_MULTILINE : EndIf
strInput=StringGadget(#PB_Any,6,txth+8*2,txtw,20,def$,flags|#ES_AUTOVSCROLL)
butOK=ButtonGadget(#PB_Any,6,txth+20+8*3,60,23,"OK") ; Set x=txtw-122 for button to be on the right
butCancel=ButtonGadget(#PB_Any,txtw-54,txth+20+8*3,60,23,"Cancel")
SendMessage_(GadgetID(strInput),#EM_SETSEL,0,Len(def$))
GetAsyncKeyState_(#VK_RETURN) : GetAsyncKeyState_(#VK_ESCAPE)
StickyWindow(winBox,#True) : SetForegroundWindow_(box) : SetActiveGadget(strInput) : MessageBeep_(#MB_ICONQUESTION)
Repeat
ev=WaitWindowEvent(1) : id=EventGadget() : ret=GetAsyncKeyState_(#VK_RETURN) : esc=GetAsyncKeyState_(#VK_ESCAPE)
a=GetForegroundWindow_()
If a<>box
thread1=GetWindowThreadProcessId_(@a,0) : thread2=GetWindowThreadProcessId_(@box,0)
If thread1<>thread2 : AttachThreadInput_(thread1,thread2,#True) : EndIf
If thread1<>thread2 : AttachThreadInput_(thread1,thread2,#False) : EndIf
SetActiveGadget(strInput)
EndIf
Until (ev=#PB_Event_Gadget And (id=butOK Or id=butCancel)) Or ret<>0 Or esc<>0 Or ev=#PB_Event_CloseWindow
If id=butOK Or ret<>0 : text$=GetGadgetText(strInput) : Else : text$=def$ : EndIf
CloseWindow(winBox)
EndIf
ProcedureReturn text$
EndProcedure
;JHPJHP @ http://www.purebasic.fr/english/viewtopic.php?f=13&t=55806
Prototype.i protoGetProcessImageFileName(hProcess, lpImageFileName, nSize)
Global GetProcessImageFileName.protoGetProcessImageFileName
Prototype.b protoQueryFullProcessImageName(hProcess, dwFlags, lpExeName, lpdwSize)
Global QueryFullProcessImageName.protoQueryFullProcessImageName
Procedure.b AdjustCurrentProcessPrivilege()
Result.b = #False
If OpenProcessToken_(GetCurrentProcess_(), #TOKEN_ADJUST_PRIVILEGES | #TOKEN_QUERY, @TokenHandle)
lpLuid.LUID
If LookupPrivilegeValue_(#Null, #SE_DEBUG_NAME, @lpLuid)
NewState.TOKEN_PRIVILEGES
With NewState
\PrivilegeCount = 1
\Privileges[0]\Luid\LowPart = lpLuid\LowPart
\Privileges[0]\Luid\HighPart = lpLuid\HighPart
\Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
EndWith
Result = AdjustTokenPrivileges_(TokenHandle, #False, @NewState, SizeOf(TOKEN_PRIVILEGES), @PreviousState.TOKEN_PRIVILEGES, @ReturnLength)
EndIf
CloseHandle_(TokenHandle)
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s GetProcessPath(hProcess)
Result.s = ""
If hProcess
Select OSVersion()
Case #PB_OS_Windows_XP
psapi = OpenLibrary(#PB_Any, "psapi.dll")
If IsLibrary(psapi)
GetProcessImageFileName = GetFunction(psapi, "GetProcessImageFileNameW")
If GetProcessImageFileName
nSize = #MAX_PATH
Dim lpBuffer.c(nSize)
lpImageFileName.s = Space(nSize)
GetProcessImageFileName(hProcess, @lpImageFileName, nSize)
BufferLength = GetLogicalDriveStrings_(nSize, @lpBuffer(0))
Repeat
lpDeviceName.s = ""
While lpBuffer(rtnCount)
lpDeviceName + Chr(lpBuffer(rtnCount))
rtnCount + 1
Wend
lpDeviceName = Left(lpDeviceName, Len(lpDeviceName) - 1)
lpTargetPath.s = Space(nSize)
QueryDosDevice_(lpDeviceName, @lpTargetPath, nSize)
If Left(lpImageFileName, Len(lpTargetPath)) = lpTargetPath
Result = Trim(ReplaceString(lpImageFileName, lpTargetPath, lpDeviceName))
Break
EndIf
rtnCount + 1
Until rtnCount >= BufferLength
EndIf
CloseLibrary(psapi)
EndIf
Case #PB_OS_Windows_Vista, #PB_OS_Windows_7
kernel32 = OpenLibrary(#PB_Any, "kernel32.dll")
If IsLibrary(kernel32)
QueryFullProcessImageName = GetFunction(kernel32, "QueryFullProcessImageNameW")
If QueryFullProcessImageName
lpdwSize = #MAX_PATH
lpExeName.s = Space(lpdwSize)
QueryFullProcessImageName(hProcess, 0, @lpExeName, @lpdwSize)
Result = Trim(lpExeName)
EndIf
CloseLibrary(kernel32)
EndIf
EndSelect
CloseHandle_(hProcess)
EndIf
ProcedureReturn Result
EndProcedure
Procedure.b PathFromHandle(WindowTitle.s, FullPath.s)
Result.b = False
hWnd = GetWindow_(GetDesktopWindow_(), #GW_CHILD)
Repeat
lpString.s = Space(#MAX_PATH)
GetWindowText_(hWnd, @lpString, #MAX_PATH)
If Len(Trim(lpString)) > 0
If FindString(LCase(lpString), LCase(WindowTitle)) > 0
AdjustCurrentProcessPrivilege()
GetWindowThreadProcessId_(hWnd, @lpdwProcessId)
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, #False, lpdwProcessId)
If hProcess
If LCase(GetProcessPath(hProcess)) = LCase(FullPath)
Result = #True
CloseHandle_(hProcess)
Break
EndIf
CloseHandle_(hProcess)
EndIf
EndIf
EndIf
hWnd = GetWindow_(hWnd, #GW_HWNDNEXT)
Until hWnd = 0
ProcedureReturn Result
EndProcedure
;http://forums.purebasic.com/english/viewtopic.php?p=296219
;http://en.wikipedia.org/wiki/Data_erasure
;Not meant to be super secure. Simple wipe.
; More Secure
; For i = 1 To 2
; FileSeek(0,0)
; For j=1 To Lof(0)
; RNum = Random(999)
; WriteByte(0,RNum)
; Next
; FlushFileBuffers(0)
; Next
Procedure Wipe(File$)
SetFileAttributes(File$,#PB_FileSystem_Normal)
If OpenFile(0,File$)
FileSeek(0,0)
For j=1 To Lof(0)
WriteByte(0,0)
Next
FlushFileBuffers(0)
FileSeek(0,0)
For j=1 To Lof(0)
WriteByte(0,1)
Next
FlushFileBuffers(0)
FileSeek(0,0)
For j=1 To Lof(0)
RNum = Random(999)
WriteByte(0,RNum)
Next
FlushFileBuffers(0)
CloseFile(#PB_All)
DeleteFile(File$)
EndIf
EndProcedure
Procedure EndCleanup()
DeleteFile("7za.exe")
End
EndProcedure
;If FileSize("7za.exe") = -1
; MessageRequester("XYKeyCrypt","7za.exe Missing. Cannot Continue.",#MB_ICONSTOP)
; EndCleanup()
;EndIf
If FileSize("XYplorer.exe") = -1
MessageRequester("XYKeyCrypt","XYplorer.exe Missing. Cannot Continue.",#MB_ICONSTOP)
EndCleanup()
EndIf
;Get Program Parameters
;For p = 1 To CountProgramParameters()
; CParam$ = CParam$ + " " + Chr(34) + ProgramParameter() + Chr(34)
;Next
;
;Get Command Line
;http://forums.purebasic.com/english/viewtopic.php?f=13&t=43459
*s.String = GetCommandLine_()
CmdRaw$ = Trim(PeekS(*s))
CmdRaw2$ = CmdRaw$+".exe"
ExeName$ = GetFilePart(ProgramFilename())
ExeName2$ = RemoveString(ExeName$,".exe")
FStringPos = FindString(CmdRaw$,ExeName$)
If CmdRaw$ = #DQUOTE$+ProgramFilename()+#DQUOTE$ Or CmdRaw$ = ExeName$ Or CmdRaw2$ = ExeName$
CParam$ = ""
ElseIf FStringPos = 0
CParam$ = Trim(RemoveString(CmdRaw$,ExeName2$))
ElseIf FStringPos = 1
CParam$ = Trim(RemoveString(CmdRaw$,ExeName$))
ElseIf FStringPos = 2
CParam$ = Trim(RemoveString(CmdRaw$,#DQUOTE$+ExeName$+#DQUOTE$))
EndIf
If FileSize("Data\XYplorer.dat") = -1
If FileSize("Data\XYplorer.ini") <> -1
MessageRequester("XYKeyCrypt","XYplorer.dat Not Found. Proceeding to Setup.",#MB_ICONINFORMATION)
While KeySame = 0
Delay(250)
Pass$ = InputBox(300,20,"XYKeyCrypt","Encryption Key for XYplorer.ini:","",#PB_String_Password)
If Pass$ = "" : EndCleanup() : EndIf
Delay(250)
PassCheck$ = InputBox(300,20,"XYKeyCrypt","Please Enter the Encryption Key Again::","",#PB_String_Password)
If PassCheck$ = ""
EndCleanup()
ElseIf PassCheck$ = Pass$
KeySame = 1
Else
MessageRequester("XYKeyCrypt","Encryption Key Does Not Match.",#MB_ICONSTOP)
EndIf
Wend
RunProgram("7za.exe","a -mhe=on -mmt=on -p"+Pass$+" Data\XYplorer.dat .\Data\XYplorer.ini","",#PB_Program_Wait|#PB_Program_Hide)
Integrity7z = RunProgram("7za.exe","t -p"+Pass$+" Data\XYplorer.dat","",#PB_Program_Hide|#PB_Program_Open|#PB_Program_Error)
Delay(200)
ExitCode = ProgramExitCode(Integrity7z)
If ExitCode = 2
MessageRequester("XYKeyCrypt Error "+StrD(ExitCode),"Error Occured During Encryption of XYplorer.ini. Check Read/Write Access to the Current Folder. Cannot Continue.",#MB_ICONSTOP)
EndCleanup()
EndIf
Wipe("Data\XYplorer.ini")
Delay(750)
MessageRequester("XYKeyCrypt","Configuration Complete.",#MB_ICONINFORMATION)
RunProgram(ExeName$,CParam$,"")
Else
MessageRequester("XYKeyCrypt","XYplorer.dat and XYplorer.ini Not Found. Cannot Continue.",#MB_ICONSTOP)
EndIf
Else
If FileSize("Data\XYplorer.ini") <> -1 : EndCleanup() : EndIf
Delay(250)
Pass$ = InputBox(300,20,"XYKeyCrypt","Decryption Key for XYplorer.ini:","",#PB_String_Password)
If Pass$ = "" : EndCleanup() : EndIf
Integrity7z = RunProgram("7za.exe","t -p"+Pass$+" Data\XYplorer.dat","",#PB_Program_Hide|#PB_Program_Open|#PB_Program_Error)
Delay(200)
ExitCode = ProgramExitCode(Integrity7z)
If ExitCode = 2
MessageRequester("XYKeyCrypt Error "+StrD(ExitCode),"XYplorer.dat Corrupted. Cannot Continue.",#MB_ICONSTOP)
EndCleanup()
EndIf
RunProgram("7za.exe","e -p"+Pass$+" -oData Data\XYplorer.dat","",#PB_Program_Wait|#PB_Program_Hide)
If FileSize("Data\XYplorer.ini") <> -1
RunProgram("XYplorer.exe",CParam$,"")
XYRun = 0
While XYRun < 5
If PathFromHandle("XYplorer",GetCurrentDirectory()+"XYplorer.exe") ;FindWindow_("ThunderRT6FormDC",0)
XYRun = 0
Delay(500)
Else
XYRun = XYRun+1
Delay(500)
EndIf
Wend
RunProgram("7za.exe","u -mhe -p"+Pass$+" Data\XYplorer.dat .\Data\XYplorer.ini","",#PB_Program_Wait|#PB_Program_Hide)
Integrity7z = RunProgram("7za.exe","t -p"+Pass$+" Data\XYplorer.dat","",#PB_Program_Hide|#PB_Program_Open|#PB_Program_Error)
Delay(200)
ExitCode = ProgramExitCode(Integrity7z)
If ExitCode = 2
MessageRequester("XYKeyCrypt Error "+StrD(ExitCode),"Error Occured During Encryption of XYplorer.ini. Check Read/Write Access to the Current Folder. Cannot Continue Wipe of XYplorer.ini.",#MB_ICONSTOP)
EndCleanup()
EndIf
Wipe("Data\XYplorer.ini")
EndIf
EndIf
EndCleanup()
; IDE Options = PureBasic 5.11 (Windows - x86)
; EnableUnicode
; EnableThread
; EnableXP
; UseIcon = 1375436159_12578.ICO
; Executable = XYKeyCrypt.exe
; CPU = 1
; DisableDebugger
; CompileSourceDirectory
; IncludeVersionInfo
; VersionField0 = 1.4.0
; VersionField3 = XYKeyCrypt
; VersionField6 = XYplorer License Crypter
; VersionField8 = XYKeyCrypt
; VersionField14 = http://www.xyplorer.com/
; VersionField18 = XYplorer User
; VersionField21 = Enternal
XYplorer Beta Club