Automated download of excel file in vba - excel

I've had a look around and I think I need some very specific help. I need to write a macro to download excel files online. Until now I have been able to use the URLdownloadtofile function by adding the get request parameters to the URL. The website I need to download from this time however doesn't seem to work that way. (It ends in aspx, if that makes a difference). I use http fox addin on Firefox to see the request line and all it gives is the website and no parameters after it. How can I use xmlhttp to download this file if I can't use URLdownloadtofile? Also one of the dropdown menus only becomes active when the previous menu value is selected.
The URL of the file is: http://cmg.cdec-sic.cl/Modulos/CMg/CDEC_CMgBarras.aspx
If I want the excel file for January 2014, tension 220 and barra alto jahuel_220 for instance, what would I need to place after the send function of the xmlhttp function? As in what parameters? I tried using the names of each parameter = to the value I want. And I changed all the $ to the hex value. But it just seemed to return the same page.
And once that works, how do I get the returned excel file to download to a specific directory?
Any help would be greatly appreciated.

Option Explicit
Private Declare Function URLDownloadToFile Lib "urlmon" _
Alias "URLDownloadToFileA" (ByVal pCaller As Long, _
ByVal szURL As String, ByVal szFileName As String, _
ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Dim Ret As Long
Sub Download_Files_from_web_and_save_to_file()
Dim strURL As String
Dim strPath As String
Ret = URLDownloadToFile(0, " http://cmg.cdec-sic.cl/Modulos/CMg/CDEC_CMgBarras.aspx", "d:\my_file.xls", 0, 0)
If Ret = 0 Then
' MsgBox "File successfully downloaded"
Else
MsgBox "Unable to download the file"
End If
End Sub

Related

Save webpage concluded instead HTML only

I'm currently using a VBA code in a spreadsheet to download a webpage, the issue is that this is downloading only the html page, without the folder that is downloaded when we go to the browser and select "Save As".
Below I'm showing the explanation with images - I would like to know if is possible to, directly from VBA, download the concluded page (with folder that comes with images, etc.) instead only the HTML.
Private Declare PtrSafe Function URLDownloadToFile Lib "urlmon" _
Alias "URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, _
ByVal szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Sub datafeed()
src = "https://google.com"
dlpath = "C:\Users\User\Downloads\Test\"
URLDownloadToFile 0, src, dlpath & "test.html", 0, 0
End Sub
How is currently downloading:
How I would like to download (like when I select Save As in the browser):
Does someone know how to configure VBA to download the webpage and the folder with the files instead only the webpage?

Download fail using VBA. Any suggestion?

Hi I'm trying to download a zip in a local server using VBA. My code works great in my PC but at the server doesn't work. Heres's the code:
PS. Cell A7 is the link of the download.
Dim downloadStatus As Variant
Dim url As String
Dim destinationFile_local As String
url = [A7]
destinationFile_local = "C:\Users\omayorga\Downloads\" & fileName([A7])
downloadStatus = URLDownloadToFile(0, url, destinationFile_local, 0, 0)
If downloadStatus = 0 Then
MsgBox "Downloaded Succcessfully!"
Else
MsgBox "Download failed"
End If
End Sub
Function fileName(file_fullname) As String
fileName = Mid(file_fullname, InStrRev(file_fullname, "/") + 1)
End Function
Any suggestion? Thanks so much
You have this in your code, you need:
Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _
(ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, _
ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Check your download link, the same said Raymond Wu your destinationFile_local, tested here your code works.
refer link
How do I download a file using VBA (without Internet Explorer)

How to download the canonical revision?

In my Excel workbook I use VBA code that calls URLDownloadToFile to download a different Excel file stored in SharePoint to the current folder of the workbook.
The downloaded workbook is not the latest / canonical revision. The link used as a parameter for URLDownloadToFile is the one that links directly to the file, NOT to a specific revision with "_vti_history".
I tried updating the file on SharePoint multiple times to test this but the same old revision was downloaded every time.
Edit: To clarify, the issue.
I call the function as
URLDownloadToFile(0, "http://blahblah/file.ext", "C:\blah\file.ext", 0, 0)
The local copy saved is not the latest revision of "file.ext" but an older one.
If the URL used is the same to download the newest version, it may be that a cached version is being downloaded by URLDownloadToFile.
Try to clear the cache for the link before downloading by using DeleteUrlCacheEntry:
Private Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Private Declare Function DeleteUrlCacheEntry Lib "Wininet.dll" Alias "DeleteUrlCacheEntryA" (ByVal lpszUrlName As String) As Long
Sub downloadFile()
Call DeleteUrlCacheEntry("http://blahblah/file.ext")
Call URLDownloadToFile(0, "http://blahblah/file.ext", "C:\blah\file.ext", 0, 0)
End Sub
I have been trying to figure this out. The function URLDownloadToFile was not working for Sharepoint Online as it couldn't navigate the authentication part. Finally, I found this link which saved my day. The solution that worked for me Version 1 as I didn't have access to the folder view of the file, I only had direct access to the file alone. I created the following function and added the reference to Windows Script Host Object Model library in VBA.
Public Sub VBA_FileCopy(ByVal sSourceFile As String, ByVal sDestinationFile As String)
Dim fs As FileSystemObject
Set fs = New FileSystemObject 'CreateObject("Scripting.FileSystemObject")
sSourceFile = Replace(sSourceFile, "/", "\")
sSourceFile = Replace(sSourceFile, "http:", "")
sSourceFile = Replace(sSourceFile, "https:", "")
sSourceFile = Replace(sSourceFile, Split(sSourceFile, "\")(2), Split(sSourceFile, "\")(2) & "#SSL\DavWWWRoot")
sSourceFile = Replace(sSourceFile, " ", "%20")
fs.CopyFile sSourceFile, sDestinationFile, True
End Sub

Bypass password on an Excel VBA project *.xla [duplicate]

I've been asked to update some Excel 2003 macros, but the VBA projects are password protected, and it seems there's a lack of documentation... no-one knows the passwords.
Is there a way of removing or cracking the password on a VBA project?
You can try this direct VBA approach which doesn't require HEX editing. It will work for any files (*.xls, *.xlsm, *.xlam ...).
Tested and works on:
Excel 2007
Excel 2010
Excel 2013 - 32 bit version
Excel 2016 - 32 bit version
Looking for 64 bit version? See this answer
How it works
I will try my best to explain how it works - please excuse my English.
The VBE will call a system function to create the password dialog box.
If user enters the right password and click OK, this function returns 1. If user enters the wrong password or click Cancel, this function returns 0.
After the dialog box is closed, the VBE checks the returned value of the system function
if this value is 1, the VBE will "think" that the password is right, hence the locked VBA project will be opened.
The code below swaps the memory of the original function used to display the password dialog with a user defined function that will always return 1 when being called.
Using the code
Please backup your files first!
Open the file(s) that contain your locked VBA Projects
Create a new xlsm file and store this code in Module1
code credited to Siwtom (nick name), a Vietnamese developer
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Long, Source As Long, ByVal Length As Long)
Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Long, _
ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, _
ByVal lpProcName As String) As Long
Private Declare Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As Long, _
ByVal pTemplateName As Long, ByVal hWndParent As Long, _
ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As Long
Dim Flag As Boolean
Private Function GetPtr(ByVal Value As Long) As Long
GetPtr = Value
End Function
Public Sub RecoverBytes()
If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 5) As Byte
Dim p As Long
Dim OriginProtect As Long
Hook = False
pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
If VirtualProtect(ByVal pFunc, 6, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 6
If TmpBytes(0) <> &H68 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 6
p = GetPtr(AddressOf MyDialogBoxParam)
HookBytes(0) = &H68
MoveMemory ByVal VarPtr(HookBytes(1)), ByVal VarPtr(p), 4
HookBytes(5) = &HC3
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 6
Flag = True
Hook = True
End If
End If
End Function
Private Function MyDialogBoxParam(ByVal hInstance As Long, _
ByVal pTemplateName As Long, ByVal hWndParent As Long, _
ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
If pTemplateName = 4070 Then
MyDialogBoxParam = 1
Else
RecoverBytes
MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
hWndParent, lpDialogFunc, dwInitParam)
Hook
End If
End Function
Paste this code under the above code in Module1 and run it
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Come back to your VBA Projects and enjoy.
Yes there is, as long as you are using a .xls format spreadsheet (the default for Excel up to 2003). For Excel 2007 onwards, the default is .xlsx, which is a fairly secure format, and this method will not work.
As Treb says, it's a simple comparison. One method is to simply swap out the password entry in the file using a hex editor (see Hex editors for Windows). Step by step example:
Create a new simple excel file.
In the VBA part, set a simple password (say - 1234).
Save the file and exit. Then check the file size - see Stewbob's gotcha
Open the file you just created with a hex editor.
Copy the lines starting with the following keys:
CMG=....
DPB=...
GC=...
FIRST BACKUP the excel file you don't know the VBA password for, then open it with your hex editor, and paste the above copied lines from the dummy file.
Save the excel file and exit.
Now, open the excel file you need to see the VBA code in. The password for the VBA code
will simply be 1234 (as in the example I'm showing here).
If you need to work with Excel 2007 or 2010, there are some other answers below which might help, particularly these: 1, 2, 3.
EDIT Feb 2015: for another method that looks very promising, look at this new answer by Đức Thanh Nguyễn.
I've built upon Đức Thanh Nguyễn's fantastic answer to allow this method to work with 64-bit versions of Excel. I'm running Excel 2010 64-Bit on 64-Bit Windows 7.
Open the file(s) that contain your locked VBA Projects.
Create a new xlsm file and store this code in Module1
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare PtrSafe Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As LongPtr, Source As LongPtr, ByVal Length As LongPtr)
Private Declare PtrSafe Function VirtualProtect Lib "kernel32" (lpAddress As LongPtr, _
ByVal dwSize As LongPtr, ByVal flNewProtect As LongPtr, lpflOldProtect As LongPtr) As LongPtr
Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, _
ByVal lpProcName As String) As LongPtr
Private Declare PtrSafe Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean
Private Function GetPtr(ByVal Value As LongPtr) As LongPtr
GetPtr = Value
End Function
Public Sub RecoverBytes()
If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 5) As Byte
Dim p As LongPtr
Dim OriginProtect As LongPtr
Hook = False
pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
If VirtualProtect(ByVal pFunc, 6, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 6
If TmpBytes(0) <> &H68 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 6
p = GetPtr(AddressOf MyDialogBoxParam)
HookBytes(0) = &H68
MoveMemory ByVal VarPtr(HookBytes(1)), ByVal VarPtr(p), 4
HookBytes(5) = &HC3
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 6
Flag = True
Hook = True
End If
End If
End Function
Private Function MyDialogBoxParam(ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
If pTemplateName = 4070 Then
MyDialogBoxParam = 1
Else
RecoverBytes
MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
hWndParent, lpDialogFunc, dwInitParam)
Hook
End If
End Function
Paste this code in Module2 and run it
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
DISCLAIMER This worked for me and I have documented it here in the hope it will help someone out. I have not fully tested it. Please be sure to save all open files before proceeding with this option.
There is another (somewhat easier) solution, without the size problems. I used this approach today (on a 2003 XLS file, using Excel 2007) and was successful.
Backup the xls file
Open the file in a HEX editor and locate the DPB=... part
Change the DPB=... string to DPx=...
Open the xls file in Excel
Open the VBA editor (ALT + F11)
the magic:
Excel discovers an invalid key (DPx) and asks whether you want to continue loading the project (basically ignoring the protection)
You will be able to overwrite the password, so change it to something you can remember
Save the xls file*
Close and reopen the document and work your VBA magic!
*NOTE: Be sure that you have changed the password to a new value, otherwise the next time you open the spreadsheet Excel will report errors (Unexpected Error), then when you access the list of VBA modules you will now see the names of the source modules but receive another error when trying to open forms/code/etc. To remedy this, go back to the VBA Project Properties and set the password to a new value. Save and re-open the Excel document and you should be good to go!
For a .xlsm or .dotm file type you need to do it a slightly different way.
Change the extension of the .xlsm file to .zip.
Open the .zip file (with WinZip or WinRar etc) and go to the xl folder.
Extract the vbaProject.bin file and open it in a Hex Editor (I use HxD, its completely free and lightweight.)
Search for DPB and replace with DPx and save the file.
Replace the old vbaProject.bin file with this new on in the zipped file.
Change the file extension back to .xlsm.
Open workbook skip through the warning messages.
Open up Visual Basic inside Excel.
Go to Tools > VBAProject Properties > Protection Tab.
Put in a new password and save the .xlsm file.
Close and re open and your new password will work.
Edit: this is an updated version of the accepted answer and should work on more office versions. It's tough but let's get this answer to the top!
With my turn, this is built upon kaybee99's excellent answer which is built upon Đức Thanh Nguyễn's fantastic answer to allow this method to work with both 32/64 bit versions of Office.
An overview of what is changed, we avoid push/ret which is limited to 32bit addresses and replace it with mov/jmp reg.
how it works
Open the file(s) that contain your locked VBA Projects.
Create a new file with the same type as the above and store this code in Module1
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare PtrSafe Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As LongPtr, Source As LongPtr, ByVal Length As LongPtr)
Private Declare PtrSafe Function VirtualProtect Lib "kernel32" (lpAddress As LongPtr, _
ByVal dwSize As LongPtr, ByVal flNewProtect As LongPtr, lpflOldProtect As LongPtr) As LongPtr
Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, _
ByVal lpProcName As String) As LongPtr
Private Declare PtrSafe Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
Dim HookBytes(0 To 11) As Byte
Dim OriginBytes(0 To 11) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean
Private Function GetPtr(ByVal Value As LongPtr) As LongPtr
GetPtr = Value
End Function
Public Sub RecoverBytes()
If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 12
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 11) As Byte
Dim p As LongPtr, osi As Byte
Dim OriginProtect As LongPtr
Hook = False
#If Win64 Then
osi = 1
#Else
osi = 0
#End If
pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
If VirtualProtect(ByVal pFunc, 12, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, osi+1
If TmpBytes(osi) <> &HB8 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 12
p = GetPtr(AddressOf MyDialogBoxParam)
If osi Then HookBytes(0) = &H48
HookBytes(osi) = &HB8
osi = osi + 1
MoveMemory ByVal VarPtr(HookBytes(osi)), ByVal VarPtr(p), 4 * osi
HookBytes(osi + 4 * osi) = &HFF
HookBytes(osi + 4 * osi + 1) = &HE0
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 12
Flag = True
Hook = True
End If
End If
End Function
Private Function MyDialogBoxParam(ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
If pTemplateName = 4070 Then
MyDialogBoxParam = 1
Else
RecoverBytes
MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
hWndParent, lpDialogFunc, dwInitParam)
Hook
End If
End Function
Paste this code in Module2 and run it
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Colin Pickard has an excellent answer, but there is one 'watch out' with this. There are instances (I haven't figured out the cause yet) where the total length of the "CMG=........GC=...." entry in the file is different from one excel file to the next. In some cases, this entry will be 137 bytes, and in others it will be 143 bytes. The 137 byte length is the odd one, and if this happens when you create your file with the '1234' password, just create another file, and it should jump to the 143 byte length.
If you try to paste the wrong number of bytes into the file, you will lose your VBA project when you try to open the file with Excel.
EDIT
This is not valid for Excel 2007/2010 files. The standard .xlsx file format is actually a .zip file containing numerous sub-folders with the formatting, layout, content, etc, stored as xml data. For an unprotected Excel 2007 file, you can just change the .xlsx extension to .zip, then open the zip file and look through all the xml data. It's very straightforward.
However, when you password protect an Excel 2007 file, the entire .zip (.xlsx) file is actually encrypted using RSA encryption. It is no longer possible to change the extension to .zip and browse the file contents.
It's worth pointing out that if you have an Excel 2007 (xlsm) file, then you can simply save it as an Excel 2003 (xls) file and use the methods outlined in other answers.
VBA Project Passwords on Access, Excel, Powerpoint, or Word documents (2007, 2010, 2013 or 2016 versions with extensions .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM) can be easily removed.
It's simply a matter of changing the filename extension to .ZIP, unzipping the file, and using any basic Hex Editor (like XVI32) to "break" the existing password, which "confuses" Office so it prompts for a new password next time the file is opened.
A summary of the steps:
rename the file so it has a .ZIP extension.
open the ZIP and go to the XL folder.
extract vbaProject.bin and open it with a Hex Editor
"Search & Replace" to "replace all" changing DPB to DPX.
Save changes, place the .bin file back into the zip, return it to it's normal extension and open the file like normal.
ALT+F11 to enter the VB Editor and right-click in the Project Explorer to choose VBA Project Properties.
On the Protection tab, Set a new password.
Click OK, Close the file, Re-open it, hit ALT+F11.
Enter the new password that you set.
At this point you can remove the password completely if you choose to.
Complete instructions with a step-by-step video I made "way back when" are on YouTube here.
It's kind of shocking that this workaround has been out there for years, and Microsoft hasn't fixed the issue.
The moral of the story?
Microsoft Office VBA Project passwords are not to be relied upon for security of any sensitive information. If security is important, use third-party encryption software.
Have you tried simply opening them in OpenOffice.org?
I had a similar problem some time ago and found that Excel and Calc didn't understand each other's encryption, and so allowed direct access to just about everything.
This was a while ago, so if that wasn't just a fluke on my part it also may have been patched.
In the event that your block of
CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX"
in your 'known password' file is shorter than the existing block in the 'unknown password' file, pad your hex strings with trailing zeros to reach the correct length.
e.g.
CMG="xxxxxx"\r\nDPB="xxxxxxxx"\r\nGC="xxxxxxxxxx"
in the unknown password file, should be set to
CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000" to preserve file length.
I have also had this working with .XLA (97/2003 format) files in office 2007.
For Excel 2007 onward you need to change your file extension to .zip
In the archive there is a subfolder xl, in there you will find vbaProject.bin.
Follow the step above with vbaProject.bin then save it back in the archive.
Modify back your extension and voilà! (meaning follow steps above)
I tried some of solutions above and none of them works for me (excel 2007 xlsm file). Then i found another solution that even retrieve password, not just crack it.
Insert this code into module, run it and give it some time. It will recover your password by brute force.
Sub PasswordBreaker()
'Breaks worksheet password protection.
Dim i As Integer, j As Integer, k As Integer
Dim l As Integer, m As Integer, n As Integer
Dim i1 As Integer, i2 As Integer, i3 As Integer
Dim i4 As Integer, i5 As Integer, i6 As Integer
On Error Resume Next
For i = 65 To 66: For j = 65 To 66: For k = 65 To 66
For l = 65 To 66: For m = 65 To 66: For i1 = 65 To 66
For i2 = 65 To 66: For i3 = 65 To 66: For i4 = 65 To 66
For i5 = 65 To 66: For i6 = 65 To 66: For n = 32 To 126
ActiveSheet.Unprotect Chr(i) & Chr(j) & Chr(k) & _
Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & _
Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
If ActiveSheet.ProtectContents = False Then
MsgBox "One usable password is " & Chr(i) & Chr(j) & _
Chr(k) & Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & _
Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
Exit Sub
End If
Next: Next: Next: Next: Next: Next
Next: Next: Next: Next: Next: Next
End Sub
Colin Pickard is mostly correct, but don't confuse the "password to open" protection for the entire file with the VBA password protection, which is completely different from the former and is the same for Office 2003 and 2007 (for Office 2007, rename the file to .zip and look for the vbaProject.bin inside the zip). And that technically the correct way to edit the file is to use a OLE compound document viewer like CFX to open up the correct stream. Of course, if you are just replacing bytes, the plain old binary editor may work.
BTW, if you are wondering about the exact format of these fields, they have it documented now:
http://msdn.microsoft.com/en-us/library/dd926151%28v=office.12%29.aspx
If the file is a valid zip file (the first few bytes are 50 4B -- used in formats like .xlsm), then unzip the file and look for the subfile xl/vbaProject.bin. This is a CFB file just like the .xls files. Follow the instructions for the XLS format (applied to the subfile) and then just zip the contents.
For the XLS format, you can follow some of the other methods in this post. I personally prefer searching for the DPB= block and replacing the text
CMG="..."
DPB="..."
GC="..."
with blank spaces. This obviates CFB container size issues.
Tom - I made a schoolboy error initially as I didn't watch the byte size and instead I copied and pasted from the "CMG" set up to the subsequent entry. This was two different text sizes between the two files, though, and I lost the VBA project just as Stewbob warned.
Using HxD, there is a counter tracking how much file you're selecting. Copy starting from CMG until the counter reads 8F (hex for 143) and likewise when pasting into the locked file - I ended up with twice the number of "..." at the end of the paste, which looked odd somehow and felt almost unnatural, but it worked.
I don't know if it is crucial, but I made sure I shut both the hex editor and excel down before reopening the file in Excel. I then had to go through the menus to open the VB Editor, into VBProject Properties and entered in the 'new' password to unlock the code.
I hope this helps.
ElcomSoft makes Advanced Office Password Breaker and Advanced Office Password Recovery products which may apply to this case, as long as the document was created in Office 2007 or prior.
My tool, VbaDiff, reads VBA directly from the file, so you can use it to recover protected VBA code from most office documents without resorting to a hex editor.
The accepted answer didn't work in Excel 2019 on Windows 10. Found out the extra steps we need to take to see the locked macro. I am summarizing the steps.
Add a .zip to the end of the excel filename and hit enter
Once the file has been changed to a ZIP file, open it by double clicking on it
Inside you would see a folder called xl like below
Inside xl, you'll find a file called vbaProject.bin, copy/paste it on the desktop
Go to the online Hexadecimal Editor HexEd.it
Search for the following texts
DPB=...
and change them to
DPx=...
Save the file and close HexEd.it
Copy/Paste the updated file from your desktop inside the ZIP file (you would need to overwrite it)
Remove the .zip extension from the end of the filename and add the excel extention again.
Open the file in excel - you may receive a couple of error notifications, just click through them.
==== EXTRA STEPS OVER THE ACCEPTED ANSWER =====
Open the Visual Basic window (usually ALT+F11 if I remember correctly) and open the VBAProject properties (Tools menu).
Click on the Protection tab and change (do not remove at this stage) the password to something short and easy to remember (we'll be
removing in next step).
Save the workbook and then close and reopen.
Open again the Visual Basic window and enter the password you just put in. Redo the previous step but this time you can remove (delete)
the password.
Save the workbook and you have now removed the password.
Extra steps are taken from following site
https://confluence.jaytaala.com/display/TKB/Remove+Excel+VBA+password
The truth is that the code files for most macro-enabled Office documents are not encrypted and the password only prevents opening the project with Office programs.
This means that, as other answers suggested, you can usually use an Office alternative to access and edit the file.
However, if you just need access to the code, you can use a tool like oledump.py to extract the Macro code. This is useful for malware analysis, as well as getting most of the code from the file so that you don't have to start from scratch if you forget the password.
In addition, many excel files dynamically set the password when the file is opened. This means that if you can read the code, you can usually find the password in plaintext or de-obfuscate it.
oledump.py Examples:
List all "streams" (embedded binary or code files) within an office document:
python oledump.py -v yourExcelFile.xlsm
Output:
A: xl/vbaProject.bin
A1: 2000 'PROJECT'
A2: 1500 'PROJECTwm'
A3: M 1224 'VBA/Module1'
A4: M 18694 'VBA/Module2'
A5: M 11877 'VBA/Module3'
...
Streams with an M next to them are macros, which is unencrypted VBA code
Extract a stream
python oledump.py -s A3 -v yourExcelFile.xlsm > Module1.vba
This will output the code contained in the A3 stream to Module1.vba.
I usually combine this with a loop to extract all files to a folder. This quick PowerShell script will extract all streams in most files:
New-Item -ItemType Directory "Output"
# just hardcode the highest stream outputted by oledump.py -v
$max = 5
for ($i = 1; $i -le $max; $i++) {
python oledump.py -s "A$i" -v yourExcelFile.xlsm > ".\Output\A$i"
}
Note that this will only extract human-readable files.
The protection is a simple text comparison in Excel.
Load Excel in your favourite debugger (Ollydbg being my tool of choice), find the code that does the comparison and fix it to always return true, this should let you access the macros.
For Excel 2016 64-bit on a Windows 10 machine, I have used a hex editor to be able to change the password of a protected xla (have not tested this for any other extensions).
Tip: create a backup before you do this.
The steps I took:
Open the vba in the hex editor (for example XVI)
Search on this DPB
Change DPB to something else, like DPX
Save it!
Reopen the .xla, an error message will appear, just continue.
You can now change the password of the .xla by opening the properties and go to the password tab.
I hope this helped some of you!
If you work in Java you may try VBAMacroExtractor. After extracting VBA scripts from .xlsm I've found there password in plaintext.
your excel file's extension change to xml.
And open it in notepad.
password text find in xml file.
you see like below line;
Sheets("Sheet1").Unprotect Password:="blabla"
(sorry for my bad english)
One simple way to remove VBA project password is to do the following:
Convert xlsm file into zip
open the VBAProject.bin file inside (i prefer to use Notepad++ (https://notepad-plus-plus.org/downloads/)
Search for DPB field
Replace it with DPx
Save file
conver the zip file into xlsm
open the excel file
Click yes if you get a message box
set a new password for the VBA project properties
close and open the file again
type your new password to unprotect

Is there a way to crack the password on an Excel VBA Project?

I've been asked to update some Excel 2003 macros, but the VBA projects are password protected, and it seems there's a lack of documentation... no-one knows the passwords.
Is there a way of removing or cracking the password on a VBA project?
You can try this direct VBA approach which doesn't require HEX editing. It will work for any files (*.xls, *.xlsm, *.xlam ...).
Tested and works on:
Excel 2007
Excel 2010
Excel 2013 - 32 bit version
Excel 2016 - 32 bit version
Looking for 64 bit version? See this answer
How it works
I will try my best to explain how it works - please excuse my English.
The VBE will call a system function to create the password dialog box.
If user enters the right password and click OK, this function returns 1. If user enters the wrong password or click Cancel, this function returns 0.
After the dialog box is closed, the VBE checks the returned value of the system function
if this value is 1, the VBE will "think" that the password is right, hence the locked VBA project will be opened.
The code below swaps the memory of the original function used to display the password dialog with a user defined function that will always return 1 when being called.
Using the code
Please backup your files first!
Open the file(s) that contain your locked VBA Projects
Create a new xlsm file and store this code in Module1
code credited to Siwtom (nick name), a Vietnamese developer
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Long, Source As Long, ByVal Length As Long)
Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Long, _
ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, _
ByVal lpProcName As String) As Long
Private Declare Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As Long, _
ByVal pTemplateName As Long, ByVal hWndParent As Long, _
ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As Long
Dim Flag As Boolean
Private Function GetPtr(ByVal Value As Long) As Long
GetPtr = Value
End Function
Public Sub RecoverBytes()
If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 5) As Byte
Dim p As Long
Dim OriginProtect As Long
Hook = False
pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
If VirtualProtect(ByVal pFunc, 6, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 6
If TmpBytes(0) <> &H68 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 6
p = GetPtr(AddressOf MyDialogBoxParam)
HookBytes(0) = &H68
MoveMemory ByVal VarPtr(HookBytes(1)), ByVal VarPtr(p), 4
HookBytes(5) = &HC3
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 6
Flag = True
Hook = True
End If
End If
End Function
Private Function MyDialogBoxParam(ByVal hInstance As Long, _
ByVal pTemplateName As Long, ByVal hWndParent As Long, _
ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
If pTemplateName = 4070 Then
MyDialogBoxParam = 1
Else
RecoverBytes
MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
hWndParent, lpDialogFunc, dwInitParam)
Hook
End If
End Function
Paste this code under the above code in Module1 and run it
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Come back to your VBA Projects and enjoy.
Yes there is, as long as you are using a .xls format spreadsheet (the default for Excel up to 2003). For Excel 2007 onwards, the default is .xlsx, which is a fairly secure format, and this method will not work.
As Treb says, it's a simple comparison. One method is to simply swap out the password entry in the file using a hex editor (see Hex editors for Windows). Step by step example:
Create a new simple excel file.
In the VBA part, set a simple password (say - 1234).
Save the file and exit. Then check the file size - see Stewbob's gotcha
Open the file you just created with a hex editor.
Copy the lines starting with the following keys:
CMG=....
DPB=...
GC=...
FIRST BACKUP the excel file you don't know the VBA password for, then open it with your hex editor, and paste the above copied lines from the dummy file.
Save the excel file and exit.
Now, open the excel file you need to see the VBA code in. The password for the VBA code
will simply be 1234 (as in the example I'm showing here).
If you need to work with Excel 2007 or 2010, there are some other answers below which might help, particularly these: 1, 2, 3.
EDIT Feb 2015: for another method that looks very promising, look at this new answer by Đức Thanh Nguyễn.
I've built upon Đức Thanh Nguyễn's fantastic answer to allow this method to work with 64-bit versions of Excel. I'm running Excel 2010 64-Bit on 64-Bit Windows 7.
Open the file(s) that contain your locked VBA Projects.
Create a new xlsm file and store this code in Module1
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare PtrSafe Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As LongPtr, Source As LongPtr, ByVal Length As LongPtr)
Private Declare PtrSafe Function VirtualProtect Lib "kernel32" (lpAddress As LongPtr, _
ByVal dwSize As LongPtr, ByVal flNewProtect As LongPtr, lpflOldProtect As LongPtr) As LongPtr
Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, _
ByVal lpProcName As String) As LongPtr
Private Declare PtrSafe Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean
Private Function GetPtr(ByVal Value As LongPtr) As LongPtr
GetPtr = Value
End Function
Public Sub RecoverBytes()
If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 5) As Byte
Dim p As LongPtr
Dim OriginProtect As LongPtr
Hook = False
pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
If VirtualProtect(ByVal pFunc, 6, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 6
If TmpBytes(0) <> &H68 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 6
p = GetPtr(AddressOf MyDialogBoxParam)
HookBytes(0) = &H68
MoveMemory ByVal VarPtr(HookBytes(1)), ByVal VarPtr(p), 4
HookBytes(5) = &HC3
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 6
Flag = True
Hook = True
End If
End If
End Function
Private Function MyDialogBoxParam(ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
If pTemplateName = 4070 Then
MyDialogBoxParam = 1
Else
RecoverBytes
MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
hWndParent, lpDialogFunc, dwInitParam)
Hook
End If
End Function
Paste this code in Module2 and run it
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
DISCLAIMER This worked for me and I have documented it here in the hope it will help someone out. I have not fully tested it. Please be sure to save all open files before proceeding with this option.
There is another (somewhat easier) solution, without the size problems. I used this approach today (on a 2003 XLS file, using Excel 2007) and was successful.
Backup the xls file
Open the file in a HEX editor and locate the DPB=... part
Change the DPB=... string to DPx=...
Open the xls file in Excel
Open the VBA editor (ALT + F11)
the magic:
Excel discovers an invalid key (DPx) and asks whether you want to continue loading the project (basically ignoring the protection)
You will be able to overwrite the password, so change it to something you can remember
Save the xls file*
Close and reopen the document and work your VBA magic!
*NOTE: Be sure that you have changed the password to a new value, otherwise the next time you open the spreadsheet Excel will report errors (Unexpected Error), then when you access the list of VBA modules you will now see the names of the source modules but receive another error when trying to open forms/code/etc. To remedy this, go back to the VBA Project Properties and set the password to a new value. Save and re-open the Excel document and you should be good to go!
For a .xlsm or .dotm file type you need to do it a slightly different way.
Change the extension of the .xlsm file to .zip.
Open the .zip file (with WinZip or WinRar etc) and go to the xl folder.
Extract the vbaProject.bin file and open it in a Hex Editor (I use HxD, its completely free and lightweight.)
Search for DPB and replace with DPx and save the file.
Replace the old vbaProject.bin file with this new on in the zipped file.
Change the file extension back to .xlsm.
Open workbook skip through the warning messages.
Open up Visual Basic inside Excel.
Go to Tools > VBAProject Properties > Protection Tab.
Put in a new password and save the .xlsm file.
Close and re open and your new password will work.
Edit: this is an updated version of the accepted answer and should work on more office versions. It's tough but let's get this answer to the top!
With my turn, this is built upon kaybee99's excellent answer which is built upon Đức Thanh Nguyễn's fantastic answer to allow this method to work with both 32/64 bit versions of Office.
An overview of what is changed, we avoid push/ret which is limited to 32bit addresses and replace it with mov/jmp reg.
how it works
Open the file(s) that contain your locked VBA Projects.
Create a new file with the same type as the above and store this code in Module1
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare PtrSafe Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As LongPtr, Source As LongPtr, ByVal Length As LongPtr)
Private Declare PtrSafe Function VirtualProtect Lib "kernel32" (lpAddress As LongPtr, _
ByVal dwSize As LongPtr, ByVal flNewProtect As LongPtr, lpflOldProtect As LongPtr) As LongPtr
Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, _
ByVal lpProcName As String) As LongPtr
Private Declare PtrSafe Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
Dim HookBytes(0 To 11) As Byte
Dim OriginBytes(0 To 11) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean
Private Function GetPtr(ByVal Value As LongPtr) As LongPtr
GetPtr = Value
End Function
Public Sub RecoverBytes()
If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 12
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 11) As Byte
Dim p As LongPtr, osi As Byte
Dim OriginProtect As LongPtr
Hook = False
#If Win64 Then
osi = 1
#Else
osi = 0
#End If
pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
If VirtualProtect(ByVal pFunc, 12, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, osi+1
If TmpBytes(osi) <> &HB8 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 12
p = GetPtr(AddressOf MyDialogBoxParam)
If osi Then HookBytes(0) = &H48
HookBytes(osi) = &HB8
osi = osi + 1
MoveMemory ByVal VarPtr(HookBytes(osi)), ByVal VarPtr(p), 4 * osi
HookBytes(osi + 4 * osi) = &HFF
HookBytes(osi + 4 * osi + 1) = &HE0
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 12
Flag = True
Hook = True
End If
End If
End Function
Private Function MyDialogBoxParam(ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
If pTemplateName = 4070 Then
MyDialogBoxParam = 1
Else
RecoverBytes
MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
hWndParent, lpDialogFunc, dwInitParam)
Hook
End If
End Function
Paste this code in Module2 and run it
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Colin Pickard has an excellent answer, but there is one 'watch out' with this. There are instances (I haven't figured out the cause yet) where the total length of the "CMG=........GC=...." entry in the file is different from one excel file to the next. In some cases, this entry will be 137 bytes, and in others it will be 143 bytes. The 137 byte length is the odd one, and if this happens when you create your file with the '1234' password, just create another file, and it should jump to the 143 byte length.
If you try to paste the wrong number of bytes into the file, you will lose your VBA project when you try to open the file with Excel.
EDIT
This is not valid for Excel 2007/2010 files. The standard .xlsx file format is actually a .zip file containing numerous sub-folders with the formatting, layout, content, etc, stored as xml data. For an unprotected Excel 2007 file, you can just change the .xlsx extension to .zip, then open the zip file and look through all the xml data. It's very straightforward.
However, when you password protect an Excel 2007 file, the entire .zip (.xlsx) file is actually encrypted using RSA encryption. It is no longer possible to change the extension to .zip and browse the file contents.
It's worth pointing out that if you have an Excel 2007 (xlsm) file, then you can simply save it as an Excel 2003 (xls) file and use the methods outlined in other answers.
VBA Project Passwords on Access, Excel, Powerpoint, or Word documents (2007, 2010, 2013 or 2016 versions with extensions .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM) can be easily removed.
It's simply a matter of changing the filename extension to .ZIP, unzipping the file, and using any basic Hex Editor (like XVI32) to "break" the existing password, which "confuses" Office so it prompts for a new password next time the file is opened.
A summary of the steps:
rename the file so it has a .ZIP extension.
open the ZIP and go to the XL folder.
extract vbaProject.bin and open it with a Hex Editor
"Search & Replace" to "replace all" changing DPB to DPX.
Save changes, place the .bin file back into the zip, return it to it's normal extension and open the file like normal.
ALT+F11 to enter the VB Editor and right-click in the Project Explorer to choose VBA Project Properties.
On the Protection tab, Set a new password.
Click OK, Close the file, Re-open it, hit ALT+F11.
Enter the new password that you set.
At this point you can remove the password completely if you choose to.
Complete instructions with a step-by-step video I made "way back when" are on YouTube here.
It's kind of shocking that this workaround has been out there for years, and Microsoft hasn't fixed the issue.
The moral of the story?
Microsoft Office VBA Project passwords are not to be relied upon for security of any sensitive information. If security is important, use third-party encryption software.
Have you tried simply opening them in OpenOffice.org?
I had a similar problem some time ago and found that Excel and Calc didn't understand each other's encryption, and so allowed direct access to just about everything.
This was a while ago, so if that wasn't just a fluke on my part it also may have been patched.
In the event that your block of
CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX"
in your 'known password' file is shorter than the existing block in the 'unknown password' file, pad your hex strings with trailing zeros to reach the correct length.
e.g.
CMG="xxxxxx"\r\nDPB="xxxxxxxx"\r\nGC="xxxxxxxxxx"
in the unknown password file, should be set to
CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000" to preserve file length.
I have also had this working with .XLA (97/2003 format) files in office 2007.
For Excel 2007 onward you need to change your file extension to .zip
In the archive there is a subfolder xl, in there you will find vbaProject.bin.
Follow the step above with vbaProject.bin then save it back in the archive.
Modify back your extension and voilà! (meaning follow steps above)
I tried some of solutions above and none of them works for me (excel 2007 xlsm file). Then i found another solution that even retrieve password, not just crack it.
Insert this code into module, run it and give it some time. It will recover your password by brute force.
Sub PasswordBreaker()
'Breaks worksheet password protection.
Dim i As Integer, j As Integer, k As Integer
Dim l As Integer, m As Integer, n As Integer
Dim i1 As Integer, i2 As Integer, i3 As Integer
Dim i4 As Integer, i5 As Integer, i6 As Integer
On Error Resume Next
For i = 65 To 66: For j = 65 To 66: For k = 65 To 66
For l = 65 To 66: For m = 65 To 66: For i1 = 65 To 66
For i2 = 65 To 66: For i3 = 65 To 66: For i4 = 65 To 66
For i5 = 65 To 66: For i6 = 65 To 66: For n = 32 To 126
ActiveSheet.Unprotect Chr(i) & Chr(j) & Chr(k) & _
Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & _
Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
If ActiveSheet.ProtectContents = False Then
MsgBox "One usable password is " & Chr(i) & Chr(j) & _
Chr(k) & Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & _
Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
Exit Sub
End If
Next: Next: Next: Next: Next: Next
Next: Next: Next: Next: Next: Next
End Sub
Colin Pickard is mostly correct, but don't confuse the "password to open" protection for the entire file with the VBA password protection, which is completely different from the former and is the same for Office 2003 and 2007 (for Office 2007, rename the file to .zip and look for the vbaProject.bin inside the zip). And that technically the correct way to edit the file is to use a OLE compound document viewer like CFX to open up the correct stream. Of course, if you are just replacing bytes, the plain old binary editor may work.
BTW, if you are wondering about the exact format of these fields, they have it documented now:
http://msdn.microsoft.com/en-us/library/dd926151%28v=office.12%29.aspx
If the file is a valid zip file (the first few bytes are 50 4B -- used in formats like .xlsm), then unzip the file and look for the subfile xl/vbaProject.bin. This is a CFB file just like the .xls files. Follow the instructions for the XLS format (applied to the subfile) and then just zip the contents.
For the XLS format, you can follow some of the other methods in this post. I personally prefer searching for the DPB= block and replacing the text
CMG="..."
DPB="..."
GC="..."
with blank spaces. This obviates CFB container size issues.
Tom - I made a schoolboy error initially as I didn't watch the byte size and instead I copied and pasted from the "CMG" set up to the subsequent entry. This was two different text sizes between the two files, though, and I lost the VBA project just as Stewbob warned.
Using HxD, there is a counter tracking how much file you're selecting. Copy starting from CMG until the counter reads 8F (hex for 143) and likewise when pasting into the locked file - I ended up with twice the number of "..." at the end of the paste, which looked odd somehow and felt almost unnatural, but it worked.
I don't know if it is crucial, but I made sure I shut both the hex editor and excel down before reopening the file in Excel. I then had to go through the menus to open the VB Editor, into VBProject Properties and entered in the 'new' password to unlock the code.
I hope this helps.
ElcomSoft makes Advanced Office Password Breaker and Advanced Office Password Recovery products which may apply to this case, as long as the document was created in Office 2007 or prior.
My tool, VbaDiff, reads VBA directly from the file, so you can use it to recover protected VBA code from most office documents without resorting to a hex editor.
The accepted answer didn't work in Excel 2019 on Windows 10. Found out the extra steps we need to take to see the locked macro. I am summarizing the steps.
Add a .zip to the end of the excel filename and hit enter
Once the file has been changed to a ZIP file, open it by double clicking on it
Inside you would see a folder called xl like below
Inside xl, you'll find a file called vbaProject.bin, copy/paste it on the desktop
Go to the online Hexadecimal Editor HexEd.it
Search for the following texts
DPB=...
and change them to
DPx=...
Save the file and close HexEd.it
Copy/Paste the updated file from your desktop inside the ZIP file (you would need to overwrite it)
Remove the .zip extension from the end of the filename and add the excel extention again.
Open the file in excel - you may receive a couple of error notifications, just click through them.
==== EXTRA STEPS OVER THE ACCEPTED ANSWER =====
Open the Visual Basic window (usually ALT+F11 if I remember correctly) and open the VBAProject properties (Tools menu).
Click on the Protection tab and change (do not remove at this stage) the password to something short and easy to remember (we'll be
removing in next step).
Save the workbook and then close and reopen.
Open again the Visual Basic window and enter the password you just put in. Redo the previous step but this time you can remove (delete)
the password.
Save the workbook and you have now removed the password.
Extra steps are taken from following site
https://confluence.jaytaala.com/display/TKB/Remove+Excel+VBA+password
The truth is that the code files for most macro-enabled Office documents are not encrypted and the password only prevents opening the project with Office programs.
This means that, as other answers suggested, you can usually use an Office alternative to access and edit the file.
However, if you just need access to the code, you can use a tool like oledump.py to extract the Macro code. This is useful for malware analysis, as well as getting most of the code from the file so that you don't have to start from scratch if you forget the password.
In addition, many excel files dynamically set the password when the file is opened. This means that if you can read the code, you can usually find the password in plaintext or de-obfuscate it.
oledump.py Examples:
List all "streams" (embedded binary or code files) within an office document:
python oledump.py -v yourExcelFile.xlsm
Output:
A: xl/vbaProject.bin
A1: 2000 'PROJECT'
A2: 1500 'PROJECTwm'
A3: M 1224 'VBA/Module1'
A4: M 18694 'VBA/Module2'
A5: M 11877 'VBA/Module3'
...
Streams with an M next to them are macros, which is unencrypted VBA code
Extract a stream
python oledump.py -s A3 -v yourExcelFile.xlsm > Module1.vba
This will output the code contained in the A3 stream to Module1.vba.
I usually combine this with a loop to extract all files to a folder. This quick PowerShell script will extract all streams in most files:
New-Item -ItemType Directory "Output"
# just hardcode the highest stream outputted by oledump.py -v
$max = 5
for ($i = 1; $i -le $max; $i++) {
python oledump.py -s "A$i" -v yourExcelFile.xlsm > ".\Output\A$i"
}
Note that this will only extract human-readable files.
The protection is a simple text comparison in Excel.
Load Excel in your favourite debugger (Ollydbg being my tool of choice), find the code that does the comparison and fix it to always return true, this should let you access the macros.
For Excel 2016 64-bit on a Windows 10 machine, I have used a hex editor to be able to change the password of a protected xla (have not tested this for any other extensions).
Tip: create a backup before you do this.
The steps I took:
Open the vba in the hex editor (for example XVI)
Search on this DPB
Change DPB to something else, like DPX
Save it!
Reopen the .xla, an error message will appear, just continue.
You can now change the password of the .xla by opening the properties and go to the password tab.
I hope this helped some of you!
If you work in Java you may try VBAMacroExtractor. After extracting VBA scripts from .xlsm I've found there password in plaintext.
your excel file's extension change to xml.
And open it in notepad.
password text find in xml file.
you see like below line;
Sheets("Sheet1").Unprotect Password:="blabla"
(sorry for my bad english)
One simple way to remove VBA project password is to do the following:
Convert xlsm file into zip
open the VBAProject.bin file inside (i prefer to use Notepad++ (https://notepad-plus-plus.org/downloads/)
Search for DPB field
Replace it with DPx
Save file
conver the zip file into xlsm
open the excel file
Click yes if you get a message box
set a new password for the VBA project properties
close and open the file again
type your new password to unprotect

Resources