0% found this document useful (0 votes)
258 views

Excel Unlocker

This document contains VBA code for unlocking password protection from Excel workbooks and worksheets. It includes functions to remove passwords from the VBA project, workbook, and individual worksheets. It opens the protected file, copies it to a temporary location, extracts specific files from the ZIP archive, modifies password values, overwrites the original files, and then closes and saves the unlocked workbook. Status messages are displayed to show the password cracking progress.

Uploaded by

wnoivijt
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
258 views

Excel Unlocker

This document contains VBA code for unlocking password protection from Excel workbooks and worksheets. It includes functions to remove passwords from the VBA project, workbook, and individual worksheets. It opens the protected file, copies it to a temporary location, extracts specific files from the ZIP archive, modifies password values, overwrites the original files, and then closes and saves the unlocked workbook. Status messages are displayed to show the password cracking progress.

Uploaded by

wnoivijt
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

MODULE NAME: mainFuncs

''Created by Anton Pivkach ([email protected])

Option Base 1

'Declare Function GetTickCount Lib "kernel32.dll" () As Long


Declare PtrSafe Function GetTickCount Lib "kernel32.dll" () As Long 'win64_bit

Public CopiedExcel As Boolean


Public RenamedZIP As Boolean
Public CreatedTMPFolder As Boolean

Public ProtectedSheets() As Long

Sub GeneralSub()

CopiedExcel = False
RenamedZIP = False
CreatedTMPFolder = False

'Check if any selection exists


If (Sheet1.CheckVBA.Value Or Sheet1.CheckWB.Value Or Sheet1.CheckWS.Value) = False Then
MsgBox "Please select at least one checkBox!", vbInformation, "Excel Unlocker"
Exit Sub
End If

ChDir (Environ("USERPROFILE") & "\Desktop")


'Select the file
Fname = Application.GetOpenFilename(filefilter:="Excel files (*.xlsx; *.xlsm), *.xlsx; *.xlsm",
MultiSelect:=False)

'Check if file selected


If Fname = False Then
Exit Sub
End If

''Check if workBook has password for opening


On Error Resume Next
Dim tmpWB As Workbook

''Disable AutoRun macro


Application.EnableEvents = False

Set tmpWB = Workbooks.Open(Fname, ReadOnly:=True, Password:="", UpdateLinks:=False,


IgnoreReadOnlyRecommended:=True)

If Err.Number > 0 Then


MsgBox "Selected Workbook is encrypted (Password for Openning)!" & vbCrLf & "This program doesn't
works with such files.", vbCritical, "Excel Unlocker"
''Return original settings (AutoRun macro)
Application.EnableEvents = True
Exit Sub
End If
On Error GoTo 0

''Check if WorkBook is in Shared mode


If tmpWB.MultiUserEditing = True Then
''Close WorkBook
tmpWB.Close saveChanges:=False
MsgBox "Selected Workbook is in Shared Mode!" & vbCrLf & "Please change mode to Exclusive (non
Shared) and try again", vbExclamation, "Excel Unlocker"
''Return original settings (AutoRun macro)
Application.EnableEvents = True
Exit Sub
End If

''Check if VBProjec protected


ProjectProtected = ProtectedVBProject(tmpWB)
''Check if WorkBook is protected
WBookProtected = PrWB(tmpWB)
''Checx if Sheets is protected
WBookSheetsProtected = PrWSheets(tmpWB)

''Close WorkBook
tmpWB.Close saveChanges:=False
Set tmpWB = Nothing

'String for output msgs


Dim OutMSG As String
OutMSG = ""

''Create Scripting Object


Dim FSO As Object
Set FSO = CreateObject("scripting.filesystemobject")

''Call procedure for each action-----------------------------


''WorkBook------------------------------
If Sheet1.CheckWB.Value = True Then
If WBookProtected = True Then
OutMSG = UnprotectWBook(Fname)
Else
OutMSG = OutMSG & vbCrLf & "Selected WorkBook has no WorkBook Password Protection."
End If
'ChangeWBStatus
WBookProtected = False
End If

''Vba-----------------------------------
If Sheet1.CheckVBA.Value = True And FSO.GetExtensionName(Fname) = "xlsm" Then
'Check whether WorkBook has VBA Project protection
If ProjectProtected = True Then

'Check whether WorkBook has Password Protection (internal ZIP encryption)


