Basically, a program is an instruction set, which is held in memory (it is loaded there when you open .exe file). When you do that, some memory gets allocated to that program. Let's say you have 1 KB of memory. 0-99 is reserved for OS, so when you launch the program, 100-199 gets assigned to that program. It starts execution reading memory linearly from 100, then 101, etc. Then, if you launch a malicious program, it will get 200-299 memory space. Code injection is changing the code in memory reserved for other programs.
Let's say 250-299 is the malicious code that's gonna get injected. When you launch the virus, it starts executing from 200, and it will do something like: find memory address, which is currently executed in program 1, and then "Write "GO TO 250" on the following address. Basically it accesses memory space that doesn't belong to it and changes it, forcing the program execution to run unexpectedly.
Anti virus software can easily see this behaviour: invalid memory access is a serious threat if done correctly (which usually changes execution of the program instead of crashing it).
Of course, realistically you will have much more running programs, and the memory layout is a bit more complicated, but I hope you get the idea