MSO.DLL is a ‘magic’ Microsoft Library that is HUUUUUGE in size and does most of the Microsoft Office work. I have been massaging it for many years and always doing so with a feeling that I am not understanding anything at all. And I really do not even pretend to have any grasp of any piece of it, but I decided to describe what I found out so far, because it may lead us to some places new.
Okay… Where do we start?
MSO.DLL is literally 25MB+ long. It’s a HUUUUUGE DLL. It is crazy, it is loco, it exports 9K APIs last time I checked and many of them via ordinal only. IDA won’t help, and any attempts to analyze it in a conventional way end up with a big, giant, mix of who-knows-what. This code is doing lots of great work, but who knows how it works… I mean… really…
In any case… Adding _any_ sense to such a big pile of code is useful. How? For starters, we can identify wrappers. What are these wrappers? It turns out that MSO.DLL exports a lot of functions that do nothing but wrapping common Windows API around.
I know, we need an example…
Take MSO #222. This function requires two arguments: address of a buffer, and its size. It then fills in that buffer with… yup… whatever a call to GetComputerNameW provides — it just passes the arguments to the final Windows API! Oh, wrappers are easy!
When I spotted this the first time I started digging more and noticed that there is a clearly visible pattern inside mso.dll that tells us about many exported APIs being nothing more but wrappers. If we are patient enough we may effortlessly identify a meaning of many MSO exported functions by just looking at the wrapped APIs they encapsulate…!
And to give a quick, although non-nonsensical demo…. when we run a following export API via rundll:
rundll32 MSO.DLL, #2310
it gives us this message:
It’s just one of 9K APIs that we just understood at the most possible lowest level — it is not implemented and we can all move on!
Divide and conquer approach apparently works. The below list summarizes the wrapper info I could gather so far; the arguments these functions take is a different story, but what’s interesting is that they do wrap lots of common APIs which could be abused in many way.
For starters, imagine an .exe that instead of loading and using common advapi32 or user32.dll APIs to deliver some functionality, proxies it via an existing mso.dll. Ouch. Try to filter this stuff out Mr EDR Threat Hunter!
Yup. Wrapping is condoming. And condoming is avoiding signatures. And to be clear and avoid any doubt: I can imagine a malware taking an advantage of MSO.DLL and delivering lots of its functionality via the wrapped API Calls. Try to sandbox or EDR it out. Good luck!