If WBookProtected = True Then
OutMSG = OutMSG & vbCrLf & UnprotectWBook(Fname)
End If

''Call VBA unlock


OutMSG = OutMSG & vbCrLf & ChangePasswordForVBA(Fname)
Else
OutMSG = OutMSG & vbCrLf & "Selected WorkBook has no VBA Project protection."
End If
End If

''WorkSheet----------------------------
If Sheet1.CheckWS.Value = True Then
If WBookSheetsProtected = True Then

'Check whether WorkBook has Password Protection (internal ZIP encryption)


If WBookProtected = True Then
OutMSG = OutMSG & vbCrLf & UnprotectWBook(Fname)
End If

''Call Sheets unlock


OutMSG = OutMSG & vbCrLf & UnprotectWSheets(Fname)
Else
OutMSG = OutMSG & vbCrLf & "Selected WorkBook has no WorkSheets Protection."
End If
End If

''Check if returning to previous state is required


If RenamedZIP = True Then

''Rename back to .xlsm file


FSO.GetFile(rename_to_zip(copy_excel_file(Fname))).Name =
FSO.GetFileName(copy_excel_file(Fname))

''Delete tmp files--------------------------


' If FSO.FolderExists(FileNameFolder & "\") Then
' FSO.deletefolder FileNameFolder
' End If

End If

If RenamedZIP Or CopiedExcel Then


OutMSG = OutMSG & vbCrLf & vbCrLf & "Unlocked file saved under the name: '" & "Unprotected_" &
FSO.GetFileName(Fname) & "' in the same folder"
End If

Set FSO = Nothing

''Return original settings (AutoRun macro)


Application.EnableEvents = True

MsgBox OutMSG, vbInformation, "Excel Unlocker"

End Sub

Function ChangePasswordForVBA(Fname As Variant) As String

Application.StatusBar = "Resetting VBA Project password..."

''Copy Excel file and Rename to ZIP


name_of_exel_file = copy_excel_file(Fname)

If name_of_exel_file = "" Then ''Missing Write acces


ChangePasswordForVBA = "Missing Write access"
Exit Function
End If

CopyFname = rename_to_zip(name_of_exel_file)

''TMP Folder
FileNameFolder = create_TMP_folder

'Object for work with ZIP file


Set oApp = CreateObject("Shell.Application")

''Set to false
ProjectFileFound = False

''Cycle trought Zip archive


For Each fileNameInZip In oApp.Namespace(CopyFname).items
'find 'xl' folder
If fileNameInZip = "xl" Then
'find vbaProject.bin
For Each subFile In fileNameInZip.Getfolder.items
'extract 'vbaProject.bin' file
If subFile = "vbaProject.bin" Or subFile = "vbaProject" Then
''Move bin file to tmp folder
oApp.Namespace(FileNameFolder).movehere subFile
ProjectFileFound = True
Exit For
End If
Next
End If
Next

''HASH for Password = 'macro'


Dim PasswordString As String
PasswordString =
"282A84CBA1CBA1345FCCB154E20721DE77F7D2378D0EAC90427A22021A46E9CE6F17188A"

''if VbaProject exists


If ProjectFileFound = True Then
tmpMSG = ""
tmpMSG = ChangeDPBValue(FileNameFolder & "\vbaProject.bin", PasswordString) ''DPB change

''Overwirte existing vbaProject.bin file


oApp.Namespace(CopyFname).items.Item("xl").Getfolder.CopyHere FileNameFolder &
"\vbaProject.bin"

'Keep script waiting until Compressing is done


On Error Resume Next
Do Until oApp.Namespace(CopyFname).items.Item("xl").Getfolder.items.Item("vbaProject.bin").Name
= "vbaProject.bin" Or _
oApp.Namespace(CopyFname).items.Item("xl").Getfolder.items.Item("vbaProject.bin").Name =
"vbaProject"
Application.Wait (Now + TimeValue("0:00:01"))
Loop
On Error GoTo 0

If tmpMSG = "" Then


ChangePasswordForVBA = "Password for VbaProject: 'macro'"
Else
ChangePasswordForVBA = tmpMSG
End If

Else
ChangePasswordForVBA = "File don't have VbaProject!"
End If

Set oApp = Nothing

Application.StatusBar = ""

End Function

