Results 1 to 2 of 2
  1. #1
    Dwar
    Dwar is offline
    Veteran Dwar's Avatar
    Join Date
    2010 Mar
    Posts
    2,222
    Thanks Thanks Given 
    211
    Thanks Thanks Received 
    2,230
    Thanked in
    292 Posts
    Rep Power
    10

    [C++] DLL Injection Class

    DLL Injection Class
    DLL injection class for C++. The class only uses low level win32 API calls.

    This class is written and tested in Windows XP. You need at least Windows 2000 to use this class. In order to check if the system meets the operating system requirements you might use the GetVersion/GetVersionEx function from the win32 API.

    Source file and the header file with a test project you can find in the attachment.
    injector.cpp
     /* Copyright (c) 2009, J. "abort" Dijkstra
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions are met:
    * * Redistributions of source code must retain the above copyright
    * notice, this list of conditions and the following disclaimer.
    * * Redistributions in binary form must reproduce the above copyright
    * notice, this list of conditions and the following disclaimer in the
    * documentation and/or other materials provided with the distribution.
    * * Neither the name of the <organization> nor the
    * names of its contributors may be used to endorse or promote products
    * derived from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY J. Dijkstra ''AS IS'' */

    #include "injector.h"

    // Constructor
    CInjector::CInjector(DWORD dwPid, LPWSTR pwszLibrary, bool fAdjustPrivileges = false, bool fExecuteFunctions = false) {
    if (dwPid == 0)
    throw string("No Process ID specified");

    if (!pwszLibrary)
    throw string("No library specified");

    // Open the process handle by it's Process ID
    hProcess = OpenProcess(INJECT_ACCESS, FALSE, dwPid);
    if (!hProcess)
    throw string("Failed to open process");

    // Calculate memory size for the library string, including terminating null
    int nSize = (lstrlenW(pwszLibrary)+1)*sizeof(WCHAR);
    if (nSize == sizeof(WCHAR))
    throw string("Invalid library specified");

    // Try to allocate memory for the library string
    try {
    this->pwszLibrary = new WCHAR[nSize];
    } catch (bad_alloc& e) {
    UNREFERENCED_PARAMETER(e);
    throw string("Insufficient memory to allocate library string");
    }

    // Store the library string in the current instance
    if (wcscpy_s(this->pwszLibrary, nSize, pwszLibrary))
    throw string("Failed to copy library string");

    // Adjust privileges if defined and pass on the exceptions
    if (fAdjustPrivileges)
    {
    string szError;
    if (!adjustPrivileges(szError))
    throw szError;
    }

    // If the class user wants to execute functions
    if (fExecuteFunctions)
    {
    if (GetFileAttributesW(pwszLibrary) == INVALID_FILE_ATTRIBUTES)
    throw string("Failed to retrieve Dynamic Link Library");

    hLibrary = LoadLibraryW(pwszLibrary);
    if (!hLibrary)
    throw string("Failed to load Dynamic Link Library");

    this->fExecuteFunctions = true;
    }

    dwBaseAddress = 0;
    }

    // Free up memory after destroying the instance
    CInjector::~CInjector() {
    if (hProcess)
    CloseHandle(hProcess);

    if (fExecuteFunctions && hLibrary)
    FreeLibrary(hLibrary);

    delete[] pwszLibrary;
    }

    // Find the Process ID by executable name
    DWORD CInjector::getProcessIdByName(LPWSTR pwszProcess, string& szError) {
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (!hSnap || hSnap == INVALID_HANDLE_VALUE)
    {
    szError = "Failed to create snapshot of processes";
    return 0;
    }

    PROCESSENTRY32W pe;
    pe.dwSize = sizeof(PROCESSENTRY32W);
    DWORD dwPid = 0;

    BOOL bResult = Process32FirstW(hSnap, &pe);
    while (bResult)
    {
    if (!lstrcmpW(pe.szExeFile, pwszProcess))
    {
    dwPid = pe.th32ProcessID;
    break;
    }
    bResult = Process32NextW(hSnap, &pe);
    }

    CloseHandle(hSnap);
    return dwPid;
    }

    // Adjust the privileges to enable access to processes like windows services
    bool CInjector::adjustPrivileges(string& szError) {
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;
    LUID luid;

    // Open process token to adjust the privileges
    if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
    szError = "Failed to open process token";
    return false;
    }

    // Request the current privileges
    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
    {
    szError = "Failed to lookup current privilege";
    return false;
    }

    // Change current privilege variables
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;

    // enable the privilege to access system services
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    // Apply the changed privileges to the current process token
    if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
    {
    szError = "Failed to adjust token privileges";
    return false;
    }

    return true;
    }

    // Inject the library into the open process
    bool CInjector::injectLibrary(string& szError) {
    HANDLE hThread; // Remote thread handle
    LPWSTR pwszLibString; // Parameter for remote LoadLibrary function
    LPVOID pLoadLibrary; // Pointer to remote LoadLibrary function
    HINSTANCE hKernelLib; // Instance of kernel library
    DWORD dwExitCode; // Remote thread exit code
    size_t nSize; // Size of zero terminated library path

    // Calculate length of the library string
    nSize = (lstrlenW(pwszLibrary)+1)*sizeof(WCHAR);
    if (nSize == sizeof(WCHAR))
    {
    szError = "Failed to retrieve length of library string";
    return false;
    }

    // Retrieve handle to the kernel library
    hKernelLib = GetModuleHandleW(KERNEL_LIB);
    if (!hKernelLib)
    {
    szError = "Failed to retrieve kernel32 handle";
    return false;
    }

    // Get the address of the loadlibrary function
    pLoadLibrary = (LPVOID)GetProcAddress(hKernelLib, LOADLIBRARY_FUNCTION);
    if (!pLoadLibrary)
    {
    szError = "Failed to retrieve remote load library address";
    return false;
    }

    // Allocate remote memory for the library string
    pwszLibString = (LPWSTR)VirtualAllocEx(hProcess, NULL, nSize, MEM_COMMIT, PAGE_READWRITE);
    if (!pwszLibString)
    {
    szError = "Failed to allocate remote memory";
    return false;
    }

    // Write the library string to the allocated remote memory
    if (!WriteProcessMemory(hProcess, pwszLibString, (LPVOID)pwszLibrary, nSize, NULL))
    {
    szError = "Failed to write remote process memory";
    return false;
    }

    // Start a remote loadlibrary thread with the library string as a parameter
    hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pLoadLibrary, pwszLibString, 0, NULL);
    if (!hThread)
    {
    szError = "Failed to create remote thread";
    return false;
    }

    // Wait for the remote thread to be terminated
    if (WaitForSingleObject(hThread, THREAD_WAIT) != WAIT_OBJECT_0)
    {
    szError = "Failed to wait for thread to exit";
    return false;
    }

    // Retrieve the loadlibrary exit code (which is the address of the library)
    if (!GetExitCodeThread(hThread, &dwExitCode))
    {
    szError = "Failed to retrieve thread exit code";
    return false;
    }

    // Free up the remotely allocated memory
    // No need to check for errors as it has no influence on the injection
    VirtualFreeEx(hProcess, pwszLibString, 0, MEM_RELEASE);

    if (!dwExitCode)
    {
    szError = "Failed to inject library into process";
    return false;
    }

    // Store the dll base address in the current instance
    dwBaseAddress = dwExitCode;

    return true;
    }

    // Retrieve the base address of the injected library
    DWORD CInjector::getBaseAddress() {
    return dwBaseAddress;
    }

    // Start a remote library function
    DWORD CInjector::startFunction(LPVOID pFunction, LPVOID pParameter, string& szError) {
    if (!fExecuteFunctions)
    {
    szError = "This instance has no remote function execution enabled";
    return 0;
    }

    if (!dwBaseAddress)
    {
    szError = "Can not execute function as the library is not injected yet";
    return 0;
    }

    HANDLE hThread;
    DWORD dwExitCode = 0;

    // Calculate the absolute function address of the function
    pFunction = (LPVOID)((DWORD)pFunction + (DWORD)dwBaseAddress);

    // Start the remote function
    hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunction, NULL, 0, NULL);
    if (!hThread)
    {
    szError = "Failed to create remote thread";
    return 0;
    }

    // Wait for the remote thread to exit
    if (WaitForSingleObject(hThread, THREAD_WAIT) != WAIT_OBJECT_0)
    {
    szError = "Failed to wait for remote thread";
    return 0;
    }

    // Retrieve the exit code of the remote thread
    if (!GetExitCodeThread(hThread, &dwExitCode))
    {
    szError = "Failed to retrieve thread exit code";
    return 0;
    }

    // Return thread exit code to be able to check for successful execution
    return dwExitCode;
    }

    // Retrieve the relative address of an exported function
    LPVOID CInjector::getRelativeAddress(char* pwszExportName, string& szError) {
    if (!fExecuteFunctions || !hLibrary)
    {
    szError = "This instance has no remote function execution enabled";
    return NULL;
    }

    // Retrieve the absolute address of the given function
    LPVOID pFunction = GetProcAddress(hLibrary, pwszExportName);
    if (!pFunction)
    {
    szError = "Failed to retrieve DLL Entry Function";
    return NULL;
    }

    // Calculate the relative function address of the function
    pFunction = (LPVOID)((DWORD)pFunction - (DWORD)hLibrary);

    return pFunction;
    }

    injector.h
     #ifndef INJECTOR_H_
    #define INJECTOR_H_

    #define STRICT
    #define WIN32_LEAN_AND_MEAN

    #define DEFAULTBASE_ADDRESS 268435456
    #define KERNEL_LIB L"kernel32.dll"
    #define LOADLIBRARY_FUNCTION "LoadLibraryW"
    #define INJECT_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
    #define THREAD_WAIT 5000

    #include <windows.h>

    // Required for making a snapshot of the processes
    #include <tlhelp32.h>

    // Required for errors
    #include <string>
    using namespace std;

    class CInjector {
    public:
    // Have an instance to store and maintain a handle to the process
    CInjector(DWORD dwPid, LPWSTR pwszLibrary, bool fAdjustPrivileges, bool fExecuteFunctions);

    // Free some memory
    ~CInjector();

    // Inject the given library in to the open process
    bool injectLibrary(string& szError);

    // Start a function in the injected library
    DWORD startFunction(LPVOID pFunction, LPVOID pParameter, string& szError);

    // Get relative address of a certain function
    LPVOID getRelativeAddress(char* pwszExportName, string& szError);

    // Get the process id by executable name
    static DWORD getProcessIdByName(LPWSTR pwszProcess, string& szError);

    // Get the base address of the injected library
    DWORD getBaseAddress();

    private:
    HANDLE hProcess; // Process handle
    HINSTANCE hLibrary; // The local library instance
    DWORD dwBaseAddress; // The injected library's base address
    LPWSTR pwszLibrary; // Store the path to the library
    bool fExecuteFunctions; // Enable function executing, so we can load it locally

    // Adjust privileges to gain access to e.g. winlogon.exe
    bool adjustPrivileges(string& szError);
    };

    #endif

    Please register or login to download attachments.

    Please, post your questions on forum, not by PM or mail

    I spend my time, so please pay a little bit of your time to keep world in equilibrium

  2. #2
    HGHACKER
    HGHACKER is offline
    Guest
    Join Date
    2010 Sep
    Posts
    1
    Thanks Thanks Given 
    0
    Thanks Thanks Received 
    0
    Thanked in
    0 Posts
    Rep Power
    0

    Re: [C++] DLL Injection Class

    good job ! you can teach me func read and write process with hotkey set ? i need it ! ex: write process a.exe = address: 0x12345 + offset: 0x24 ! you can help me ? thanks you very much !

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •