# TLDR
This is my research about dynamic link libraries
## Definition
Dynamic link libraries or DLL in short term is a collections of small programs that larger program can load when needed. The smaller program called DLL file contains instruction that help the larger program handle what may be not the core function of that program.
DLL contains bits of code and data like classes or variables or other resources that the larger program need
## Two types of dll
There are static and dynamic links in DLL
- **Static links:** These are linked earlier in the process and are embedded into the executables. Static library are link to the executable when the program is compiled either at runtime or at load time. Static libraries are not shared between program because they are written into the individual executable.
- **Dynamic links:** DLLs contain the files that program links to. The libraries are stored at the computer, external to the program that the users writes. They are called dynamic because they are not embedded in the executable they are just link to it when needed.
## How to make a dll file and how to compile it
First we make a simple dll file as follow
```=
#include <stdio.h>
// Exported function
__declspec(dllexport) void hello() {
printf("Hello, World!\n");
}
```
The `__declspec(dllexport)` adds the export directive object file so you do not need to use the `.def` file so basicly this function will just print out the `hello world!` message
Create a header file `.h` file for dll
```=
#ifndef MYDLL_H
#define MYDLL_H
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void hello();
#ifdef __cplusplus
}
#endif
#endif
```
After that we compile the source code using this command i use gcc as a compiler you can use visual studio as you like
```=
gcc -shared -o mydll.dll mydll.c '-Wl,--out-implib,libmydll.a'
```
After running this code this will produce a `.dll` file and a import library file name `libmydll.a` after this you can create a simple file name `main.c`
```=
#include <stdio.h>
#include "mydll.h"
int main() {
hello();
return 0;
}
```
But we are not done yet after this we will use this command in order to compile our c code using a dll file
```=
gcc -o main.exe main.c -L. -lmydll
```
After this `main.exe` will be created run a simple command `./main.exe` and you will see a `hello world!` message.
## How to load a dll file
In order to build a `.dll` file you will have to use `__declspec(dllexport)` so that when we compile the code the dll file will be create or you can use `DllMain` as follow
```=
#include<stdio.h>
#include<windows.h>
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReversed) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
MessageBox(NULL, "Hi, I am a DLL", "DLL message", MB_OK | MB_ICONINFORMATION);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
```
The code to load the dll file after compile
```=
#include<stdio.h>
#include<windows.h>
int main() {
HMODULE hDll = LoadLibrary("loadDll.dll");
if (hDll == NULL) {
printf("Failed to load the dll file.\n");
} else {
printf("Success\n");
}
FreeLibrary(hDll);
}
```
## Dll injection
Dll injection is the process that you insert your code inside a running process
To make a dll injection we need to go through 4 steps:
- Interupt inside process
- Allocate a memory area inside process
- Copy all dll or dll path inside allocated memory
- Process execute DLL
In order to process Dll injection we have some option like CreateRemoteThread(), NtCreateThread(),... We have to allocate and copy so there will be free memory space to execute Dll there are two familiar way to do is LoadLibraryA() and jump to DllMain.
Disadvantage of LoadLibraryA() is a function inside kernel32.dll to load dll, file execute and some library. With parameter is dll which mean we will allocate a memory space, write down the path to dll and choose the starting point is the address of LoadLibraryA() but it will register the dll file to the program so it will be easy to detect and the dll will be load but not execute.
### Interrupt inside process
First take handle of process in order to work with. By doing this we will using OpenProcess(). We also need the right to execute some of the task as follow
```=
hHandle = OpenProcess( PROCESS_CREATE_THREAD |
PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION |
PROCESS_VM_WRITE |
PROCESS_VM_READ,
FALSE,
procID );
```
### Allocate memory space
Using VirtualAllocEx() take the right amount of memory space if we use LoadLibraryA() we need to allocate a memory space to write the path to Dll but if we use jump to DllMain we need to allocate a large amount of memory space to write down all Dll file.
We can use the code as follow
```=
GetFullPathName(TEXT("mydll.dll"),
BUFSIZE,
dllPath,
NULL);
dllPathAddr = VirtualAllocEx(hHandle,
0,
strlen(dllPath),
MEM_RESERVE|MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
```
First we will take the handle of Dll by using CreateFileA() and calculate the size of dll using GetFileSize() and finally using VirtualAllocEx()
```=
GetFullPathName(TEXT("mydll.dll"),
BUFSIZE,
dllPath,
NULL);
hFile = CreateFileA( dllPath,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
dllFileLength = GetFileSize( hFile,
NULL );
remoteDllAddr = VirtualAllocEx( hProcess,
NULL,
dllFileLength,
MEM_RESERVE|MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
```
### Copy Dll and identify address
When we have enough memory space, use WriteProcessMemory() to execute the write task
```=
WriteProcessMemory( hHandle,
dllPathAddr,
dllPath,
strlen(dllPath),
NULL);
```
We need to read Dll before write it down to memory space of process
```=
lpBuffer = HeapAlloc( GetProcessHeap(),
0,
dllFileLength);
ReadFile( hFile,
lpBuffer,
dllFileLength,
&dwBytesRead,
NULL );
WriteProcessMemory( hProcess,
lpRemoteLibraryBuffer,
lpBuffer,
dllFileLength,
NULL );
```
Now identify the executable starting point:
Dll path and LoadLibraryA()
We will identify the address of LoadLibraryA() and move it to executable function with parameter is the address of dll path take the address of LoadLibraryA() and we use GetModuleHandle() and GetProcAddress()
```=
loadLibAddr = GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
```
By this method, we will avoid registering the DLL with the program. However, the difficult part is obtaining the DLL entry point when it is written into the memory region. Fortunately, we already have a function to find the DLL entry point
```=
dwReflectiveLoaderOffset = GetReflectiveLoaderOffset(lpBuffer);
```
### Dll execute
Now, Dll have stayed inside memory space and we have address of that memory the last thing we need to do is let the process execute it there are several way but i prefer the tradition way by using CreateRemoteThread()
```=
rThread = CreateRemoteThread(hTargetProcHandle, NULL, 0, lpStartExecAddr, lpExecParam, 0, NULL);
WaitForSingleObject(rThread, INFINITE);
```
WaitForSingleObject to make sure that Dll have been executed before windows execute another task of process
My code to make an dll injection
```=
#include <stdio.h>
#include <windows.h>
int main(int argc, char *argv[]) {
DWORD TID = 0;
DWORD PID = 0;
LPVOID rBuffer = NULL;
HANDLE hProcess = NULL;
HANDLE hThread = NULL;
HMODULE hKernel32 = NULL;
wchar_t dllPath[MAX_PATH] = L"E:\\blue-cyber-re\\week-3\\main-injector\\dllInjector.dll";
size_t pathSize = sizeof(dllPath);
size_t bytesWritten = 0;
if (argc < 2) {
printf("Usage: %s <PID>\n", argv[0]);
return EXIT_FAILURE;
}
PID = atoi(argv[1]);
printf("[DEBUG] pid = %d", PID);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
if (hProcess == NULL) {
printf("[DEBUG] unable to get a handle to the process (%ld), error: 0x%lx\n", PID, GetLastError());
}
printf("[DEBUG] got a handle to the process\n");
printf("Getting handle to kernel32.dll\n");
hKernel32 = GetModuleHandleW(L"kernel32");
if (hKernel32 == NULL) {
printf("Failed to load kernel32, error: 0x%lx\n", GetLastError());
return EXIT_FAILURE;
}
printf("[DEBUG] got a kernel32\n");
printf("[DEBUG] Getting address of LoadLibraryW()\n");
LPTHREAD_START_ROUTINE kawLoadLibrary = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryW");
printf("[DEBUG] got address of LoadLibraryW()\n");
printf("allocating memory in target process\n");
rBuffer = VirtualAllocEx(hProcess, NULL, pathSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE);
if (rBuffer == NULL) {
printf("Can not allocate a buffer to the target process memory, error: 0x%lx\n", GetLastError());
goto CLEANUP;
}
printf("Allocated buffer\n");
printf("Writing to buffer\n");
WriteProcessMemory(hProcess, rBuffer, dllPath, pathSize, &bytesWritten);
printf("Done with WriteProcessMemory\n");
printf("Creating a thread\n");
hThread = CreateRemoteThread(hProcess, NULL, 0, kawLoadLibrary, rBuffer, 0, &TID);
if (hThread == NULL) {
printf("unable to create thread, error: 0x%lx\n", GetLastError());
goto CLEANUP;
}
printf("created a new thread\n");
printf("Waiting thread finish\n");
WaitForSingleObject(hThread, INFINITE);
printf("Thread done\n");
CLEANUP:
if (hThread) {
printf("closing handle to thread\n");
CloseHandle(hThread);
}
if (hProcess) {
printf("closing handle to process\n");
CloseHandle(hProcess);
}
printf("finished with house keeping, see you next time!\n");
return EXIT_SUCCESS;
}
```
Or you can use ExtremeInjector a tool in helping create dll injection link in [here](https://github.com/master131/ExtremeInjector/tree/master/VC)