Function UnprotectWBook(Fname As Variant) As String


Dim UL As Workbook
Dim lockedWB As Workbook

''Remember this WB name


Set UL = ThisWorkbook

LockedWBName = copy_excel_file(Fname)

If LockedWBName = "" Then ''Missing Write access


UnprotectWBook = "Missing Write access"
Exit Function
End If

''Disable AutoRun macro


Application.EnableEvents = False
''Disable Alerts
Application.DisplayAlerts = False
''Dissable screen updating
Application.ScreenUpdating = False

''Open Locked WB
On Error Resume Next ''Prevent error for WriteProtection Password
Set lockedWB = Workbooks.Open(LockedWBName, notify:=False, WriteResPassword:="",
UpdateLinks:=False, IgnoreReadOnlyRecommended:=True)

''Check for Write password---------------


If Err.Number <> 0 Then
'Open original file
Set lockedWB = Workbooks.Open(Fname, ReadOnly:=True, UpdateLinks:=False,
IgnoreReadOnlyRecommended:=True)
'Save as Unlocked
lockedWB.SaveAs LockedWBName, WriteResPassword:="", ReadOnlyRecommended:=False
End If

On Error GoTo 0

''Return original settings (AutoRun macro)


Application.EnableEvents = True

''Randomize HASH values to improve chance of quick break


Sheet3.Calculate

