Executable relocations, whether performed for optimization or security, will only relocate the image (executable, shared object) as a whole.
For that reason, to bypass ASLR for example, any single address within a chosen shared object is sufficient. Given, of course, you know the precise version and build of the shared object. Knowing the specific build ...
If you compare pseudocode returned by decompiler with your own C code you will notice one very important difference - in decompiler's output it is merely a comment, but it's very important. I'm talking about following lines:
int v7; // [sp+10h] [bp-42Ch]@1
char v8; // [sp+14h] [bp-428h]@1
int v9; ...
Yes, it is possible to perform the necessary loading steps in the injector process (i.e., resolving the import addresses) before injecting the DLL, and some injectors/malware do that. See for example address 0x18007CD00 in my ComRAT IDB.
However, doing it that way is more cumbersome, as some of the neccessary DLLs might not already be loaded by the target ...
ok I was wondering how one could include printf() intact but run without console
it seems if one uses WinMain() and compile with /subsystem:windows one can achieve this
here is a sample code
int pringlob = 0;
int a = 9;
int b = 10;
int c = 33;
int WINAPI WinMain(_In_ HINSTANCE,_In_opt_ HINSTANCE,_In_ LPSTR, ...
The approach you outlined seems plausible; I'd probably do something similar to that if I were approaching this problem. If printf is being called via function pointer -- say, it's an import from another .DLL -- you could simply overwrite its IAT entry with the one in your DLL. Otherwise, I'd go with hooking printf directly, and passing the arguments onto ...
As you said, the Lua engine is embedded directly into the game. It's inside plugins/GameManagerVC.dll (or GameManagerVC64.dll in case of 64-bit).
So, first step will be finding out, which version of Lua it is. So put this DLL into Ghidra or IDA Pro. The most easiest way of figuring out, what version of Lua it uses, is by searching for "Lua" string ...
Is your binary relocated on load (ASLR)? In that case 14608 points to some random memory (probably unallocated). You need to use a position-independent instruction to load the address of the dlopen stub (e.g. ADRL).
For any external functions used (e.g. libc functions), there will exist a stub in the binary's PLT for said function. When the program calls the function, it jumps to the PLT stub, which correctly handles finding the address of the function the first time it is called.
For your purposes, you can read the PLT addresses or offsets from the binary, and use that ...