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".
What they said is they found evidence that the binary was modified manually.
This is way more tedious that disassembling and reassembling a binary.
That's not the case.
Tools like IDA Pro, Binary Ninja, and Hopper make this quite easy. A good hex editor and knowing the file offsets is also fine. This is seen as magic because it is a bit of a lost art, but it turns out to be easy to learn.
Check out "crackmes" if anyone has become interested in this topic of mangling binaries by hand. They are fun and you will get results quickly on the easier challenges.
Also check out Microcorruption CTF.
It used to be stuff we did for fun.
Back in the day we might not even load the entire program into memory - I remember manually patching disk sectors on the C64 with tools that'd let me disassemble arbitrary content to see if it happened to match code.
I also spent a couple of years programming assembly directly in a "machine code monitor" - an assembler used to assemble/disassemble memory instruction by instruction rather than from a file.
This was something several members of my primary school class would do for entertainment.
The idea that this is particularly difficult just reflect that fewer developers have spent time getting familiar with assembly these days.
We still do! When I added Retroarch to my HTPC I wanted it to use the "ok" and "power" buttons on my remote instead of "enter" and "escape" which are only found on a keyboard. While I did contribute a patch to the Retroarch project, which I tested using a laptop, binary patching was much easier on the Raspberry Pi ARM binaries than figuring out the build system for LibreELEC (the binary patch drops support for enter/escape, so it's literally changing two bytes for the two keycodes).
It is a matter of hitting F4 in hiew.