'''HASH values calculated based on algorithm described here:


'http://stackoverflow.com/questions/12852095/how-does-excels-worksheet-password-protection-work

''Sort
UL.Worksheets("hash_table").AutoFilter.Sort.SortFields.Clear
UL.Worksheets("hash_table").AutoFilter.Sort.SortFields.Add Key:= _
Range("B1:B32769"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _
:=xlSortNormal
With UL.Worksheets("hash_table").AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With

s_t = GetTickCount
ETR = 0

''Enable errors resuming


On Error Resume Next

Do ''Dummy loop to enable early exit from For

For i = 2 To 32769
DoEvents

''update changes by 1% Calculate ETR


If i Mod 300 = 0 Then
e_t = GetTickCount
If ETR > 0 Then
ETR = (ETR + ((32769 - i) / 300 * (s_t - e_t) / 1000)) / 2
Else
ETR = (32769 - i) / 300 * (s_t - e_t) / 1000
End If

Application.StatusBar = "WB Protection password guessing: " & Format((i / 32769), "0%") & " / Max
ETR: " & Format(TimeSerial(0, 0, ETR), "hh:mm:ss")
s_t = GetTickCount
End If

lockedWB.Unprotect UL.Worksheets("hash_table").Cells(i, 1).Value


If Not (lockedWB.ProtectWindows Or lockedWB.ProtectStructure) = True Then

UnprotectWBook = "Allowable WB Protection password: '" &


UL.Worksheets("hash_table").Cells(i, 1).Value & "'"
Application.StatusBar = "WB Protection password guessing: " & Format((i / 32769), "0%") & " ->
Success!!!"
Exit Do
End If

Next i
Loop Until 1 = 1

''Disable errors resuming


On Error GoTo 0

''Save WB
lockedWB.Close saveChanges:=True

Application.StatusBar = ""

Application.DisplayAlerts = True
Application.ScreenUpdating = True

End Function
Function UnprotectWSheets(Fname As Variant) As String ''Fname As Variant

Application.ScreenUpdating = False

Application.StatusBar = "Remove Sheets password..."

''Copy Excel file and Rename to ZIP


CopyFname = rename_to_zip(copy_excel_file(Fname))
''TMP Folder
FileNameFolder = create_TMP_folder

'Object for work with ZIP file


Set oApp = CreateObject("Shell.Application")

''Extract locked sheets


For i = 1 To UBound(ProtectedSheets)
DoEvents

Application.StatusBar = "Sheets Protection / extracting " & "sheet" & ProtectedSheets(i)

''Move .xml file to tmp folder


oApp.Namespace(FileNameFolder).movehere oApp.Namespace(CopyFname &
"\xl\worksheets").items.Item("sheet" & ProtectedSheets(i) & ".xml")

Next i

''Dim xmlDoc As MSXML2.DOMDocument


''Dim objNode As IXMLDOMSelection

''Process each locked sheet----------------------

''Create XML object


Set xmlDoc = CreateObject("MSXML2.DOMDocument")

For i = 1 To UBound(ProtectedSheets)

Application.StatusBar = "Sheets Protection / removing protection of " & "sheet" & ProtectedSheets(i)

'Load XML file (sheet)


xmlDoc.Load FileNameFolder & "\sheet" & ProtectedSheets(i) & ".xml"

''Set Node sheetProtection


Set objSelecion = xmlDoc.getElementsByTagName("sheetProtection")
''Revmove node
objSelecion.removeAll
''Save changes
xmlDoc.Save FileNameFolder & "\sheet" & ProtectedSheets(i) & ".xml"

Next i

''Overwirte existing sheets in ZIP file------------------------


For i = 1 To UBound(ProtectedSheets)
Application.StatusBar = "Sheets Protection / compressing " & "sheet" & ProtectedSheets(i)

'' prevent compressing error----


On Error Resume Next
Do
oApp.Namespace(CopyFname & "\xl\worksheets").CopyHere FileNameFolder & "\sheet" &
ProtectedSheets(i) & ".xml"

DoEvents
Application.Wait (Now + TimeValue("0:00:01"))
Loop Until Err.Number = 0
On Error GoTo 0
'Keep script waiting until Compressing is done
On Error Resume Next
Do Until oApp.Namespace(CopyFname & "\xl\worksheets").items.Item("sheet" & ProtectedSheets(i) &
".xml").Name = CStr("sheet" & ProtectedSheets(i) & ".xml")
DoEvents
Application.Wait (Now + TimeValue("0:00:01"))
Loop
On Error GoTo 0
Next i

Application.StatusBar = ""

UnprotectWSheets = "All the Sheets have been unprotected"


Application.ScreenUpdating = True

End Function
MODULE NAME: auxiliaryFuncs

Option Base 1

Function ProtectedVBProject(ByRef wb As Workbook) As Boolean


' returns TRUE if the VB project in the active document is protected
Dim VBC As Integer

VBC = -1
On Error Resume Next
VBC = wb.VBProject.VBComponents.Count
On Error GoTo 0

If VBC = -1 Then
ProtectedVBProject = True
Else
ProtectedVBProject = False
End If

End Function

Function PrWB(ByRef wb As Workbook) As Boolean

PrWB = False

If wb.ProtectWindows Then PrWB = True


If wb.ProtectStructure Then PrWB = True

If PrWB = True Then


'try for password protection
On Error Resume Next
wb.Unprotect
If Err.Number = 0 Then PrWB = False
On Error GoTo 0
End If

End Function

Function PrWSheets(ByRef wb As Workbook) As Boolean

PrWSheets = False

''Arrays for storing protected wsheets


i=0

For Each SH In wb.Sheets


If SH.ProtectContents Or SH.ProtectDrawingObjects Or SH.ProtectScenarios Then
i=i+1
ReDim Preserve ProtectedSheets(i)
ProtectedSheets(i) = SH.Index
PrWSheets = True
End If
Next

End Function

Function copy_excel_file(file_to_copy)

''Create Scripting Object


'Dim FSO As Object
Set FSO = CreateObject("scripting.filesystemobject")

'Define new name


UnprotecedFilePath = FSO.GetParentFolderName(file_to_copy) & "\Unprotected_" &
FSO.GetFileName(file_to_copy)

''Check if file already copied


If CopiedExcel = False Then
On Error Resume Next
''Copy
FSO.CopyFile file_to_copy, UnprotecedFilePath, True

''Check for access error


If Err.Number <> 0 Then
MsgBox "You have no Write access to the folder: '" & FSO.GetParentFolderName(file_to_copy) & "'",
vbCritical, "Excel Unlocker"

copy_excel_file = ""
Exit Function
End If

On Error GoTo 0
'Save flag
CopiedExcel = True
End If

Set FSO = Nothing

''return path
copy_excel_file = UnprotecedFilePath

End Function
Function rename_to_zip(file_to_rename)

''Create Scripting Object


Dim FSO As Object
Set FSO = CreateObject("scripting.filesystemobject")

''Create new name


ZIPFilePath = FSO.GetParentFolderName(file_to_rename) & "\" & FSO.GetBaseName(file_to_rename) &
".zip"

''Check if file already renamed


If RenamedZIP = False Then
'chekc if file with such name exists
If FSO.FileExists(ZIPFilePath) Then FSO.DeleteFile ZIPFilePath, True
'Change extension
FSO.MoveFile file_to_rename, ZIPFilePath
'Save flag
RenamedZIP = True
End If

Set FSO = Nothing

''Return path
rename_to_zip = ZIPFilePath

End Function

Function create_TMP_folder()

''Path to tmp folder


FileNameFolder = Environ("tmp") & "\UnlockFolderTMP"

If CreatedTMPFolder = False Then


''Create Scripting Object
'Dim FSO As Object
Set FSO = CreateObject("scripting.filesystemobject")

''Delete if previous files exists


Do While FSO.FolderExists(FileNameFolder & "\")
FSO.deletefolder FileNameFolder

DoEvents
Application.Wait (Now + TimeValue("0:00:01")) '' wait until deletion is done
Loop

'Make the tmp folder in User tmp


FSO.CreateFolder FileNameFolder

'Destroy FSO
Set FSO = Nothing

'Set Flag
CreatedTMPFolder = True
End If

create_TMP_folder = FileNameFolder

End Function

Function ChangeDPBValue(PathToBinFile As String, HASHPassword As String) As String

''Dim adoStream As ADODB.Stream


''Dim adoBin As ADODB.Stream

Dim PasswordArrayByte() As Byte

Set adoStream = CreateObject("ADODB.Stream")


Set adoBin = CreateObject("ADODB.Stream")

ReDim PasswordArrayByte(Len(HASHPassword))

''Convert String to byte


For i = 1 To Len(HASHPassword)
PasswordArrayByte(i) = Asc(Mid(HASHPassword, i, 1))
Next i

''Read TXT data fine 'DPB' value


With adoStream
.Mode = 3 'adModeReadWrite
.Type = 2 'adTypeText
.Charset = "us-ascii"
.Open
.LoadFromFile (PathToBinFile)
bytes = .ReadText

''Find Start of Value pos


StartPosVal = InStr(1, bytes, "DPB=", vbTextCompare) + 5

''IF there is no DPB value


If StartPosVal = 5 Then
.Close
Set adoStream = Nothing
Set adoBin = Nothing
ChangeDPBValue = "VBA Protection Not found"
Exit Function
End If

''Find End of Value pos


EndPosVal = InStr(StartPosVal, bytes, """", vbTextCompare) - 1
'Define lenght
ValLength = EndPosVal - StartPosVal + 1

If Len(HASHPassword) < ValLength Then


'add additional '0' if coded password is longer
ReDim Preserve PasswordArrayByte(Len(HASHPassword) + ValLength - Len(HASHPassword))

For i = Len(HASHPassword) + 1 To UBound(PasswordArrayByte)


PasswordArrayByte(i) = Asc(0)
Next i
End If

.Close
End With

''Read binary data


With adoStream
.Mode = 3 'adModeReadWrite
.Type = 1 'adTypeBinary
.Open
.LoadFromFile (PathToBinFile)

''Create empty stream object


With adoBin
.Mode = 3 'adModeReadWrite
.Type = 1 'adTypeBinary
.Open
End With

'copy first part of bytes (till start of 'DPB' value)


.Position = 0
.CopyTo adoBin, StartPosVal - 1

'copy new DPB value


adoBin.Write (PasswordArrayByte)

'copy remaining part of bytes (after 'DPB' value)


.Position = EndPosVal ''Set position to remaining part
.CopyTo adoBin

'save to file
adoBin.SaveToFile PathToBinFile, 2 'adSaveCreateOverWrite
adoBin.Close

.Close
End With

Set adoStream = Nothing


Set adoBin = Nothing
ChangeDPBValue = ""

End Function

'Sub Auto_Open()
'
''''Add ADO library if required---------------------------------------------
''ADOAssigned = False
''
''For i = 1 To ThisWorkbook.VBProject.References.Count
'' ''Debug.Print ThisWorkbook.VBProject.References.Item(i).Name
'' If ThisWorkbook.VBProject.References.Item(i).Name = "ADODB" Then
'' ADOAssigned = True
'' End If
''Next i
''
''If ADOAssigned = False Then
'' ThisWorkbook.VBProject.References.AddFromFile Environ("CommonProgramFiles") &
"\System\ado\msado15.dll"
''End If
'
'
'End Sub

You might also like