I'm kind of new to this sort of thing so I hope someone can help me. I'm currently trying to understand how most malwares infect other files/modify an exe. Using Visual Studio 2017 I made an exe (with c++) that only does 2 things: print "Injection didn't work!" and after that runs "pause>NUL". I compiled it in x86 Release mode. Then I made a second exe which only prints "Injection worked". My main goal was to inject code into the first/target exe so that it runs the second exe first and then itself. So the final output after the injection should look something like this: "Injection worked. Injection didn't work!". My idea was to use OllyDBG. I opened the target exe and I added the following code into the code cave at the end of the code:
ASCII "inject.exe"
PUSH 1
PUSH 008B1F7C (Address of ASCII "inject.exe")
Call WinExec
Call __security_init_cookie (This is the assembly code at the entrypoint which I overwrote with a JMP instruction to this codecave)
JMP 008B1572 (JMP back to next instruction after entrypoint)
And the entrypoint looks like this:
JMP 008B1F87 (JMP to codecave)
This code should execute inject.exe which is the second exe I made (and this exe is located in the same folder as the target exe). When I run this in OllyDBG it works and it gives me the desired output but as soon as I save it to an exe (Copy to exectuable -> All modifications -> Copy All -> Save as InjectionTestPatched.exe) it won't run anymore and crashes before printing anything. I also checked the %errorlevel% after execution which was -1073741819 and not 0. I don't really understand why the code worked in OllyDBG but not when I save it as an exe.
Does someone know what is going on here? (Please excuse my bad English as I'm not a native english speaker)
EDIT: I think I figured out WHY it is behaving like this but I don't know how to fix it. When I debug the Patched EXE every address seems to be correct but the address to the ASCII isn't. all JMP/CALL addresses adjust accordingly to the offset but the address to the ASCII remains static (the PUSH 008B1F7C doesnt change). Could ASLR be the source of my problems? And if yes, how can I bypass this...
Here the address in red should point to the ASCII but it is the same as it was before (the addresses changed after the exe was made). What I don't understand is that the JMP address changed to the right address but the PUSH not. Why does that happen, how can I fix this? (EDIT2: Problem solved)
EDIT2: So I figured out a way to push the ASCII address on the stack correctly everytime by loading the EIP into EAX and sub it. This seems to work beacause the ASCII address is always on the stack when I reload the code. But now I have the next problem which is that WinExec doesnt seem to work anymore after reloading. OllyDBG doesn't even recoginze this instruction anymore as it shows it as 4 individual DB lines and not as CALL WinExec. How could I solve this?
EDIT3: PROBLEM SOLVED! the Call for WinExec seemed to have been changed due to ASLR even tho the address is always the same. I solved it by loading the static address to EAX and then with a CALL EAX i can call a static address which is not affected by ASLR. My Injection worked now.
call
after the string +pop
.call
, an address of the next instruction is pushed on the stack for theret
opcode. In your case it would be a string and thus bypop
-ing you could obtain the address of it.