8 ms·
Editing binaries: easier than it sounds
- codezero 13y agoThis is always an interesting subject. I enjoyed reading this similar (more practical) application of binary editing by Russ Cox to patch the Mac OS X kernel: http://research.swtch.com/macpprof http://research.swtch.com/macpprof
- chch 13y agoI used to do a something similar to this (though less sophisticated) every time a new Chrome update came out, changing a single byte in the binary so that I could restore the http:// http:// at the front of URLs. I considered making a website to publish the proper offset to change for each version, but I got complacent after a while.
- wging 13y agoHow did you figure out which byte to change?
- chch 13y agoI haven't done it in a year or two, so it took me a minute to figure out the basics again. The short version is that I crawled through the source of Chromium for a while until I found the flag that controls it [0]. Then, since FormatUrlType was a uint32, and I assumed the storage of constants would be close together, I did a little trial and error searching through the binary in Hex Fiend until I found the value for kFormatUrlOmitAll. Then I would change this value from a 7 to a 5, which would remove the kFormatUrlOmitHTTP flag (or sometimes to a 1, to see if I liked trailing slashes on bare hostnames). Of course, since Chrome autoupdates, I had to do this every few times I restarted the browser, until I just got too lazy. :) I can't seem to find the offset this time, though, so I very well might be missing a step! [0] https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_util.h&sq=package:chromium&dr=C&l=67 https://code.google.com/p/chromium/codesearch#chromium/src/n... [1] https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_util.cc&q=kFormatUrlOmitAll&sq=package:chromium&l=986&type=cs https://code.google.com/p/chromium/codesearch#chromium/src/n...
- coldpie 13y agoI'm so glad Firefox still allows this as an option. I guess it's irrational, but it drives me absolutely nuts to see bare URLs without protocols.
- tehwebguy 13y agoThis is cool, and reminds me of a disaster I once wrought upon myself: Maybe 6 years ago I used TextWrangler to find and replace against a folder. It was only a few characters being changed but there were loads of instances of them. In my PHP code it was no biggie but I accidentally overwrote parts of a Flash FLA (hundreds of instances in the binary) and made a massive piece of a project for my biggest client at the time worthless. Totally avoidable, lesson learned!
- Filligree 13y ago...revision control? Backups?
- deleted 13y ago[deleted]
- nicholassmith 13y agoI think a few of us probably have incidents like this that inspired us to use source control and/or better backup solutions.
- tehwebguy 13y agoLike I said, lesson learned.
- lunixbochs 13y agoI just used IDA for this today (I patched the Bochs bios to skip the 3-second F12 delay on boot). There's a handy "Patch program" menu under Edit. It allows you to replace bytes, assemble code, and apply your changes back to the binary.
- BorisMelnik 13y agowow, what a great idea. too bad my BIOS is basically made by north korea and isnt hackable.
- ygra 13y ago»If it had occurred to anyone to edit the binary to increment the version number, they could have pushed out a good update in a minute instead of half an hour« Or longer because now you have to patch the signature as well (as unsigned binaries probably won't be distributed by the updater).
- cperciva 13y agoThere are some binary edits which are just plain trivial: Editing data which is embedded into binaries. As an 11 year old, I was annoyed that Civilization had "Americans" but not "Canadians", so I pulled out a hex editor and corrected that omission...
- lmm 13y agoOf course that's only trivial if the strings are the same length - in my childhood I broke some programs that way.
- tjgq 13y agoAh, the memories. I had to thrice reinstall DOS on my childhood computer because of that. I later learned that editing binary files in a text editor wasn't a very bright idea...
- twic 13y ago"Mexicans!!"
- cperciva 13y agoIn the case of Civilization, the strings were padded out to a constant length.
- chinpokomon 13y agoIn my youth, I learned to recognize conditional JMP instructions by their opcodes and would bypass copy protection and nag screens all the time with CD 90, or explicit JMPs depending on how the code executed. I probably spent more time working on the crack than I ever did playing the games I'd patch, but I have no doubt that the practice is what inspired me to become a developer. It was so satisfying when I understood how a program worked at such a low level and I could get into the heads of the creators of those applications and games.
- Jugurtha 13y agoChinpokomon, if I didn't know you weren't me, I would've sworn I wrote these lines. Like a program I wasn't even interested in. Once done, wouldn't even use it. Years I was 14-15 were spent looking at disassembly listings(I used Win32DASM) getting drowned in patching versions (HexDecChar Editor), changing things. Sometimes not keeping track, wait, what did I change ? Learning to organize, even on paper. Offsets. Then writing small programs in Assembly, Pascal and C to do that. EB, 74, 75, 76, 90 etc.. Had a special meaning to me. Test calls, bogus functions and bloated DLLs getting called from a gazillion places(some of these on purpose). This has been invaluable to me. When I went to college, some courses have people struggling with debugging a program, but as you said, when you've been so close to the machine and didn't get lost, following an index is fairly easier. Also undeniably, when we had uP architecture course, I already knew that 5 years before, so it just was a refresher (bear in mind that they didn't even scratch the surface of what I was doing on my own as a kid. The most interrupt they toid with was printing (09h/21h) whilst I played with TSR and some neat things. It was also very useful with microcontroller class. PIC micros had only 35 instructions (didn't like MikroC). A lot of what I did as a kid or a bit later, turned to come in handy, always, at a later time.. So it became a sort of rule .. Whenever I'm doing something, I trust my gut instinct that some time, I'll use it. I'm yet to be proven wrong. Thanks for sharing, man.
- forgottenpaswrd 13y agoMe too. We created a group for competing breaking protections on commercial programs. It was more than patching things with NOPs(), but correcting checksums and so on. We never released the programs once without protection. It was fun. ()for people that are not into this, just replacing opcodes alone does not work as the OS checks that the executable has not been modified, and the program could do it too itself in very sophisticated ways.
- taspeotis 13y agoRaymond Chen has some interesting articles on patching and hot patching Windows. Among others: * http://blogs.msdn.com/b/oldnewthing/archive/2011/09/21/10214405.aspx http://blogs.msdn.com/b/oldnewthing/archive/2011/09/21/10214... * http://blogs.msdn.com/b/oldnewthing/archive/2013/01/02/10381672.aspx http://blogs.msdn.com/b/oldnewthing/archive/2013/01/02/10381... This one most closely matches the spirit of the article: * http://blogs.msdn.com/b/oldnewthing/archive/2012/11/13/10367904.aspx http://blogs.msdn.com/b/oldnewthing/archive/2012/11/13/10367...
- Gracana 13y agoThe Microsoft Money one is actually linked from Dan Luu's article. Interesting reads, all of them.
- callesgg 13y agoThe problem you now have two identical but not identical versions. I would not like to be part of a team that does binary edits. Unless there is no other way.
- anon4 13y agoAssuming they just compiled the old version with a bumped version number, that's exactly what they ended up with. If you compile the same source twice you get the exact same binary.
- awalton 13y ago> If you compile the same source twice you get the exact same binary. You wish this were true. You really, really wish it were. But it's not always. Reproducibility is a really tough problem when you support 25+ Linuxes, each with their own versions of GCC and libc, different compiler flags by default, etc. There's some work being done to make this "better" like GNU ld's build-id hashing binary sections so it's easier to tell if they changed, and projects that stash the compiler's flags in a binary section with -frecord-gcc-switches/-grecord-gcc-switches. But we've still got a long way to go, at least in the wonderfully fragmented landscape of Linux software development. Furthermore, the example in the article is rather specious. Versioning is very often done by macros and string replacement and not some constant somewhere in a .section that's easy to just "lemme tweak this" and push a new release. No, you'd have to go through the entire object file to find any place that version number is used. It's not the exceptional case in real world software with multiple supported releases that you see code like: if (version_number == 2 || version_number == 3) { do this thing; } else if (version_number == 4) { do that thing instead; } or its equivalent with #ifdefs, which the compiler can then fold away in preprocessing or dead code elimination leaving you with the right chunk for the product version. Hex editing the binary won't catch this, leaving you with a broken binary. tl;dr: rebuild the software if you screwed up.
- jevinskie 13y agoYeah I think it may be short sighted to shortcut a build+release process just to save a few hours. I can only imagine what might go wrong or what I might miss. Someone else mentioned code signatures which is a good point.
- anigbrowl 13y agoThis is worth it just for the link to radare: http://www.radare.org/y/?p=features http://www.radare.org/y/?p=features I don't actually program a whole lot and when I do it's usually part of a reversing effort on something obsolete or buggy or that I can't figure out how it works (not warez stuff, though). Assembler is enormous fun to dig around in if you have time on your hands and enjoy puzzle-solving. Another good free tool if you're into this sort of thing is Ollydbg. : http://www.ollydbg.de/ http://www.ollydbg.de/
- eXpl0it3r 13y agoWhile replacing some text and editing some assembly code in a small application is kind of easy and fun, changing some logic in a larger application will require a way better understanding of the code. Basically if you're unable to attach a debugger to it, you'll have a really hard time. Not to forget that changing binaries violates in many cases the EULA of the application. Sure nobody will notice or complain, but it's something to keep in mind.
- pilif 13y agoTangentially related: >But they couldn’t push the old version into the auto-updater because the client only accepts updates from higher numbered versions This is one of the reasons why I always make my auto-updating routines as dumb as possible: The only thing the client does is to tell the server its version and then let the server decide. If it believes there's an update, it sends the (signed) update. If it doesn't, it 404s. This way the server (easily modifyable) has full control and there's less chance for the client (hard to modify, needs to work for any kind of update to work) to end up in a non-updatable state.
- tfinniga 13y agoPutting as much logic as possible into the server component is definitely the way to go. I did something similar, I would send the version as well as the md5sum of the executable. Aside from being able to tell the 32 and 64-bit versions apart, the other advantage was that I'd be able to track whether they were running an executable with the md5sum I shipped, or if it had been hacked. Add that to an ip geolocation server, and now I've got a map of who is using a legal version and who is using an illegal version. I even plotted the success and spread of different cracks over time.. in our case, the Russian cracks usually lagged the Chinese cracks, but then had a better distribution network. Our auto-update function would check once a day on startup, based on the same version string and md5sum of the last check. So, we could see the person creating the hack.. same IP address, same version string, multiple md5sums, and their final md5sum would spread. I also added the demo status and a unique machine id, and that let us answer questions like "Do paying customers ever install a hacked version?", "Do people who start with the hacked version ever pay?", "Into what languages should I translate my software", "How many demo users are in our funnel", "How long does it take a demo user to convert to paid", etc.
- twowordbird 13y agoSo, do paying customers ever install a hacked version? Do people who start with the hacked version ever pay?
- 13y ago
- agumonkey 13y agoThe title reminded to investigate emacs core package bindat (bidirectional pack/unpack of binary layouts) to generate disassemblers/patchers http://www.gnu.org/s/emacs/manual/html_node/elisp/Bindat-Examples.html http://www.gnu.org/s/emacs/manual/html_node/elisp/Bindat-Exa...
- deleted 13y ago[deleted]
- mbrock 13y agoAt a previous job we had a pretty serious off-by-one error in a crypto module. This module was distributed as a binary DLL to dozens of customers. For various reasons it would have been a costly and inconvenient project to rebuild it from source and redistribute it. So I located the bug and realized it could be fixed by just increasing a constant in the binary. The best part is that the relevant bit pattern turned out to be legible in ASCII. So this serious bug could be fixed by searching for something like ".," and replacing it with ".~". I taught the devops guys to do this in Notepad++. The DLL could even be reloaded without restarting the server. Problem solved! When I left the company and wrote a little report about this, the architect patted me on the back and sighed deeply. With his customary tone of affection and good cheer, he said "mbrock, you are a horrible, horrible person."
- ColdHawaiian 13y agoI don't understand the architects response, was he being sarcastic?
- mbrock 13y agoI think he appreciated my willingness to sometimes be a horrible, horrible person for the sake of the business. :)
- negamax 13y agonop and jmp were my favorite instructions to break key auths. I miss doing that.
- arbernat 13y agoYou can do pretty radical modifications of code too if you're willing to move it somewhere else to get the room to enlarge things. It turns out that almost all x86 instructions are position independent; there's only a few that are. Then you jump from the original location to the patch, run the patch, and jump back. Gratuitous plug - that was my doctoral research (among other things, hot-patching in safety checks on a running Apache binary), and I wouldn't mind seeing it get used for a good purpose. The code's available at www.dyninst.org.