This project was made during my first year of my undergraduate degree, and I’m proud to say it culminated in a research paper.

The Problem: Manual Mapping

One of the biggest challenges is “fileless” malware. Attackers can inject malicious code directly into the memory of a legitimate, running application (like a web browser). This allows their code to execute without ever touching the disk as a traditional .exe file.

One of the most common techniques for this is called manual mapping. A method in which a chunk of memory is allocated, and written with any arbritary code you want to execute. The problem is, if no suspicious functions are called (Like traditional LoadLibrary injection) and no malicious files are on disk, how can you possibly detect that a piece of memory is actually malware?

A potential solution

My approach with rx-int was to build a driver that acts real-time guard for a process’s memory, think of it like an anti-cheat. Instead of waiting for a single suspicious event, it monitors the conditions required for manual mapping to succeed.

To run, injected code usually needs memory with very specific permissions (Read, Write, and Execute). rx-int flags any memory region that is allocated with these dangerous permissions. When attached to a process, the driver first creates a baseline scan, calculating hashes of the existing memory segments. It then continuously re-scans these regions. If a hash ever changes, it signals that the memory has been modified, potentially by an attacker injecting code. This prevents the obvious case of allocating memory with only Read permissions and elevating the regions memory to RWX. Apart from this, any time a new thread is created within the process, it checks where that thread is starting from. If it’s originating from a memory region that isn’t a known, legitimate module, it’s flagged as highly suspicious. It’s a two way street, if you try hijack a thread the VAD scanner will get you, if you try evade the VAD scanner you’ll most likely make a thread that’ll get you.

The driver also maintains a CPU overhead of around 0.7% on the VM testbench I used, which gives it decent leverage as a method thats feasible without many downsides.

The paper is available here, along with the project.

Thanks :)