Reverse Engineering Win32 Part 5 “DLL Injection Method 1 (In my opinion the Best)”

Hi guys,

i have to thank everyone, who wanted this topic. The Game i am reversing 😀 is vulnerable to DLL injection. I can inject code in it ^^ with this method.

DLL Injection “What is it?”

You force the other application to load your dll (DLL Attach Event of your dll will get executed). There are some methods, which make this possible. The most clean one in my opinion is this one.

How does it work?

We inject a small shellcode in the Application:

unsigned char sc[] = {
 // Push ret
 0x68, retChar[0], retChar[1], retChar[2], retChar[3],
 // Push all flags
 0x9C,
 // Push all register
 0x60,
 // Push 0x66666666 (later we convert it to the string of "C:\DLLInjectionTest.dll")
 0x68, strChar[0], strChar[1], strChar[2], strChar[3],
 // Mov eax, 0x66666666 (later we convert it to LoadLibrary adress)
 0xB8, apiChar[0], apiChar[1], apiChar[2], apiChar[3],
 // Call eax
 0xFF, 0xD0,
 // Pop all register
 0x61,
 // Pop all flags
 0x9D,
 // Ret
 0xC3
 };

The shellcode just call LoadLibraryA with the dll you want it to use ^^.

If we inject the Shellcode, which gets executed. Why not let the Shellcode does our dirty work? Why do we need a DLL todo this?

There are several reasons:

  1. You can write C Code in your DLL, so you can faster write complex code injections. An AES Decrypter in Shellcode is sick, but writing a DLL in C Code is possible and alot easier.
  2. The Game i reverse has a “security” feature. It creates it’s own Process as a ChildProcess. You can’t access the child Process remote (You can but it is hard, parent process is just for monitoring and so on). But if you load your dll in the Parent Process, it will be loaded in the child process aswell. So you got a workaround this “security” feature. (I guess they hooked LoadLibrary and every library loaded, they load in the child process too. They made the mistake ;).

How does the Code works?

We create the Process (so we have full access to it and get the ProcessID and ThreadID for free):

// Create Process SUSPENDED
 PROCESS_INFORMATION pi;
 STARTUPINFOA Startup;
 ZeroMemory(&Startup, sizeof(Startup));
 ZeroMemory(&pi, sizeof(pi));
 CreateProcessA("C:\\Windows\\notepad.exe", NULL, NULL, NULL, NULL, CREATE_SUSPENDED, NULL, NULL, &Startup, &pi);

Next we run the Thread so it can initialise all it’s dlls and so on (IMPORTANT: You don’t need todo this. If the game or whatever you want to manipulate has well security try without this!):

ResumeThread(pi.hThread);
 Sleep(1000);
 SuspendThread(pi.hThread);

Next we allocate Memory for our DLL Name (On the remote process, i love this function):

remote_dllStringPtr = VirtualAllocEx(pi.hProcess, NULL, strlen(dllPath)+1, MEM_COMMIT, PAGE_READWRITE);

After this we get the current EIP (This is possible because the process is suspended).

 printf("Get EIP\n");
 ctx.ContextFlags = CONTEXT_CONTROL;
 GetThreadContext(pi.hThread, &ctx);
 printf("EIP: %X\n", ctx.Eip);</pre>

Now we allocate memory for our shellcode and fill our allocated memory:

printf("Allocating Remote Memory For Shellcode\n");
 remote_shellcodePtr = VirtualAllocEx(pi.hProcess, NULL, shellcodeLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 printf("Shellcode Adress: %X\n", remote_shellcodePtr);

printf("Write DLL Path To Remote Process\n");
 WriteProcessMemory(pi.hProcess, remote_dllStringPtr, dllPath, strlen(dllPath)+1, NULL);

 printf("Write Shellcode To Remote Process\n");
 WriteProcessMemory(pi.hProcess, remote_shellcodePtr, shellcode, shellcodeLen, NULL);

At the end we set the EIP of the remote process to our shellcode:

printf("Set EIP\n");
 ctx.Eip = (DWORD)remote_shellcodePtr;
 ctx.ContextFlags = CONTEXT_CONTROL;
 SetThreadContext(pi.hThread, &ctx);

 printf("Run The Shellcode\n");
 ResumeThread(pi.hThread);

Code

// DLL Injection Method1.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include "stdafx.h"
#include <Windows.h>

void createShellcode(int ret, int str, unsigned char** shellcode, int* shellcodeSize)
{
 unsigned char* retChar = (unsigned char*) &ret;
 unsigned char* strChar = (unsigned char*) &str;
 int api = (int) GetProcAddress(LoadLibraryA("kernel32.dll"), "LoadLibraryA");
 unsigned char* apiChar = (unsigned char*) &api;
 unsigned char sc[] = {
 // Push ret
 0x68, retChar[0], retChar[1], retChar[2], retChar[3],
 // Push all flags
 0x9C,
 // Push all register
 0x60,
 // Push 0x66666666 (later we convert it to the string of "C:\DLLInjectionTest.dll")
 0x68, strChar[0], strChar[1], strChar[2], strChar[3],
 // Mov eax, 0x66666666 (later we convert it to LoadLibrary adress)
 0xB8, apiChar[0], apiChar[1], apiChar[2], apiChar[3],
 // Call eax
 0xFF, 0xD0,
 // Pop all register
 0x61,
 // Pop all flags
 0x9D,
 // Ret
 0xC3
 };

 *shellcodeSize = 22;
 *shellcode = (unsigned char*) malloc(22);
 memcpy(*shellcode, sc, 22);
}

int _tmain(int argc, char* argv[])
{
 // Path to the DLL, which you want to inject
 char dllPath[] = "C:\\DLLInjectionTest.dll";

 unsigned char* shellcode;
 int shellcodeLen;

 LPVOID remote_dllStringPtr;
 LPVOID remote_shellcodePtr;

 CONTEXT ctx;

 // Create Process SUSPENDED
 PROCESS_INFORMATION pi;
 STARTUPINFOA Startup;
 ZeroMemory(&Startup, sizeof(Startup));
 ZeroMemory(&pi, sizeof(pi));
 CreateProcessA("C:\\Windows\\notepad.exe", NULL, NULL, NULL, NULL, CREATE_SUSPENDED, NULL, NULL, &Startup, &pi);

 ResumeThread(pi.hThread);
 Sleep(1000);
 SuspendThread(pi.hThread);

 printf("Allocating Remote Memory For DLL Path\n");
 remote_dllStringPtr = VirtualAllocEx(pi.hProcess, NULL, strlen(dllPath)+1, MEM_COMMIT, PAGE_READWRITE);
 printf("DLL Adress: %X\n", remote_dllStringPtr);

 printf("Get EIP\n");
 ctx.ContextFlags = CONTEXT_CONTROL;
 GetThreadContext(pi.hThread, &ctx);
 printf("EIP: %X\n", ctx.Eip);

 printf("Build Shellcode\n");
 createShellcode(ctx.Eip, (int) remote_dllStringPtr, &shellcode, &shellcodeLen);

 printf ("Created Shellcode: \n");
 for(int i=0; i<shellcodeLen; i++)
 printf ("%X ", shellcode[i]);
 printf("\n");

 printf("Allocating Remote Memory For Shellcode\n");
 remote_shellcodePtr = VirtualAllocEx(pi.hProcess, NULL, shellcodeLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 printf("Shellcode Adress: %X\n", remote_shellcodePtr);

 printf("Write DLL Path To Remote Process\n");
 WriteProcessMemory(pi.hProcess, remote_dllStringPtr, dllPath, strlen(dllPath)+1, NULL);

 printf("Write Shellcode To Remote Process\n");
 WriteProcessMemory(pi.hProcess, remote_shellcodePtr, shellcode, shellcodeLen, NULL);

 printf("Set EIP\n");
 ctx.Eip = (DWORD)remote_shellcodePtr;
 ctx.ContextFlags = CONTEXT_CONTROL;
 SetThreadContext(pi.hThread, &ctx);

 printf("Run The Shellcode\n");
 ResumeThread(pi.hThread);

 printf("Wait Till Code Was Executed\n");
 Sleep(8000);

 printf("Free Remote Resources\n");
 VirtualFreeEx(pi.hProcess, remote_dllStringPtr, strlen(dllPath)+1, MEM_DECOMMIT);
 VirtualFreeEx(pi.hProcess, remote_shellcodePtr, shellcodeLen, MEM_DECOMMIT);

 return 0;
}

Download here

There are other ways todo this, but this method can be attached to a process and can create a process. It is one of the strongest DLL Injections.
Next DLL Injection Method i will show you is with SetWindowHookEx (Preventing the SetWindowHookEx should be nearly impossible without beeing on driver Level, but i don’t like it you will see why 😉 ).

Leave a Reply

Your email address will not be published. Required fields are marked *