sRDI
sRDI copied to clipboard
SRDI_CLEARMEMORY bug or missing feature?
I am trying to use the SRDI_CLEARMEMORY flag, but I am having a couple of issues. First, if I try running the shellcode generated using the PIC code of ShellcodeRDI.c
I don't get any call to VirtualFree
and it seems that there is no visible effect on the allocated memory.
After reading the ShellcodeRDI.c
, the code responsible for the memory cleaning looks like is the following:
if (flags & SRDI_CLEARMEMORY && pVirtualFree && pLocalFree) {
if (!pVirtualFree((LPVOID)dllData, 0, 0x00008000))
{
pLocalFree((LPVOID)dllData);
}
}
However, it looks to me that pVirtualFree
and pLocalFree
are initialised but no value is assigned to them?
I tried modifying the code myself and added the following at line ~ 260 of ShellcodeRDI.c
:
BYTE sLocalFree[] = { 'L', 'o', 'c', 'a', 'l', 'F', 'r', 'e', 'e' };
BYTE sVirtualFree[] = { 'V', 'i', 'r', 't', 'u', 'a', 'l', 'F', 'r', 'e', 'e' };
FILL_STRING_WITH_BUF(aString, sLocalFree);
pLdrGetProcAddress(library, &aString, 0, (PVOID*)&pLocalFree);
FILL_STRING_WITH_BUF(aString, sVirtualFree);
pLdrGetProcAddress(library, &aString, 0, (PVOID*)&pVirtualFree);
Now, if I debug the program with something like x64dbg, I can see the invocation to VirtualFree but the following error is returned:

LocalFree
fails as well with this:

The program I used to inject the sRDI shellcode is the DotNet loader in the main repository, where the ConvertToShellcode
function is called with the 0x2
flag.
Am I doing something wrong here (except for spending my Sunday reading C code)?
Just seeing this, I'll have to dig in a take a look, it's been a while since I've looked at the memory free option
Thanks for the helpful info!
Alright, here are my thoughts based on my quick 5m walk through:
-
You're absolutely right about those function pointers not being assigned, and your code above looks like an easy fix there.
-
The error codes you are seeing are somewhat expected, and it actually brings up a larger issue I hadn't considered before:
-
For any given memory address, we can't be sure the best way to free it without more context
-
The strategy currently employed is in two phases: - First - attempt to free the memory with
VirtualFree
, which should simply fail the memory was not allocated with VirtualAlloc - Second - attempt to free the memory withLocalFree
, which for some reason I considered more unsafe at the time. I'm not sure what scenarios may cause this to fail vs crash in terms of target address. -
The mistake is in assuming that dllData could be freed directly from inside the sRDI blob. If we are assuming a normal use case, the whole block of data, bootstrap and dll combined, are all allocated together. In other words, not other is sRDI potentially trying to free a memory pointer inside it's own virtual block, but it also is not using the base address of the virtual block. Instead it's likely an offset sitting right past the bootstrap PiC.
I don't know that actually freeing the memory will ever be reasonable without creating some sort of shellcode jump to safely free the memory, but never actually try to return there.
The next best solution would be to simply zero out the DLL data in memory, but leave the block allocated. I think this achieves 80% of most people would want, but still leaves the memory region as an artifact.
Hi Nick,
Thanks a lot for taking the time to look into this. I was in fact experimenting with subtracting an offset to the dllData pointer to make it point to the start of the bootstrap code, but without much success. The workaround I was using was just applying an XOR to the first N bytes from dllData and obfuscate it (did not use zero because my lack of knowledge, visual studio was optimising the code and making it a memset).