So can you just bind arbitrary keys to arbitrary characters? Aren't there a limited number of codes (scan codes?) that the keyboard will send out?
For example, you can't have an ! key. That is always Shift+1 (with a US layout, that is). QMK and other firmwares will let you make an ! key, but it's implemented by pressing shift, then pressing 1. So you could never make a keyboard shortcut that is Shift+! even though you can press that on your keyboard. The OS wouldn't be able to tell the difference between than and Shift+1. As a corollary, you couldn't rebind your keyboard such that Shift+1 outputs @ instead of !.
It's really just a classic case of bad abstraction. All the keyboard hardware does is scan rows and see which columns are also active. That gives you a grid position like (1,2) for "w". It is then forced to translate that to a scancode that it sends to the computer. The computer then sees that scancode and translates it to a letter. Obviously, things would be easier to program if the keyboard just emitted characters, or the OS just read key matrix grid positions. (In the first case, your X key would always be X, no matter what. Annoying for laptop users that want to use Dvorak, of course. In the second case, things like QMK wouldn't need to exist, you could just write a normal program running on your computer to add layers, shifting, tap dances, etc.)
The end result is that everything sucks. Isn't it always?