I know others went and said good stuff but I fancy typing.
There are two main ways of hardcoding cheats, kind of three if the system keeps the binary in RAM (DS does, any cartridge using relatively slow storage chips which is surprisingly few, the GBA mostly not but there are bits of code loaded into RAM at times, and optical media) and four if you count save games (it is a possibility you can use, though most would not).
To be a trainer under most "Scene" standards (
https://scenerules.org/ ) you would need to have a menu to select things, button combos to select and always on hardpatch does not count. If not caring about the Scene (note the capital S) then things get more lax and you can have in game button combos and hardpatches. Button combos may even be more practical than the only menu at the start approach in some aspects but hey.
This is what most of the auto patching tools employ, though theoretically they could do menus. It is also an expensive thing in terms of space required which is why you tend to only see them for a prebaked list of games or on fairly high powered systems (16 bit and older then being more impressive for this).
What stuff like the original xbox counts as with custom firmware loaded affairs I don't know, though I would lean towards "doesn't count" even if technically...
Anyway step 1 is you need to make some cheats, or indeed find the memory. This is such a basic step in all this that if you don't have it already you face a massive uphill struggle.
https://web.archive.org/web/20080309104350/http://etk.scener.org/?op=tutorial and
https://gamehacking.org/wiki/EnHacklopedia for the sake of having something.
Now comes the two approaches.
1) You remake the idea of the cheat engine in the game (probably during a period that happens every so often or you can trigger if it is one of those systems with a nice debug you can fire).
Traditionally this means you would find the vblank routine (usually not hard as it happens maybe 60 times a second) and add a little thing saying set memory value to full/minimum/whatever you want.
If the game stores the value on the stack while it operates on it then it might not work, if the game does the calculation before your set memory it might not work if the damage is high enough, and if the damage is still high enough then it might not work, this in addition to otherwise breaking a game if you need to get below a certain health value, or have the timer do something while you are artificially keeping it high, in addition to basic anti cheat.
2) You edit the game itself. This is traditionally what the game genie family of devices did (or technically they intercepted reads to the locations and replaced it with their own info), hence the relative scarcity of codes, ease of hardpatching them into games compared to gameshark/action replay/codebreaker/goldfinger/... Though a few of the game genie devices had limited RAM editing abilities, and some of the RAM based stuff had very limited ROM manipulation abilities (master codes tending to take it all up). The lives count might be in memory but somewhere along the line will be something that ultimately subtracts a life when you lose the game of beat the bus. Find this sub and flip it to an add, or find the detection you were hit at all and say all good regardless of whether there was a collision (might even dodge knockback/stun effects and all the rest for doing this) and you have yourself a cheat.
The trouble comes in that beat the bus might not be the only thing and if say a mario game is your object you have enemies, hazards (maybe, might count as enemies for some purposes), out of time, poison mushrooms, crush, cold in some cases, jumping into a pit, maybe the boss... and you then presumably want to do all of them. You still also have the game needs to get below a value and whatnot stuff from 1).
This needs to fail/get below a value (say the "have to lose to your new mentor" fight in a RPG, time at the end of a level counting it off for bonus and any number of other things that a simple infinite value would trouble) is why you often get press to refill, or maybe do this action to trigger, cheats instead of simple infinite.
3) If the binary is in memory then you can use a memory cheat (or alternating cheats) to change the game's internal logic without having to hardpatch a ROM or make a game genie. The more advanced DS cheats often do this extensively. You can tell if you really want (the location of RAM and overlays in DS games is noted in its header) and then hardpatch the game (maybe having to account for compression and encryption). I note it mainly because it is an option, though not one most will employ as it is extra steps to do not a lot.
4) Save games. They will tend to be loaded into memory, might then be possible to edit things accordingly. Might have to break the "does the hash/checksum match?" as part of it. Very rare someone looking to make a trainer will attack anything like this but a technical possibility, and sometimes editing saves can yield some interesting results or just be a thing you want to do.
Anyway so you have your RAM cheats or ROM/binary cheats (possibly binary patch in RAM)
Now you get to intercept the startup of the game, make a nice little animation/ bit of graphics if you are kicking it old school and then set values in a free space in RAM corresponding to your menu.
Where the conventional check for button press cheat will reach out and look at the buttons and IF it detects that then flips a bit or does the cheat then ELSE it will carry on as before you instead check the bit of RAM you twiddled during the intro part you added on.
What and where you intercept it more or less dealer's choice. If you do it right at the start you need to be wary of things flushing RAM for you, not to mention you more or less also have to set the system up yourself and write a fully functional program that can pass off back to the main ROM. You can do this simply enough though and not have to dig into the ROM to intercept its startup (probably a 5 minute affair if you are good enough to do this sort of thing but hey). To that end many will instead let the basic IO/setup happen, intercept it there and then do what they need to do before handing it back off. If you are really good, or maybe just the system is primed for it, you could also do an in game jump back to the menu to turn things on and off.
All this will also vary with the system you are doing it on -- newer systems that have enough memory to not need all the fun tricks with massively complicated memory buses, memory bank controllers and bank switching tending to have a bit of an easier time than the older stuff that had to use all the tricks to get that bit more storage, that chip on the cart to play some fancier music than stock/do 3d graphics, that bit more RAM, that had multiple processors all doing their own thing and all the rest of the stuff that makes coding for such systems first an exercise in memory.
Editing a ROM might vary a bit more, presumably you would add a further step to the thing rather than a simple change a sub to an add or set to instead first check the memory location you set in the trainer and then act as per your desires. This may cause timing issues as well.