Ghidra + MSDN Offline Library = ❤️



A while back [I blawgd about how to get the MSDN library for offline use](https://blag.nullteilerfrei.de/2017/12/21/get-the-msdn-library-for-offline-use/). However, the Help Viewer has its problems. I won't list all of its problems, but it was certainly a bad candidate to integrate Win32 API documentation support to Ghidra. There is [a pretty neat project by Laurence Jackson](http://laurencejackson.com/win32/), but I think I just found something a little better even: Microsoft provides [a download of the MSDN Library for Visual Studio 2008 SP1, stand-alone, offline, as an ISO](https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=20955) - smell this, Help Viewer: <img decoding="async" src="https://blag.nullteilerfrei.de/wp-content/uploads/2019/07/CreateFile.MSDN_.2008.png" class="aligncenter size-medium wp-image-4794"/> So this is nice, but the main point of this exercise was to integrate this into Ghidra. If that's something you care about, <span id="more-4786"></span>read on. ## Integrating this into Ghidra After installing the MSDN for VS2008 to the default location, I took a [neat script](https://github.com/0x6d696368/ghidra_scripts/blob/master/GoogleSearch.py) by _mich_ (I take him for a big Endian kinda guy) and modified it as follows: ```python # Attempt to look up currently higlighted Windows API calls in the MSDN Library. #@category Search #@keybinding F2 import shlex import os import subprocess from ghidra.program.model.symbol import FlowType def searchMSDN(topic): def getViewerPath(*commonFilesPathCandidates): for baseDir in commonFilesPathCandidates: path = os.path.join(baseDir, 'microsoft shared', 'Help 9', 'dexplore.exe') if os.path.exists(path): return path viewer = getViewerPath( os.environ.get('CommonProgramFiles(x86)', ''), os.environ.get('CommonProgramFiles', ''), R'C:\Program Files (x86)\Common Files', R'C:\Program Files\Common Files' ) command = '"{}" /helpcol ms-help://MS.MSDNQTR.v90.en /LaunchFKeywordTopic {}'.format(viewer, topic) return subprocess.call(shlex.split(command)) def searchAddress(address): try: search = getFunctionAt(address).getName() except AttributeError: raise Exception('No reference found for address {}'.format(address)) if search.startswith('FID_conflict:'): search = search[13:] return search def getReferenceName(address, level=0): assert level < 5 for reference in getReferencesFrom(address): if reference.isExternalReference(): return reference.getLabel() if reference.getReferenceType() == FlowType.UNCONDITIONAL_CALL: try: return searchAddress(reference.getToAddress()) except Exception: pass if reference.getReferenceType() == FlowType.INDIRECTION: return getReferenceName(reference.getToAddress(), level + 1) else: return searchAddress(address) try: searchMSDN(getReferenceName(currentAddress)) except Exception as E: print 'ERROR: Help lookup failed: {}'.format(E) ``` I put this into `%USERPROFILE%\ghidra_scripts`, and sure enough, I could bind this to the F2 key: <img fetchpriority="high" decoding="async" width="1025" height="640" src="https://blag.nullteilerfrei.de/wp-content/uploads/2019/07/LaunchMSDN.In_.Script.Manager.png" class="aligncenter size-medium wp-image-4794" style="border:1px solid black" srcset="https://blag.nullteilerfrei.de/wp-content/uploads/2019/07/LaunchMSDN.In_.Script.Manager.png 1025w, https://blag.nullteilerfrei.de/wp-content/uploads/2019/07/LaunchMSDN.In_.Script.Manager-300x187.png 300w, https://blag.nullteilerfrei.de/wp-content/uploads/2019/07/LaunchMSDN.In_.Script.Manager-768x480.png 768w, https://blag.nullteilerfrei.de/wp-content/uploads/2019/07/LaunchMSDN.In_.Script.Manager-1024x639.png 1024w" sizes="(max-width: 1025px) 100vw, 1025px" /> Using it is a painfully slow process, but it works. This is me testing it on a [Phorpiex](https://malpedia.caad.fkie.fraunhofer.de/details/win.phorpiex) sample: <img decoding="async" src="https://blag.nullteilerfrei.de/wp-content/uploads/2019/07/Lookup.MSDN_.From_.Ghidra.gif.gif" alt="MSDN Lookup from Ghidra" width="100%" class="aligncenter size-medium wp-image-4792" style="border:1px solid black"/> ### Conclusion I can't believe I am going to say this, but here it goes: > _"Maybe I should rewrite this in Java for better performance."_

Tags: - - -

2 Replies to “Ghidra + MSDN Offline Library = ❤️”

  1. Oh nice, very glad to hear it! I only checked comments just now to say that I updated the script slightly to accommodate `FlowType.INDIRECTION`.

Leave a Reply

Your email address will not be published. Required fields are marked *