Saturday, November 17, 2012

DLL injection with C++

I started looking into ways to inject a DLL to a process. Since I wanted to do it in C++ and I'm not that familiar with it, it took me a while to get it working. After googling for some evenings, I came across this example which worked. Since the example had a lot of code for error handling that was not really needed for it to work, I started to remove that code line by line...until I was left with only a few lines of code that did the trick:


public: static int injectDll(HANDLE processHandle, TCHAR* dllToInject, int sizeOfDllPath) { 
 VOID* pvProcessPath = VirtualAllocEx(processHandle, NULL, sizeOfDllPath, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
 WriteProcessMemory(processHandle, pvProcessPath, dllToInject, sizeOfDllPath, NULL);
 VOID* pvLoadLibraryAddress = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "LoadLibraryW");
 DWORD nThreadIdentifier;
 CreateRemoteThread(processHandle, NULL, NULL, (LPTHREAD_START_ROUTINE) pvLoadLibraryAddress, pvProcessPath, 0, &nThreadIdentifier);
 return 1;
} 

In the DLL, I just call the OutputDebugString() method that should be safe to call from the DllMain (the entry point in the DLL):

#include <iostream>
#include "stdafx.h"
#include "tester.h"
#include <windows.h>

#pragma unmanaged
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
 switch (fdwReason) {
 case DLL_PROCESS_ATTACH:
  OutputDebugString(L"DLL injected");
 }
 return TRUE;
};
To view the debug messages, I used a tool named DebugView (by Microsoft).

The complete code is the following:
#include "stdafx.h"
#include &ltwindows.h>
#include &lttlhelp32.h>
#include &ltWinDef.h>

class Injector {
        public: const static int PROCESS_NOT_FOUND = 1;

  public: const static HANDLE getHandle(const LPCWSTR processName) {
   PROCESSENTRY32 entry;
   entry.dwSize = sizeof(PROCESSENTRY32);
   HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

   if (Process32First(snapshot, &entry) == TRUE)
   {
    while (Process32Next(snapshot, &entry) == TRUE)
    {
     if (wcscmp(entry.szExeFile, processName) == 0) {  
      printf("Handle found for process %ls (%i) \n", processName, entry.th32ProcessID);
      return OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
     }
    }
   }
   throw PROCESS_NOT_FOUND;
  }

  public: static void closeHandle(HANDLE handle) {
   CloseHandle(handle);
  }

  public: static int injectDll(HANDLE processHandle, TCHAR* dllToInject, int sizeOfDllPath) { 
   VOID* pvProcessPath = VirtualAllocEx(processHandle, NULL, sizeOfDllPath, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
   WriteProcessMemory(processHandle, pvProcessPath, dllToInject, sizeOfDllPath, NULL);
   VOID* pvLoadLibraryAddress = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "LoadLibraryW");
   DWORD nThreadIdentifier;
   CreateRemoteThread(processHandle, NULL, NULL, (LPTHREAD_START_ROUTINE) pvLoadLibraryAddress, pvProcessPath, 0, &nThreadIdentifier);
   return 1;
  } 
};

int _tmain(int argc, _TCHAR* argv[])
{
 const LPCWSTR processName = L"vlc.exe";
 TCHAR dllPath[MAX_PATH] = L"C:\\Users\\oss\\Documents\\Visual\ Studio\ 2010\\Projects\\injector\\Debug\\tester.dll";

 try {
  HANDLE handle = Injector::getHandle(processName);
  Injector::injectDll(handle, dllPath, sizeof dllPath);
  Injector::closeHandle(handle);
  printf("Dll was injected to %ls \n", processName);
 } catch (int e) {
  if(e == Injector::PROCESS_NOT_FOUND) {
   printf("Process %ls not found \n", processName);
  } else {
   printf("Some unknown error was thrown: %i \n", e);
  }
 }
 return 0;
}

Friday, June 8, 2012

Maven jetty plugin logging

I'm using the maven jetty plugin (org.mortbay.jetty) in one of my projects and I was searching for a way to see the jetty errors. I was getting internal server errors but there was nothing in the log. It turns out, there is a command line argument that you can pass in, to set the log level:

-Dorg.eclipse.jetty.LEVEL=DEBUG