Upon starting a new role in a new team at a new company, one of the IT processes that was not fully understood by existing staff was how desktop shortcuts to file shares were created on user's desktops. Here is a rundown of my process to "reverse engineer" this shortcut creation process, as well as modify it when requirements changed.
A request came in asking for a new file share to be created and a shortcut to it to be placed in the "NetworkShortcuts" folder on the user's desktop. The level 1 team manually create the share and security group, but the shortcut is not being created. When the shortcut is manually created, the next day it is no longer in the NetworkShortcuts folder.
Two files which the level 1 team were aware of related to this process were the "ShortCutReader.exe" application and a "win7shortcuts.vbs" file on the root partition of each user's computer. The app was run each time a new staff member joined in order for their shortcuts to appear. The win7shortcuts.vbs file was tied to a Group Policy Object (GPO) that ran each time a user logged on.
Reverse engineering shortcut creation process
Reading the win7shortcuts.vbs file to start with, I determined each time it ran, it created the NetworkShortcuts folder on the desktop via...
sub CreateFolder() on error resume next Set objFSO = CreateObject("Scripting.FileSystemObject") Set objShell = CreateObject("Wscript.Shell") strPathDesktop = objShell.SpecialFolders("Desktop") if objFSO.FolderExists(strPathDesktop & "\NetworkShortcuts") Then set objFolderTemp = objFSO.getFolder(strPathDesktop & "\NetworkShortcuts") wscript.sleep(2000) objFolderTemp.delete True wscript.sleep(5000) end if objFSO.CreateFolder(strPathDesktop & "\NetworkShortcuts") set objFSO = nothing set objShell = nothing end sub
... followed by connecting to a database, and selecting the share name and server name for the logged in user...
function iterateGroupsFinal() tshortcuts = 0 DBNAME = "Usershortcuts" DBSource = "SQL01" Set conDatabaseShortcuts = CreateObject("ADODB.Connection") conDatabaseShortcuts.Open "Provider=sqloledb;" & "Data Source=" & DBSource & ";" & "Initial CataLog=" & DBName & ";" & "Integrated Security=SSPI" sqlStmt = "Select sharename, servername from Shortcuts where displayname = '" & getLoggedInUser() & "'" Set rsShortcuts = conDatabaseShortcuts.Execute(sqlstmt) If Not rsShortcuts.EOF Then Do While Not rsShortcuts.eof Call createShortcut(Trim(rsShortcuts.Fields("servername").value), Trim(rsShortcuts.Fields("sharename").value)) tshortcuts = tshortcuts + 1 rsShortcuts.movenext Loop End If Set rsShortcuts = Nothing Set conDatabaseShortcuts = Nothing iterateGroupsFinal = tshortcuts End function
... ending with the creation of each shortcut for each share discovered:
sub createShortcut(servername, sharename) ' add the server prefixes if servername = "fs1" Then servername = "acme-fs1" Else servername = "acme-" & servername end If Set WSHShell = WScript.CreateObject("WScript.Shell") DesktopPath = WSHShell.SpecialFolders("Desktop") if testping(servername) then on error resume next Set theShortcut = WSHShell.CreateShortcut(DesktopPath & "\NetworkShortCuts\" & sharename & " on " & servername &".lnk") theShortcut.TargetPath = WSHShell.ExpandEnvironmentStrings("\\" & servername & "\" & sharename) theShortcut.WindowStyle = 4 theShortcut.IconLocation = WSHShell.ExpandEnvironmentStrings("%windir%\explorer.exe, 0") theShortcut.Save end if end Sub
Now that I had the database server name and instance, I connected to the database and ran a SELECT query on myself. Sure enough, the shortcuts that I had on my desktop matched what was in the relevant table mentioned in the vbs file.
I manually created a security group in the format "SG_fs1_test", forced an AD sync then re-ran the ShortcutReader script. The shortcut was created!
When running this app, it enumerates all enabled AD users and their security groups, then adds those with the prefix "SG_fs1_" to the Shortcuts table in the Usershortcuts database, which is what the vbs script looks at.
Troubleshooting shortcuts not being created
About a year later after the initial discovery, the shortcut application stopped working. When running the application, it would not proceed past the 'reading from domain' step:
I tried running this on different computers and different zones of the network to rule out any issues with connectivity to the domain controllers. When this produced the same result, I decided to look at the actual source of the application. After some web searches, I understood I needed a decompiler to achieve this, and the recommended one was JetBrains dotPeek.
After installing dotPeek, I pointed it to the directory of the shortcut application. The first file in the list was "ADHandler", so I double-clicked on this file and it opened it as "ADHandler.cs". The ".cs" extension is for C# source code files, so now I understood I was dealing with C# (whereas I'm only using Powershell day-to-day).
In the middle of the screen was the variable "sServiceUser" and "sServicePassword". The user account being used for this application was an over-privileged service account recently decommissioned a week or two prior to the reports of the app no longer working. With the help of the DBA, we created a new service account specifically for this application that only had access to this database instance.
In order to update this ADHandler.dll file, I went looking for the original source file, and found it in a neighbouring folder with the source of the shortcut application. I opened the file in Visual Studio and proceeded to update the user account info in the sServiceUser and sServicePassword variables. I then selected the 'Build Current Document' option from the Build menu. Renaming the original version as a backup, I moved the newly updated ADHandler.dll with the new service account into the same directory. Running the shortcut app again, it proceeded past the 'reading from domain' stage and created shortcuts as before.
Thanks for reading! This process took several days of troubleshooting and culminated in getting some exposure to vb script and C#, using a decompiler to further understand how an application worked, and then re-compiling after changes were made.