I've been trying to patch a binary to call LoadLibrary(). The program currently does not call it, but does call other kernel32 DLL functions, and I'm able to get a sense of the lower end digits of the function address (which, from my observations so far, seem to be the same across program executions).
In my attempts to answer this question on my own, I've noticed that when disassembling and debugging the binary, the base address for function calls and addresses changes at each runtime - I understand this is because the virtual address for a program is decided when it's loaded by the OS.
What I'm a bit confused by though is that the actual opcodes to call DLL functions also change to reflect this, and I can see that they're changed when I disassemble the binary - so the actual binary itself is modified before or during runtime.
How does this happen(is it performed by the loader or the binary? In either case, how are all the function calls to be updated kept track of?), and is there any way for me to account for this when patching the binary to call a DLL function? Is it possible to apply a single patch which calls the function I want across all executions?
For more info, I am hoping to eventually do this on packed binaries with no statically available IAT information.