https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools

All Credit goes to James Forshaw, he is just awesome!

Recently stepped upon on this tool https://github.com/cyberark/RPCMon which was mentioned by my colleague Lee, he is awesome!

So as I am interested in this new tool, I decided to give its source a read and trying to learn something new.

Which brings me back to James’ tools again, So I thought, why not just get myself familiar with the James tool and come up something on my own in the end.

The NtApiDotNet.dll exposed bunch of functions that will allow us to interact, parse, create windows objects dynamically, It is also heavily used in NtObjectManager.ps1 which you can import as a powershell module and enjoy all its power.

So, how does james do it? The answer is: Magic… Really…

I wanted to dive into how the we can use NtApiDotNet.dll to parse RPC servers from the .dll, .exe files on disk. Which is ParsePeFile() at sandbox-attacksurface-analysis-tools-main\\NtApiDotNet\\Win32\\RpcServer.cs:271 and used by RPCMon at https://github.com/cyberark/RPCMon/blob/f8b1935352764323d83fddb0eb56d89ff269f21e/RPCMon/Control/Engine.cs#L265

The function signature looks like public static IEnumerable<RpcServer> ParsePeFile(string file, string dbghelp_path, string symbol_path, RpcServerParserFlags flags) which will takes in .dll,.exe file path, debuggerfile path, symbols filepath, also a RpcServerParserFlags enum which looks like this .

public enum RpcServerParserFlags
    {
        /// <summary>
        /// None.
        /// </summary>
        None = 0,
        /// <summary>
        /// Parse client entries.
        /// </summary>
        ParseClients = 1,
        /// <summary>
        /// Ignore symbols when parsing.
        /// </summary>
        IgnoreSymbols = 2,
        /// <summary>
        /// Try and resolve structure names. Needs private symbols.
        /// </summary>
        ResolveStructureNames = 4,
        /// <summary>
        /// Enable a symbol server fallback. If the copy of dbghelp doesn't have a symsrv.dll
        /// then download from a public symbol URL to a local cache directory during symbol
        /// resolving.
        /// </summary>
        SymSrvFallback = 8,
    }

next it will come to a use of LoadLibarayEx which is different than LoadLibrary by The action to be taken when loading the module. Here is LoadLibraryFlags.DontResolveDllReferences which doesn’t load anyother resources of the DLL and does not call Dllmain when loaded.

Which upon success loading, James puts the handle of that newly loaded DLL to a class called SafeLoadLibraryHandle which have bunch of public methods to use such as GetProcAddress()...

After gainning the handle to loaded module, It will tend to find hardcoded byte sequence for