Post

Building My First Shellcode Injector: My Malware Development Journey So Far.

How I built my first shellcode injector in C++ and what I've learnt so far.

Building My First Shellcode Injector: My Malware Development Journey So Far.

Why Malware Development?

For as long as I can remember cyber security has always fascinated me. Understanding how systems work and how to break them down and exploit them is just so cool to me.

I recently took a course on Metasploit and learnt about msfvenom; a tool within the Metasploit Framework that can be used to generate payloads to attack targets. After taking a course I tried using msfvenom to generate a payload that spawns the calculator on my Windows 10 machine so I entered the necessary command and generated an exe that I could then run on my Windows machine to spawn the calculator app.

When running the exe on my Windows machine, I quickly run into a problem, Windows Defender was able to detect that the exe was malicious and stopped me from running it. I had to disable it in order to run the exe successfully. This is when I had the genius idea, if I can create my own malware I wouldn’t have to worry about it being detected by Anti-virus software and EDR’s. Maybe kind of silly but that’s what has brought me here now 😃 .

In this post, I’ll walk through my journey so far—learning C++, understanding Windows internals, and building my first Shellcode Injector. If you’re starting out on a similar path, I hope my experiences can help guide you.

Learning C++ Basics

I consumed a bit of content relating to the topic and realized most people were using either C or C++ due to their ability to interact closely with system resources. Deciding to learn C++ was my personal preference, you could learn C and still be able to do what code written in C++ would do. I have also seen people write malware in Rust, Go, Python and other languages so you could use whatever language you want.

I already have experience with Python, JavaScript and C (I’m a Software Engineer 😃) so in learning C++ I focused primarily on:

  • Pointers and memory management: Which are essential for interacting with processes.
  • API Functions: How to use the Windows API to perform actions using C++.

To cap learning the basics of C++, I built a simple Processes Monitor. The tool, using the Windows API and ToolHelp API creates a snapshot of all running processes on the system and then displays them on including information such as the PID, number of threads and others. This really helped cement my knowledge of C++ and the Windows API.

Windows Internals

Understanding the internals of Windows is vital to develop effective malware. This seemed like a daunting task at first but I just needed to understand three basic things. Threads, Processes and Handles. Here’s a simplified breakdown of what I learned:

  • Processes: A process is a running instance of a program. Each process has it’s own memory space which means Process A cannot directly access the memory space of Process B without using special techniques like Process Injection.
  • Threads: A thread is an entity within a process that Windows schedules for execution or in simpler terms, a unit of execution within a process. A process must have at least one thread, without threads, a program’s process will not be able to run.
  • Handles: A handle is a pointer to a system resources like a process or thread. If malware gets a handle to a process, it can inject code into the process, suspend, modify or even terminate the process.

A good resource I used is Microsoft’s Windows Internals Part I Book though it was too much for me to grasp so I coupled it with some YouTube videos and that really helped. A solid understanding of these concepts is what helped me build my very first Shellcode Injector.

Building The Shellcode Injector

With a solid foundation, I was now ready to build my first Shellcode Injector. Shellcode Injection is a malware technique where malicious code (shellcode) is injected into the memory space of another process and then executed. This technique is widely used to execute malware stealthily as the malware is executed inside a trusted process instead of spawning a new suspicious process.

Steps

  1. Identify the process you want to inject into. Which was notepad.exe in my case, again, just my personal preference. You could inject into whatever process you like.
  2. Allocate memory inside the target process.
  3. Write shellcode to the allocated memory space in the target process.
  4. Execute the shellcode.

A pretty simple and straightforward procedure right? Knowing what exact API calls to use was a bit of a hassle for me but with some help, I figured it out.

The code below searches for a specified process and returns it’s PID. This way I don’t have to manually search for the PID, the program does that by itself.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// gets the PID of a running process
DWORD GetProcessID (const wchar_t* processName) {
	DWORD PID = 0;
    // create a snapshot of all running processes
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hSnapshot == INVALID_HANDLE_VALUE) {
		cout << "Failed to get snapshot of running processes" << endl;
		return EXIT_FAILURE;
	}
	
	PROCESSENTRY32 pe32;
	pe32.dwSize = sizeof(PROCESSENTRY32);

	if (Process32First(hSnapshot, &pe32)) {
		do {
			if (_wcsicmp(pe32.szExeFile, processName) == 0) {
				PID = pe32.th32ProcessID;
				break;
			}
		} while (Process32Next(hSnapshot, &pe32));
	}
	CloseHandle(hSnapshot);
	return PID;
}

If anything seems confusing, you could always run a quick google search to better understand the code. You can find a link to the full code on my GitHub

Key Takeaways

  • Just like with any other programming language, practice makes perfect. Memory management and pointers are hard to grasp but it is vital to get a solid grasp on them.
  • Understanding the Windows API is one of the most important things to understand. That is what is used to basically do everything from getting handles to processes, allocating memory, executing shellcode, everything.
  • Sometimes malware does not execute how you want it to or at all, using tools like Process Hacker (now System Informer) is a skill you have to pick up to debug the malware you write.

Next Steps

Now that I have successfully implemented Shellcode Injection, I plan to explore more advanced techniques like:

  • DLL Injection: Forcing processes to load a malicious DLL, which is kind of similar to Shellcode Injection.
  • Process Hollowing: Replacing the memory of a legit process with malicious code.
  • Evasion Techniques: Learning how malware avoids detection by security tools as injecting raw unaltered shellcode into a process will trigger an AV or EDR 😢.

I will continue documenting my progress and sharing insights as I dive deeper into malware development. If you’re on a similar journey, I’d love to hear about your experiences. Drop a comment or reach out, I’m always open to discussions and learning from others in the field!

In my next post, I will explore the ins and outs of DLL Injection. Thanks for reading 😃! If you found this post helpful, consider sharing it with others who might be interested.

This post is licensed under CC BY 4.0 by the author.