Page cover

Process and Thread APIs

Introduction

Now, although many of these APIs are used for malware development (and we will, of course, be using them for that purpose), we won't address that here. Instead, we will be focusing on what these functions do, how they work, and in the exploitation section, we will discuss how to utilize them to exploit Windows.

Prerequisites

To understand APIs for Processes and Threads, we must first know what they are. When you start an application, such as Notepad.exe, that is a process. Anything that involves executing a program can be considered a process. Every process provides the resources necessary to execute a program. For example, your memory-hungry browser creates many processes (called child processes) that each have their own virtual address, code, open handles, PID, and many more attributes.

As you can see, my browser creates many instances, one for every tab I have opened, and more instances are created (although not every browser child process is created from a new tab).

There are also multiple kinds of processes; there are application processes (such as EXEs), which you can start and end with ease:

Example of an Application process

You can also see from this output that the CMD mentions the process's PID, which is a unique identifier for programs and can be very useful for injecting malware techniques...

There are background (or daemon) processes that do exactly as they're named and have multiple uses, whether it be for Anti-viruses, creating backups, or keeping things up to date (like your CPU drivers).

Background Processes

Lastly, there are Windows processes. These are vital for Windows to even function. If you go around and start ending random tasks, you're bound to hit a Windows Process, which will likely cause the infamous blue screen of death, and nobody wants that.

Windows Processes

Next, we have Threads. Now, every process has its own (or multiple) threads; they have their own attributes, such as their own PID, exception handlers, storage, etc. Threads also share their Virtual Address Space and System Resources with a process. Windows supports preemptive multitasking, which basically means multiple threads being executed from multiple processes. In one process, you can be editing a document while the other one can be loading up a game at the same time. Any modern-day CPU allows you to do this and can enable multi-threading (a much faster way to perform tasks due to have more threads in a process).

Lastly, I want to talk about handles; these essentially allow you to interact with other Win32 functions. You want to use a process or a thread? Well, do I have news for you! A handle allows you to do this and can be thought of as a C pointer (in the simplest of terms).

Functions

Now that we have covered the basics of what a process, thread, and handle are, it's time for the fun part! We will be diving into the Win32 API and talking about all the needed functions for Malware Development. Note: There are a multitude of Processthreadsapi.h functions; if you would like to see them, they will be linked in the references!

CreateProcessA

We will first be looking at how to create a process. All this function does is open up a new program (generally notepad.exe) and give that program its needed attributes (handles, threads, etc).

Looking at the MSDN, we can already gather a ton of information. Firstly, this is a Boolean function (true or false), which can be executed either through an application name (such as C:\program.exe) or through the command line, it can have security attributes, inherit handles, create flags, a new environment, a specific directory, and most importantly, the lpStartupInfo (which specifies the handles, appearance, windows station, and many more things), as well as lpProcessInformation (information about the newly created process).

#include <Windows.h>
#include <stdio.h>
#include <tchar.h>


int main() {


	STARTUPINFO info = { sizeof(info) };
	PROCESS_INFORMATION processinfo;
	LPCSTR path = L"C:\\Windows\\system32\\notepad.exe";

	printf("[+] Creating Process! \n");
	if (CreateProcess(path, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &info, &processinfo))
	{
		printf("Waiting for Process to execute... \n");
		WaitForSingleObject(processinfo.hProcess, INFINITE);

		printf("Process Finished! Closing handles! \n");
		CloseHandle(processinfo.hProcess);
		CloseHandle(processinfo.hThread);
	}
	else
	{
		printf("CreateProcess failed (%ld). \n", GetLastError());
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}

Looking at our C program above, we can see some important information.

Firstly, nothing is defined in the global scope (we have no need here, but for other methods it can be used, but it will cause more problems). Secondly, we are defining our variables: info, processinfo, and path. After that, we will use the CreateProcess functions, supply lpApplicationName with our path, and leave everything NULL/FALSE except for the needed pointers to STARTUPINFO and PROCESS_INFORMATION.

Finally, we will then wait for the code to execute, then close all handles (which, if not, will stay persistent on the system, which is VERY BAD). And of course, some error handling, and that is all!

CreateProcess Example Function

As you can see, our code runs as expected, and we have successfully opened a process!

OpenProcess

Following the trend of processes, we have OpenProcess, which opens an existing local process object. Let's check out the MSDN for more information.

Now we can see this function has 3 parameters, a double word consisting of the desired access, a boolean to it processes inheritance, and another double word for the process's ID.

Starting with the desired access, this could mean many things; maybe you want this process to only retrieve certain information, maybe to read memory only? How about all access? Here you can find the entire list, but for our sake, we will be using PROCESS_ALL_ACCESS.

As for the inheritance, handle this just asks if any child processes from the main OpenProcess will inherit the same handle hProcess, since we don't care, we will put it as FALSE.

Lastly, we must supply a Process Identifier or PID of the process that must be opened. You can use the command tasklist | findstr [program] Or use the details tab in Task Manager.

Notepad PID through Task Manager

TerminateProcess

After discussing the creation and opening processes, it's only fair that we also address how to terminate them. TerminateProcess terminates all specified processes and all of their threads.

Looking at the MSDN, we can see that its parameters are: a handle to the process and an ExitCode.

Process Benchmark

After talking about creating, opening, and terminating processes, it's time to use our skills and see how all these functions work.

CreateRemoteThread

Now, before we start, I know what you're thinking: aren't there both CreateRemoteThread and CreateRemoteThreadEx? Well, you are 100% right, and luckily, we will be mentioning both in this section (there aren't many differences between the two).

The primary function of the two is to create a thread in the virtual address space of another process, essentially adding itself to a process.

Looking at the MSDN for this function, we can gather all the parameters we must fill in:

Firstly, we need a handle to process. In this case, we will be using OpenProcess and using a handle to that process for our remote thread.

lpThreadAttributes will be NULL (just a specific security descriptor).

dwStackSize will be 0 (this sets an initial stack size, but since we don't care, we'll use the default size).

lpStartAddress must be filled with a pointer to the LPTHREAD_START_ROUTINE.

lpParameter will be null (not needed).

dwCreationFlags will be set to 0 (no need for any flags).

lpThreadIs will be linked to the Thread Identification (TID); this is needed to even perform the function properly, or for malware development injection techniques.

Now, you may be wondering, will CreateRemoteThreadEx be much different? Well, no. The only difference is the addition of lpAttributeList, which, in our case, is also set to 0.

References

Last updated