All,
I have been trying to figure this out for a couple of days now and I need some help.
For a research project for work I have written some custom malware, the malware itself is not the issue here and I won't share any code, but I do need some help on the actual injector.
I have some problems trying to fully understand how and when I need to perform manual relocations. I am not relocating at the moment and using a random address from virtualallocex, and everything just works. My malware exe runs and I have no issues UNLESS the memory location where the remote process PE is loaded at overlaps with my malware PE preferred base address.
I am not using NtUnmapViewOfSection as it gets detected by AntiVirus and basically is just a crap function that randomly doesn't work, so my plan is to just use a random address provided by VirtualAllocEx and relocate if need be (which I don't understand, see questions hereunder).
This is my current working method (unless target process overlaps with preferredbase):
- Download malware exe and place in buffer
- CreateProcess to start victim process
- Suspend the thread right after (I'm not using CREATE_SUSPENDED flag as this does not work in win10)
- Get necessary header info from the buffer (PIMAGE_DOS_HEADER, PIMAGE_NT_HEADERS), also get the ImageBase address from remote process PEB
- Allocate memory in target process (VirtualAllocEx), using NULL for lpAddress so virtualAllocEx can choose the location
- Write PE headers and sections to the memory location
- Protect Memory
- Change EAX to new entrypoint
- Change PEB to new baseAddress
- ResumeThread
- Profit
So please help me understand the following:
Why does this work without doing any manual relocations, is there some magic PE loader in the background that does this even though I'm injecting?
Why doesn't it work when the target process overlaps with the preferred base address. The PE image itself is copied in a non-overlapping memory location, so how in the hell is that any different from my working solution when the target process doesn't overlap. It should just do the magic relocation thing from my first question.
Why do I see so many people change the preferredBaseAddress in the image before writing it to memory? To my knowledge this field is only used to map PE to their preferredbaseaddress, if they can't do that the PE loader performs the relocations. Seeing as injection code usually performs its own manual relocations I have no idea why they would change this.
Hopefully somebody can help me understand, because this is driving me nuts :).
Best regards!