简体   繁体   中英

C++ dll injection failed

I am on a window10 environment, coding in vistual studio x64

Here is the dll injection target code

#include<stdio.h>
#include<iostream>
#include<Windows.h>
#include<string>

using namespace std;
int main()
{
    string choose;
    int hello = 200;
    while (true) {
        cout << &hello << endl;
        cout << "[+] Value : " + to_string(hello) << endl;
        cout << "[!] new Value : ";
        cin >> choose;
        if (choose == "show")
        {
            cout << "[+] Value : " + to_string(hello) << endl;
        }
        else
        {
            hello = stoi(choose);
        }
    }
}

Here is the injector

#include <iostream>
#include <string>
#include <windows.h>
#include <tlhelp32.h>

using namespace std;

bool WINAPI InjectDynamicLibrary(DWORD processId, LPCTSTR dllPath)
{
    HANDLE hProc = NULL;
    hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
    if (hProc == NULL)
    {
        cout << "[!] Opening process failed!!\n";
        return FALSE;
    }
    LPTSTR psLibFileRemote = NULL;
    psLibFileRemote = (LPTSTR)VirtualAllocEx(hProc, NULL, lstrlen(dllPath) + 1,
        MEM_COMMIT, PAGE_READWRITE);
    if (psLibFileRemote == NULL)
    {
        printf("[-] VirtualAllocEx failed.\n");
        return FALSE;
    }
    
    if (WriteProcessMemory(hProc, psLibFileRemote, (void *)dllPath, 
        lstrlen(dllPath) + 1, NULL) == 0)
    {
        printf("[-] WriteProcessMemory Failed.\n");
        return FALSE;
    }

    PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)
        GetProcAddress(GetModuleHandle(L"Kernel32"), "LoadLibraryA");
    if (pfnStartAddr == NULL)
    {
        printf("[-] GetProcAddress Failed.\n");
        return FALSE;
    }

    HANDLE hThread = CreateRemoteThread(hProc,
        NULL,
        0,
        pfnStartAddr,
        psLibFileRemote,
        0,
        NULL);

    if (hThread == NULL)
    {
        printf("[-] CreateRemoteThread Failed.\n");
        return FALSE;
    }
    printf("[*] Inject Succesfully.\n");
    return TRUE;
}

DWORD FindProcessId(LPCSTR processName)
{
    DWORD ProcessID = 0;
    HWND hwnd = FindWindowA(0, processName);
    GetWindowThreadProcessId(hwnd, &ProcessID);
    if (ProcessID == 0)
    {
        cout << "[!] Couldn't Find window\n";
    }
    return ProcessID;
}

int main()
{
    LPCSTR injecttargetpath = "C:\\Users\\user\\source\\repos\\C++\\C test\\x64\\Debug\\C test.exe";
    LPCTSTR dllpath = L"C:\\Users\\user\\source\\repos\\hackeddll\\Debug\\hackdll.dll";
    InjectDynamicLibrary(
        FindProcessId(injecttargetpath),
        dllpath);
    system("pause");
}

And here is the Dll code

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

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    if (ul_reason_for_call)
    {
        MessageBoxA(0, "Hello", "HELLO", MB_OK);
    }
    return TRUE;
}

The inject Successfully message show up, but nothing happened.

I have tried to turn my permission level into require administrator, but it doesn't really help.

What is the problem?

You are compiling with UNICODE defined, making LPCTSR be const wchar_t* , but your injection code is not taking into account that sizeof(wchar_t)=2 bytes, it Is assuming that LPCTSR is const char* instead, where sizeof(char)=1 byte. As such, it ends up writing only 1/2 of the DLL's Unicode file path into the target process. And then the injection is calling LoadLibraryA() passing it a (partial) Unicode file path, which will fail.

You need to change the injection to multiply the result of lstrlen()+1 by sizeof(TCHAR) when allocating and filling the remote memory, and to use LoadLibraryW() when UNICODE is defined.

You also need to cleanup after yourself. If VirtualAllocEx() succeeds, you need to call VirtualFreeEx() to free the memory you allocated. If CreateRemoteThread() succeeds, you need to call WaitForSingleObject() to wait for LoadLibrary(A|W) to finish running, and then call CloseHandle() to release the thread you created.


On a side note:

You are searching for the target process by looking for an active window whose title text is the target file path, which likely does not exist. You should instead be enumerating running processes, looking at the EXE file paths that each process was created from. See Process Enumeration , Enumerating All Processes , and Taking a Snapshot and Viewing Processes on MSDN for how to get those paths.

Also, PROCESS_ALL_ACCESS is too many permissions to ask for. You don't need that many rights to perform DLL injection. All you need are: PROCESS_CREATE_THREAD , PROCESS_QUERY_INFORMATION , PROCESS_VM_OPERATION , PROCESS_VM_WRITE , and PROCESS_VM_READ - the bare minimum needed to call WriteProcessMemory() and CreateRemoteThread() . Don't ask for more rights than you really need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM