Hey Guys,
I developed a simple DLL Injection a few days ago, afterwards noticing that I don't want to use DLL-Injection as it seem'd to unsecure to me.
As you were giving me help all the time, I decided to give it back to you. I thought that source would be a nice help, for everybody, how want's to do DLL Injection on it's own.
I don't know a good reason not using the "big"-ones supporting this (*Magic, iHook), despite the fact, that this one may be a bit more secure, as you have different hashes.
Nevertheless, It is somehow hopefully interessting to some of you, to see, how easy this actually is.
Another good thing is, you can use this to inject into every 32bit Process or Process running in 32bit "Emulation"-Mode. Keep in Mind, that true 64bit Processes won't work. That means, this code works on 64bit Operating Systems, but only if the Target-Process has an "*32" as suffix in Taskmanager.
This Code comes with a sample Library hooking ShowMessageA() using Detours. There are several other and better methods, it is just an example. The best thing to do is, to create an sample-application like this:
Code:
#include <Windows.h> while(true) {ShowMessageA(NULL, "TestMSG", "TestHeader", MB_OK);
Please keep in mind, that every .NET Language cannot generate matching DLL's! The ones you compile won't work. The DLL has to be written in C++, Delphi, C, etc.
Neither are you able to call DoString from this, as it "Creates a Remote Thread". You need to hook from thereon a Procedure in the MainThread. This is just to get Detours to work!
Ok now have fun 
Code:
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
internal static class NativeMethods /* provides all the wrappers to the WINAPI */
{
[Flags()]
public enum ProcessAccess : int
{
/// <summary>Specifies all possible access flags for the process object.</summary>
AllAccess = CreateThread | DuplicateHandle | QueryInformation | SetInformation | Terminate | VMOperation | VMRead | VMWrite | Synchronize,
/// <summary>Enables usage of the process handle in the CreateRemoteThread function to create a thread in the process.</summary>
CreateThread = 0x2,
/// <summary>Enables usage of the process handle as either the source or target process in the DuplicateHandle function to duplicate a handle.</summary>
DuplicateHandle = 0x40,
/// <summary>Enables usage of the process handle in the GetExitCodeProcess and GetPriorityClass functions to read information from the process object.</summary>
QueryInformation = 0x400,
/// <summary>Enables usage of the process handle in the SetPriorityClass function to set the priority class of the process.</summary>
SetInformation = 0x200,
/// <summary>Enables usage of the process handle in the TerminateProcess function to terminate the process.</summary>
Terminate = 0x1,
/// <summary>Enables usage of the process handle in the VirtualProtectEx and WriteProcessMemory functions to modify the virtual memory of the process.</summary>
VMOperation = 0x8,
/// <summary>Enables usage of the process handle in the ReadProcessMemory function to' read from the virtual memory of the process.</summary>
VMRead = 0x10,
/// <summary>Enables usage of the process handle in the WriteProcessMemory function to write to the virtual memory of the process.</summary>
VMWrite = 0x20,
/// <summary>Enables usage of the process handle in any of the wait functions to wait for the process to terminate.</summary>
Synchronize = 0x100000
}
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
internal static extern IntPtr LoadLibraryA(string lpFileName);
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
internal static extern UIntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll")]
internal static extern IntPtr OpenProcess(ProcessAccess dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
internal static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,
uint dwSize, UInt32 flAllocationType, UInt32 flProtect);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
internal static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, UIntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out IntPtr lpThreadId);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);
}
public Boolean InjectDLL(String DLL, Process Proc)
{
UIntPtr bWritten;
IntPtr hThread;
byte[] DLLName = new ASCIIEncoding().GetBytes(DLL); // Bear in Mind that this does not check the Existance of the DLL
IntPtr hKernel = NativeMethods.LoadLibraryA("kernel32.dll"); // Get the Handle of the kernel32.dll
UIntPtr LoadLib = NativeMethods.GetProcAddress(hKernel, "LoadLibraryA"); // The the Adress of the LoadLibraryA function. The function which will Load our DLL into the Memory
NativeMethods.FreeLibrary(hKernel); // Release the Handle, as it is not needed anymore
if (LoadLib == UIntPtr.Zero) // Error. Maybe Misspelling of LoadLibraryA or broken System? :D
return false;
IntPtr ProcHandle = NativeMethods.OpenProcess(NativeMethods.ProcessAccess.AllAccess, false, Proc.Id); // Open the Process.
if (ProcHandle == IntPtr.Zero) // Couldn't Open Process. GetLastError() would be usefull
return false;
IntPtr cave = NativeMethods.VirtualAllocEx(ProcHandle, (IntPtr)0, (uint)DLLName.Length, 0x1000 | 0x2000, 0x04); // MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE. THIS Allocates Memory for the PATH of our Library as LoadLibraryA has one argument. We don't need the EXECUTE FLAG as it is just a text String.
if (cave == IntPtr.Zero) // System/Process run out of memory? :/
return false;
Boolean WPM = NativeMethods.WriteProcessMemory(ProcHandle, cave, DLLName, (uint)DLLName.Length, out bWritten); // Write the DLLName
if (WPM == false) // GetLastError().
return false;
IntPtr hThr = NativeMethods.CreateRemoteThread(ProcHandle, (IntPtr)0, (uint)0, LoadLib, cave, (uint)0, out hThread); // We start a NEW Thread with "main()" LoadLibraryA and it's argument located in the cave.
if (hThr == IntPtr.Zero) // maybe security?
return false;
/* Here you could use WaitForSingleObjectEx() to wait for the DLL to Loadup and then clean up, if you care ;)
VirtualFreeEx(Proc, cave, strlen(DLL), MEM_RELEASE);
CloseHandle(Proc);
*/
return true;
}
Bear in Mind that this does not check the Existance of the DLL. Also the FULL Path is required
Your DLL could look like this:
Code:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <Windows.h>
#include "detours.h"
#pragma once
#pragma comment(lib, "detours.lib")
static void NuThread();
int (WINAPI *pMessageBox)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) = MessageBoxA; // Get Pointer to Original Function
int WINAPI MyMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); // Own Detour.
bool APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NuThread, 0, 0, NULL); //Create a Thread doing this, letting LoadLib finish.
break;
case DLL_THREAD_ATTACH:
MessageBoxA(NULL, "DLL_THREAD_ATTACH", "", MB_OK);
break;
case DLL_THREAD_DETACH:
MessageBoxA(NULL, "DLL_THREAD_DETACH", "", MB_OK);
break;
case DLL_PROCESS_DETACH:
MessageBoxA(NULL, "DLL_PROCESS_DETACH", "", MB_OK);
break;
}
DisableThreadLibraryCalls(hModule);
return true;
}
int __stdcall WINAPI MyMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
/* Way One:
Bear here in mind that MessageBoxA == MyMessageBox!!! or else you will run into a deadlock */
if (lpCaption != "Hooked your bitch") // If not already modified
return MessageBoxA(hWnd, lpText, "Hooked your bitch", uType); // Call self again but modified
else
return pMessageBox(hWnd, lpText, lpCaption, uType); // modified, Call original Method.
/* Way Two (a bit more proper) */
return pMessageBox(hWnd, lpText, "Hooked your bitch", uType); // Call original but modified
}
static void NuThread()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pMessageBox, MyMessageBox);
if (DetourTransactionCommit() == NO_ERROR)
{
MessageBoxA(NULL, "MessageBox() detoured sucessfully", "Hooking", MB_OK);
}
}
****, as I'm posting this I'm wanting to Inject a DLL, Hook up Module32Next and Draw some funny nice stuff using EndScene.
I am about to use another Method, but it is more complicated and will NOT let me simply include directx 
If you have any questions, post in this thread (My Inbox has reached it's total of 5 Messages).
Also I would love any hints, that DLL Injection is safe 
Edit: Code is Lincensed under the Creative Commons: CC-BY-NC-SA