8 ms·
Microsoft Has Manually Patched Their Equation Editor Executable
- mariusmg 9y agoWhy is this so newsworthy ? Crackers do it every day :)
- grandpoobah 9y agoWe prefer the term 'people of non-colour'.
- lima 9y agoAnd here I am, manually patching Docker containers...
- atupis 9y agoJust why?
- dullgiulio 9y agoBecause they are immutable /s
- nicktelford 9y agoThere's only two reasons I can think of why they'd patch the binary directly: either they've lost the source-code, or they no longer have an environment they can build it in.
- leoc 9y agoFor ages Alan Kay has been claiming to know that MS has lost part of the Word codebase.
- khstangherlin 9y agoThis do make a lot of sense. I don't think there is exe calls directly linked from other apps. If that were the case they would just update the address in the calling app. Much easier. Anyway, very nice piece of work. :)
- nimish 9y agoMicrosoft has lost tons of code over the years. Even with the source, refactoring office which has people using file formats that are binary dumps of memory, is not trivial.
- leeter 9y agoThis was actually the Onus for the switch to the XML formats IIRC. Basically after the DOJ settlement they had the uneasy realization that the requirement to document the .doc format was going to be a nightmare because nobody had a complete spec of it. To make it worse the code wasn't very portable and customers were asking for x64 support pretty hard at the time.
- rangibaby 9y agoRe: 64 bit is that about Excel? I found the idea of a Word document needing >4GB RAM somewhat absurd
- pjmlp 9y agoI can imagine users just pasting images without a 2nd thought about their sizes. I routinely update single page Powerpoints with more than 4 MB, due to the background image or logos.
- acdha 9y agoNote that due to the way the 32-bit address space was laid out, a process could really use only about 2GB of RAM — the extra 2GB was reserved for the system based on old 386-era CPU limitations. Since that space had various things allocated in it, a normal program generally wouldn't get more than 1.7GB in a single allocation — e.g. according to https://support.microsoft.com/en-us/help/313275/-not-enough-memory-error-messages-when-you-copy-formulas-over-large-ar https://support.microsoft.com/en-us/help/313275/-not-enough-... Excel 2003 had a heap limit of about 1GB. The other thing to keep in mind is that Office documents are, in addition to being somewhat bloated internally, far more than just text. Think about all of the people writing things like documentation with hundreds of screenshots (all uncompressed BMPs), audio or video, etc. — and the people with those are far more likely to be at the kind of large corporations which expect value from their support contracts. There were multiple ways to deal with that problem but in general the easiest was switching to a 64-bit address space.
- dtech 9y agoAnother reason could be that it has dependencies that link to specific addresses in the exe. It's very peculiar that they made the effort to keep all the original adresses.
- breakingcups 9y agoThat's a really good point.
- bearbearbear 9y agoThe most likely reason is there's a heavy handed government agency that relies on all the base addresses to be the same, who buys lots of Microsoft licenses.
- ggg9990 9y agoYes, the NSA is surveilling the populace 24/7 through Microsoft Equation Editor.
- ajnin 9y agoIt's keeping the adresses that requires the least effort, changing them would have implied to also change all calls and jumps in the rest of the code, which could mean a very large number of addresses to change.
- nostoc 9y agoIt's not an effort, it's probably a side effect of simply patching the binary. If you can't rebuild it, you have to manually edit it, and when you do that you can't really change the addresses, not without a lot of headache.
- ksk 9y agoOne other reason might be that they licensed part of the code from a third party and are no longer allowed to re-distribute it. I suppose patching out a few bytes might get them out of legal jail.
- porfirium 9y agoSo Microsoft lost the source code? Or maybe the engineer couldn't be bothered to set up the old toolchain used to build this executable?
- ceautery 9y agoManual patching is more of a bother, I imagine, so this wouldn't be due to a smug engineer getting his prima donna on.
- moonbug22 9y agoProbably bought it in from a third party. Why'd you think Pinball went away?
- tjalfi 9y agoRaymond Chen answered this question five years ago[0]. [0] https://blogs.msdn.microsoft.com/oldnewthing/20121218-00/?p=5803 https://blogs.msdn.microsoft.com/oldnewthing/20121218-00/?p=...
- dtech 9y agoThat is both pretty impressive and horrific. I wonder if they patched this way because they wanted to maintain as much binary compatibility as possible, or if they don't have the original source/couldn't reproduce the build process.
- frik 9y agoThey probably don't have the Office 97 or 2000 build pipeline around anymore. And back then for Office XP or 2003 copied the equation editor in binary form to the new repository.
- gizmo 9y agoHorrific? This is what you do when you want to make sure you don't introduce any unintentional changes. Computers aren't magic, and there is nothing wrong about patching a binary. Compiling the software with a modern compiler or linking to a modern runtime is very likely to bring obscure bugs in the codebase to the surface. It's pretty hard to replicate the entire build process that produced the original binary, even if they have the source code and everything else on hand.
- andrewchambers 9y agoIts funny how very few people do fully self contained and reproducible builds. At least nixos tries hard.
- jononor 9y agoYour QA process, including automates tests should ensure there were no unacceptable changes introduced. Otherwise you ability to create and ship fixes in timely manner will be severely harmed by the fear of breaking things.
- bryanrasmussen 9y agohow many decades of software is your QA process, with its automated tests, covering?
- dzdt 9y agoI once worked at a place which lost part of the source code for their giant mission-defining application. They spent a decade linking in object code for which there was no corresponding source code. The build team was very proud when they announced that the application would finally start being built from the source code in version control. Stuff happens!
- bearbearbear 9y ago> They spent a decade linking in object code for which there was no corresponding source code. How would you go an entire decade without noticing this? Wouldn't you have to use that missing source code for something within ten years?
- dzdt 9y agoI only know details at the level of war story, secondhand. I may have overstated a bit. For sure there was a build process relinking in old object code for many years which no one knew how to reproduce. Possibly there was still associated source code, but the object bits had been declared "golden" and no one knew exactly what source version or build process had produced those "golden" bits.
- leeter 9y agoI've had something similar before at a prior employer caused by bad linking of some C# to some C++. Someone thought it was a good idea to P/Invoke directly the mangled names. Needless to say that changed once I was finally able to get my hands on the source.
- gvb 9y agoLikely the source was used to build an object library which then got linked in to form the executable. If the library Just Worked, there would be no reason to rebuild it.
- pjc50 9y agoOh, undoubtedly it was noticed, but an enterprise software company has a tremendous capacity to procrastinate on fixing things.
- dawnbreez 9y agoWhile this does suggest that they lost the source code for this program, it also shows an unbelievable amount of skill.
- porfirium 9y agoHN, where writing assembly shows an unbelievable amount of skill.
- pmelendez 9y agoIt is indeed a lost art. I can count with just one hand the amount of colleagues that I know that are capable of doing this. Also this is not assembly, it is object code.
- icebraining 9y agoAlso this is not assembly, it is object code. Disassemblers exist. You can take the binary, generate the assembly code, fix it and then re-compile to find the needed changes. I cracked a few sharewares with OllyDbg this way (just for fun, never distributed), and I'm no "leet coder".
- pmelendez 9y agoWould the assembler maintain the same binary size and the exactly the same address module in the same order just like the article claims? What they said is they found evidence that the binary was modified manually. This is way more tedious that disassembling and reassembling a binary.
- icebraining 9y agoA tool designed for reverse engineering like OllyDbg will maintain everything, yes.
- porfirium 9y ago>This is way more tedious that dissembling and reassembling a binary. That's not the case.
- abainbridge 9y agoI wonder how the checked in the fix to the source control system?
- Freak_NL 9y agoProbably: git rm -r . git add EQNEDT32.EXE git commit -m "Fixed CVE-2017-11882" git push (Provided someone automatically updated the code repository to git or some other modern tool in the past 17 years.)
- misterdata 9y ago'FCIB', apparently: https://blogs.msdn.microsoft.com/oldnewthing/20171114-00/?p=97396 https://blogs.msdn.microsoft.com/oldnewthing/20171114-00/?p=...
- Freak_NL 9y ago> F-C-I-B or as a sort-of acronym eff-sib […] stands for "foreign checked-in binary" […] The term FCIB didn't originally mean "foreign checked-in binary". According to legend […] "Not another f—ing checked-in binary!"
- emidln 9y agoI've done this in the past by checking in both a binary as well as a diff to the previous version. It's sometimes helpful to have both if your SCM doesn't handle binary diffs well.
- userbinator 9y agoNotice the xchg, stosb and a loop instruction. This was definitely written by a skilled Asm programmer --- I've never seen even a compiler at -Os generate code like that. This also compels me to "code-golf" the function even more: push edi mov edi, [esp+8] mov ecx, [esp+12] jecxz label2 label1: push ecx call sub_416352 stosb pop ecx test al, al loopnz label1 jecxz label2 dec edi salc stosb label2: pop edi ret Original: 58 bytes; patched: 44; mine: 30. I've done plenty of patching like this, and indeed the relative "sparseness" of compiler output very often allows the more functional version to be smaller than the original. It's amazing how many instructions the original wastes --- notice how none of ebx, esi, or edi are used, yet they get needlessly pushed and popped; and despite saving those registers so they could be used locally, the compiler perplexingly decided to keep all the local variables on the stack instead. The "jump around a jump", with both of them being the "long" form (for destinations greater than 128 bytes away, not the case here) is equally horrible. This may actually be a case where today's compilers will generate smaller code for the same source. Note that in 32-bit code, memcpy is typically implemented by first copying blocks of 4 bytes using the movsd (move double word) instruction, while any remaining bytes are then copied using movsb (move byte). This is efficient in terms of performance, but whoever was patching this noticed that some space can be freed by only using movsb, and perhaps sacrificing a nanosecond or two. On older processors this was true, but since Ivy Bridge a REP MOVSB will essentially be as fast but smaller. Look up "enhanced REP MOVSB" for more information.
- azag0 9y agoHow does this go with the often quoted mantra that you can only beat compilers today if you're an extremely skilled asm programmer? Or is the problem you describe just about executable size rather than speed?
- bitexploder 9y agoThat mantra applies to "most" programmers. I think he was talking mostly about size. Odds are good most programmers tinkering in machine code won't beat the performance of the compiler. That takes experience. It is a good rule of thumb. I think it is easier to write smaller (size) code than a compiler, but when you measure performance it will beat you often until you get good. Alignment, x86 tricks... It takes a bit of knowledge to do well.
- yoz-y 9y agoThe article mentions that the timestamp of compilation gets embedded into the binary. When does this happen? I am used to having identical binaries when recompiling the same source code with same flags (and compiler and so on and so on)
- anon1253 9y agoThey probably just lost the ability to build it, or the source code can't be found. Happens quite often. 17 years is a /long/ time to maintain build systems and remember where you put the files.
- nathan_f77 9y agoI'm glad that most of the software development community seems to have settled on git. I get the feeling that I'll still have all of the source code for my projects in 20 years. Redundant backups are especially important for software companies. It's scary to think how many startups give all cofounders and developers admin access to everything. It helps that git is distributed, but it's not hard to imagine a scenario where a ticked off former employee wipes everyone's laptops and deletes the hosted source code. Even if you don't update the mirrors regularly, it's good to know that you have some copies of data in BitBucket/GitLab/Heroku/Google Drive.
- Merad 9y agoI don't know if I would hold your breath. 10 years ago I think most people hadn't even heard of git (it was ~2 years old) and Google Code was the hot new thing, and GitHub was a year or so away from creation. At the time most people seemed to be pretty content Subversion and hosting on Sourceforge (before it turned evil) or Google Code, but in the next ~5 years everything changed. Granted git, GitHub, etc. have far more momentum that anything that came before, but this is a field where it feels like the only constant is change.
- dmitriid 9y agoOne reason for doing it this way is possibly this: > Well, have you ever met a C/C++ compiler that would put all functions in a 500+ KB executable on exactly the same address in the module after rebuilding a modified source code, especially when these modifications changed the amount of code in several functions? It's quite possible they are still contractually obligated to maintain some pretty old systems where changes to the .exe would produce unexpected behaviour. I had Access apps/databases crash on a system if they were built by a different version of Access.
- magnat 9y agoSlightly off-topic: what program is used to produce disassembly graphs as those in article?
- kristofferR 9y agohttps://www.hex-rays.com/products/ida/ https://www.hex-rays.com/products/ida/ IDA is widely regarded as the best disassembler and debugger out there. It comes with a price to match too though.
- erikbye 9y agoIf anyone wants to give it a go they can use v5.0, which is free for non-commercial use. Otherwise: https://reverseengineering.stackexchange.com/questions/1817/is-there-any-disassembler-to-rival-ida-pro https://reverseengineering.stackexchange.com/questions/1817/...
- pjc50 9y agoIt is something of a rite of passage in the piracy community to crack your own copy of IDA Pro. It's also a rite of passage to distribute cracked and boobytrapped copies on filesharing sites...
- londons_explore 9y agoOh, I remember the old "this will only work if your timezone is set to Moscow" version...
- Havoc 9y agoThat plus softice.
- sandos 9y agox64dbg can also produce nice graphs and is open-source!
- nostoc 9y agoradare2 is another open source alternative, but it comes with quite a learning curve. http://rada.re/r/ http://rada.re/r/
- be5invis 9y agoYou have to know that the MSFT may not have the source code of Equation Editor, since it is a simplified version of MathType.
- foobarbecue 9y agoI suppose the fact that they have patched the binary means they can never again patch the source?
- artursapek 9y agoThey'd have to re-implement the patch in source before doing anything else to it. I wonder if they are no longer able to build from source anymore... why else would they resort to this?
- foobarbecue 9y agoAs explained in the article and in other comments, it's possible that there are dependencies that rely on address continuity of contents or file size continuity.
- tzahola 9y agoThere are plenty of companies hooking into private APIs within Word and Excel with their “productivity tools”. Probably an important MSFT customer was using one of these tools as a crucial part of their operations, so they convinced them not to break it. Just like how Google had to put special cases in Android to keep compatibility with some hacks Facebook was using in their app.
- dingo_bat 9y agoI salute and respect the guy who did this while hoping I never have to do anything like this.
- wruza 9y agoI was dreaming I’ll have to do something like that until it faded below the weight of modern <script src> programming. It is like dancing twist, rock and hardbass in the era of electronic arse shaking.
- alkonaut 9y agoIf the thing is 17 years old an a replacement has existed since forever, what purpose does this file have today (Assuming I'm on a modern windows, I run either no ms office or a modern office version).
- whatthesmack 9y agoFrom the article: > While Office has had a new Equation Editor integrated since at least version 2007, Microsoft can't simply remove EQNEDT32.EXE (the old Equation Editor) from Office as there are probably tons of old documents out there containing equations in this old format, which would then become un-editable.
- alkonaut 9y agoAh. missed that. But obviously I'd be very happy for this program to be patched by replacing it with this program: MessageBox.Show("This document contains an old equation and you don't have the editor. Do you want to download the old editor?"); Becuase there comes a point in time when any time you bump into an equation like this, it's actually more likely to be a malicious one. Even better if they could at least render the old equation statically using the new office, but not edit it. Then it would be almost insanely rare that anyone needs the old editor.
- twoodfin 9y agoThis is the kind of thing that can rapidly escalate to a CTO asking his Microsoft sales VP why he's spending $18M/year on upgrade and support contracts when a report that's worked "forever" can start talking back like Clippy. Microsoft doesn't preserve backward compatibility because they're stubborn; it's a key part of their value proposition to some of their biggest clients.
- alkonaut 9y agoThis is the thing: I'm also a paying customer, I just don't pay as much. But I'd like to pay for more security/less compatibility, instead of the other way around. This should also be very easy to do e.g. by noticing whether you are in a setting where there is any risk of the scenario you say. If it's a home machine for example, then don't worry about compatibility, focus on security.
- rogerhoward 9y agoI'm surprised no one has noted the copyright is to Design Science - this is a small company in my hometown who are still around. I've spoken with their CEO a few times and I wouldn't be at all surprised if the source code was lost, or somehow at least wasn't being made available to Microsoft (I doubt it ever was). It's a really old school shop who seems to have largely been coasting on the licensing of this one component for the past couple decades and I wouldn't at all be shocked to find they no longer are capable of maintaining it themselves.
- rob74 9y agoI noted it - thanks for the background info on the company! I also assume that either they are not able to maintain the software themselves, or they have lost the source code, but it might also be that setting up the toolchain to compile such an old piece of software is more effort than just patching the binary.
- sjburt 9y agoThis is such an underappreciated aspect of code stewardship. There are powerful tools for source control and archiving. But ensuring that state of code could actually be built at an arbitrary date in the future is so much less assured.
- londons_explore 9y agoI agree here. I would guess the build environment involves lots of dependencies, lots of special config, lots of stuff which has to be the exact correct version, and all that knowledge has been lost as people have left the team and it wasn't properly documented. Sure, you could spend a couple of weeks setting up a suitable environment again and relearning everything from scratch, but binary patching is probably easier.
- extra88 9y agoDesign Science still develops and sells MathType, the "pro" version of the Equation Editor licensed to Microsoft. They also make other software meant to make math more accessible to people with various disabilities. https://www.dessci.com/en/ https://www.dessci.com/en/
- _pmf_ 9y agoAh, this brings up a lot of font memories of me in high school preparing presentations using this fine piece of software[0] before replacing it with a 1GB open source equation editor called LaTeX. [0] It was actually quite usable once you got to know its warts.
- infinity0 9y agoBinary hacking FTW. The semi-official Debian server, alioth.debian.org, where a lot of random developer stuff is hosted, is stuck on Debian wheezy for various reasons. Most users, including myself (a Debian Developer) don't have root access to upgrade the server nor install new software. The version of libapt-inst is too old to support Debian packages with control.tar.xz members (only control.tar.gz members). So we can't upload newer Debian packages to various custom APT repos that we host on that server. I worked around this by looking at the libapt-inst source code, figuring out how to make it support control.tar.xz instead of control.tar.gz, and binary-patched libapt-inst.so to have this effect instead. It's actually fairly simple 1. there is a check for control.tar.gz, the failure branch prints an error and then returns. I overwrite this with NOP so it goes into the "success" branch. 2. then later it extracts the control.tar.gz member and pipes it through gzip. Luckily, nowhere else in the program uses the exact string "control.tar.gz" or "gzip" so I simply patch that string "control.tar.gz" -> "control.tar.xz" in the binary and also change "gzip" -> "xz\0\0". (Actually given the change in (2), (1) is not necessary. But without it you get a bunch of spurious error messages.) Applying this patch makes the resulting .so lose the ability of working with old control.tar.gz members (which is still needed of course). So my workaround does this: LD_PRELOAD=libapt-inst.so.patched apt-ftparchive [..] && apt-ftparchive [..] i.e. runs it once with the hack to pick up the new-style debs, and once again without the hack to pick up the old-style debs. My motto is, "dirty solutions for dirty problems". :D :D :D
- uyoakaoma 9y agodirty solutions for dirty problems :):)
- mschuster91 9y ago> The semi-official Debian server, alioth.debian.org, where a lot of random developer stuff is hosted, is stuck on Debian wheezy for various reasons Jeez. How is security maintained? That actually scares me a bit.
- mort96 9y agoWheezy is supported until the end of May 2018, so it still gets security patches.
- deleted 9y ago[deleted]
- alexeiz 9y agoIt's an old program the source code for which may either not compile with the modern C++ compiler, or be lost. Back in 2000, Microsoft was using Visual Source Safe for managing its source code. I wouldn't be surprised if nobody can remember where the heck the VSS repository with that source code is located. That leaves the binary monkey-patching as the only reasonable solution. I'm pretty sure Raymond Chen still works at Microsoft...
- ajross 9y agoBinary patching is really only reasonable when the source code is indeed lost. If they had the code but simply needed a compiler that worked, they could have rebuilt it using the same toolchain and build environment it was built with to begin with. Old versions of Windows and MSVC are obviously still around.
- lzybkr 9y agoI have no specific insight to this patch, but I do have personal experience binary patching a popular Microsoft product. My patch was to the VC++ compiler nearly 20 years ago. We had source, and my fix was also applied to the source (which I'd imagine is still there today), but a binary patch also made sense in the short term. The binary that I patched was used to build another important Microsoft product, and this bug was found late in the product cycle where any compiler change was risky. We weren't 100% confident we had the exact sources used to build that version of the compiler (git would have been handy then), we only knew, plus or minus one day, what the sources where. After carefully evaluating the binary patch versus the risk of building from uncertain source, the binary patch was taken to reduce risk. I'm no reverse engineer, but this was a pretty interesting exercise in RE even though I had sources. I had no symbols, and the binary was optimized so that functions were not contiguous, cold paths were moved to the end of the binary. Just finding the code I needed to patch was not easy. The code review was fun - a dozen or so compiler engineers reviewed the change on paper printouts - the most thorough review I've had in my career, and the only one that used paper. To the best of my knowledge, this binary was never used to build anything other than that specific version of the product which I won't name - not that it matters really, the product is still in use, but that version is unlikely to be in use anywhere anymore.
- dielel 9y agoThanks for sharing this. I suspected that "not being sure if you have the exactly right source code" could be a real world reason to patch a binary, and now I know.
- Someone 9y agoThis ‘old’ equation editor is a limited version of MathType (https://en.wikipedia.org/wiki/MathType#Microsoft_Equation_Editor https://en.wikipedia.org/wiki/MathType#Microsoft_Equation_Ed...) that has been supplanted by a built-in equation editor. Chances are that Microsoft doesn’t have a license for bug fixes from Design Science (makers of MathType) anymore and isn’t willing to pay for this fix. Alternatively, Design Science may not be able to deliver a version that, for maximum backwards compatibility, has only this fix (to minimize risks, they would have to have kept an environment around that hosts the compiler used back then)
- jws 9y agoJust a historical note: Patching used to be much more common. Back in the Vax VMS days the image file format (executables, not pictures) had a section for patches. From the ANALYZE/IMAGE command… Patch information --- Indicates whether the image has been patched (changed without having been recompiled or reassembled and relinked). If a patch is present, the actual patch code can be displayed. (VAX and Alpha only.)
- yuhong 9y agoI noticed a 0F 1F NOP, which breaks older processors. This is in an update that goes back to Office 2007.
- lunixbochs 9y agoBinary patching is a really common requirement in attack/defense CTF, and there are a few projects floating around to help with it. Keypatch helps you do assembly overwrites in IDA Pro. Binary Ninja lets you do assembly (and C shellcode!) overwrite patches, and even has undo. I have my own project [1] for patching ELFs that relies on injecting additional segments and injecting a hook at any address, so as to not require in-place patches. It can also massage GCC/Clang output and inject that reliably into an existing binary. [1] https://github.com/lunixbochs/patchkit https://github.com/lunixbochs/patchkit I have my own story about this as well. A few years ago I released a port of Uplink: Hacker Elite for the OpenPandora handheld with a few game engine patches, and some people were running into a bug: the game would enter the "new game" screen on every launch, even if you already had a save game to load. I and couldn't find the exact source I'd used to build it and didn't want to spend time making sure I got all of my bugfixes into the vanilla repository, so... I went digging with IDA, found the topmost branch to the "new game" wizard, and patched the address to go to the main menu function instead. At that point you could still click "new game" from the menu and it wouldn't go through the patched address (so "new game" still worked), but you could also load an existing game, thus fixing the bug! I still have nothing on Notaz, who statically recompiled StarCraft and Diablo for that community :)
- sswaner 9y agoReminds me of that time Mark Watney used a similar method to patch his rover’s comms to connect to an old radio system.