1. Basic DLL using Golang

#golang #maldev #malwaredevelopment #persistence

A DLL is a library that contains code and data that can be used by more than one program at the same time. For example, in Windows operating systems, the Comdlg32 DLL performs common dialog box related functions. Each program can use the functionality that is contained in this DLL to implement an Open dialog box. It helps promote code reuse and efficient memory usage.

Let's dive on how we can program and compile a dll in Golang.

DLL Template in C

In C++ a skeleton DLL template looks like this:

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>


BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		MessageBox(NULL, L"DllMain loaded", L"Success", 0);
	case DLL_PROCESS_DETACH:
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	}
	return TRUE;
}

extern "C" __declspec(dllexport) BOOL test() {
	MessageBox(NULL, L"Exported test() function loaded", L"Success", 0);

	return TRUE;
}

There are a few things happening here. In the DllMain function there is a case switch where code execution happens when the dll is attached, detached on both process and thread. We cannot recreate DllMain inGolang, but we have alternatives.

On line 22 a function named test() is exported.

Windows comes with a tool for testing dlls called rundll32.exe. To run an exported dll function the following code can be used:

rundll32.exe <DLL PATH>,<DLL Entry Point>

Although we cannot recreate a like for like dll from c using Golang let's try recreate the above functionality.

DLL Template in Golang

Golang Code:

package main

import "C" // Cgo is required to compile a dll
import "golang.org/x/sys/windows"

// This code will execute before any other function executes
func init() {
	windows.MessageBox(
		windows.HWND(0),
		windows.StringToUTF16Ptr("init loaded"),
		windows.StringToUTF16Ptr("Success"),
		0x0,
	)
}

//Exported functions should have the following comment right before the function
//export Test
func Test() {
	windows.MessageBox(
		windows.HWND(0),
		windows.StringToUTF16Ptr("Exported test() function loaded"),
		windows.StringToUTF16Ptr("Success"),
		0x0,
	)
}

// doesn't really do anything but it's needed to compile
func main() {

}

Line 3, CGO:

import "C" / cgo is required to compile a dll in go

Line 7, init():

In Go, the init function is a special function that can be defined in a package. The init function is not called explicitly; instead, it is automatically called by the Go runtime before the exported function of the program.

Line 17, Exported function:

All exported functions should be proceeded with the following comment:

//export <func name>

Line 28, main()

It's only required for the code to compile

Compiling the DLL

In order to compile the code Cgo should be installed on the PC. Here is a setup guide.

go build -buildmode=c-shared -o test.dll

Executing the dll using rundll32

Since our dll doesnt have a main function, we have to specify the function. In our code we exported the Test function so that's what we will run.

rundll32.exe .\test.dll, Test

After running the dll function Test, 2 messageboxes will show up. Firstly the one defined in the init() function and then the one from the Test() function.

We now have all the knowledge we need to generate a malicious dll.

Complete Code

package main

import "C" // Cgo is required to compile a dll
import "golang.org/x/sys/windows"

// This code will execute before any other function executes
func init() {
	windows.MessageBox(
		windows.HWND(0),
		windows.StringToUTF16Ptr("init loaded"),
		windows.StringToUTF16Ptr("Success"),
		0x0,
	)
}

//Exported functions should have the following comment right before the function
//export Test
func Test() {
	windows.MessageBox(
		windows.HWND(0),
		windows.StringToUTF16Ptr("Exported test() function loaded"),
		windows.StringToUTF16Ptr("Success"),
		0x0,
	)
}

// doesn't really do anything but it's needed to compile
func main() {

}

Last updated