【问题标题】:c++ Injector runs but is not injecting DLLc++ Injector 运行但未注入 DLL
【发布时间】:2018-08-19 00:16:39
【问题描述】:

我在 Windows 10 上使用 Visual Studios 2017,我编写了一个 C++ 程序来打开一个进程的句柄。程序运行并打开进程。我在调试器中运行程序,看起来所有函数都通过了。但是我知道 DLL 没有注入,因为当我在 32 位游戏上运行此应用程序时。我可以删除我使用的 test.dll,这意味着它没有被使用。关于为什么它运行良好但没有注入的任何建议?

PS remThread 的值为 0x0000011c

// DLL Injector.cpp : Defines the entry point for the console application.

#include "stdafx.h"
int InjectDLL(DWORD, string*);
int getDLLpath(string*);
int getPID(int*);
int getProc(HANDLE*, DWORD);
void enableSeDebug();

int main()
{
    //Escalate privlege 
    enableSeDebug();

    system("title Dll Injector");
    string dllPath = "";
    int PID = -1;

    getDLLpath(&dllPath);
    getPID(&PID);


    InjectDLL(PID, &dllPath);
    system("pause");
    return 0;
}

int getDLLpath(string* dllPath)
{
    cout << "Please enter the path to your DLL file\n";
    cin >> *dllPath;
    return 1;
}

int getPID(int* PID)
{
    cout << "Please enter the PID to your target process\n";
    cin >> *PID;
    return 1;
}

int getProc(HANDLE* handleToProc, DWORD pid)
{

    //Create a handle to the process
    *handleToProc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
    if (*handleToProc != 0)
    {
        cout << "Unable to open process.\n";
        return -1;
    }
    else
    {
        cout << "process opened.\n";
        return 1;
    }
}


int InjectDLL(DWORD PID, string* dllPath)
{

    HANDLE handleToProc;
    LPVOID LoadLibAddr;
    LPVOID baseAddr;
    HANDLE remThread;

    //Get handle to process
    if (getProc(&handleToProc, PID) < 0)
        return -1;

    //Load kernel32 library
    LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");

    if (!LoadLibAddr)
        return -1;

    //Allocate memory for DLL injection
    baseAddr = VirtualAllocEx(handleToProc, NULL, dllPath->length(), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (!baseAddr)
        return -1;

    //Write dll path
    if (!WriteProcessMemory(handleToProc, baseAddr, dllPath, dllPath->length(), NULL))
        return -1;

    //Create remote thread
    remThread = CreateRemoteThread(handleToProc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, baseAddr, 0, NULL);

    if (!remThread)
        return -1;

    //Wait untill DLL exits then deallocate memmory
    WaitForSingleObject(remThread, INFINITE);

    //Freing memmory
    VirtualFreeEx(handleToProc, baseAddr, dllPath->length(), MEM_RELEASE);

    //Closing handles
    if (CloseHandle(remThread) == 0)
    {
        cout << "Failed to close handle to remote thread.\n";
        return -1;
    }

    if (CloseHandle(handleToProc) == 0)
    {
        cout << "Failed to close handle to target process.\n";
        return -1;
    }

    return 1;
}



void enableSeDebug()
{
    /////////////////////////////////////////////////////////
    //   Note: Enabling SeDebugPrivilege adapted from sample
    //     MSDN @ http://msdn.microsoft.com/en-us/library/aa446619%28VS.85%29.aspx
    // Enable SeDebugPrivilege
    HANDLE hToken = NULL;
    TOKEN_PRIVILEGES tokenPriv;
    LUID luidDebug;
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) != FALSE)
    {
        if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug) != FALSE)
        {
            tokenPriv.PrivilegeCount = 1;
            tokenPriv.Privileges[0].Luid = luidDebug;
            tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            if (AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, 0, NULL, NULL) != FALSE)
        {
                // Always successful, even in the cases which lead to OpenProcess failure
                cout << "SUCCESSFULLY CHANGED TOKEN PRIVILEGES" << endl;
            }
            else
            {
                cout << "FAILED TO CHANGE TOKEN PRIVILEGES, CODE: " << GetLastError() << endl;
            }
        }
    }
    CloseHandle(hToken);
    // Enable SeDebugPrivilege
}

上面的代码可以打开一个32位进程并且运行没有函数调用失败但是DLL没有注入?

【问题讨论】:

  • 不知道为什么 - 从GetLastError()开始
  • if (!handleToProc == 0) 测试总是正确的,因为handleToProc 是一个有效的指针。你的意思是检查*handleToProc
  • 我将条件更改为 *handleToProc != 0 并且它仍然打印“无法打开进程”。我也使用了 if(handleToProc) 和相同的结果。
  • 0xcccccccc 表示未初始化的堆栈内存:stackoverflow.com/questions/127386/…
  • 你还没有调用GetLastError

标签: c++ windows winapi window-handles


【解决方案1】:

我能够解决我的问题。检查 getProc 时我需要做

int getProc(HANDLE* handleToProc, DWORD pid)
{

  //Create a handle to the process
  *handleToProc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
  if (*handleToProc == NULL) //I changed this line to check for NULL
  {
      cout << "Unable to open process.\n";
      return -1;
  }
  else
  {
      cout << "process opened.\n";
      return 1;
  }
}

我需要更改的第二部分是我的 dllPath,它是一个需要成为 char* 的字符串。因此,当我编写 DLL 字符串时,它是一种不同的编码。使用 char* 指针修复了这个问题,现在注入器可以工作了。

【讨论】:

  • 在 Windows 中使用 char 并不能解决任何字符编码问题,除非是巧合。 char 不明确(可能是 ASCII、ANSI、UTF-8 等)。使用 wchar_t,它代表 Windows 中的 UTF-16LE 代码单元。
  • 我使用进程黑客查看了进程内存。使用字符串导致数据全部混乱。当我使用 char* 时,我可以在目标进程内存中看到 dll 路径。如果我的解释是否准确,可以争论,但字符串对我不起作用。
  • 当然,std::string 是一个 C++ 类模板。您不能将其视为只是一个字符数组。将std::string 替换为char* 不会更改字符编码。它将一种类型替换为另一种类型。我之前的评论仍然适用:不要在 Windows 中使用 std::stringchar*。使用std::wstringwchar_t*
  • 好吧,为什么不使用 char* 呢?
  • 这在我的第一条评论中有解释。它的编码本质上是模棱两可的。
【解决方案2】:

嗯,我觉得getProc中的测试应该是:

if (*handleToProc == 0)
    ...

加上其他人在 cmets 中关于测试和报告 GetLastError 的说法。

可能还有其他问题,我只是略过代码

【讨论】:

  • 所以我可以打开一个我假设的 32 位进程,因为我的应用程序是 32 位的。我在 vs 2017 上运行了调试器,一切都运行了,我得到了正常值。我在关闭句柄之前设置了一个系统(“暂停”),但我可以告诉 DLL 没有注入,因为删除 DLL 文件并不能告诉我它正在使用中。
  • 现在没有实际意义,是吗?
【解决方案3】:

在这里,您必须将其重写为更“正确”的代码。 (不是专业人士)。您在条件检查方面遇到了一些问题。一切都适合我。

#include <windows.h>
#include <iostream>
#include <tlhelp32.h>
#include <string>
using namespace std;

void getPID(DWORD&);
int  getProc(HANDLE&, DWORD);

int main()
{
    cout << "title Dll Injector" << endl;
    string dllPath = "";
    DWORD PID = NULL;
    HANDLE handleToProc = nullptr;

    getPID(PID);

    if (getProc(handleToProc, PID) < 0)
        return -1;


    //Lets check is the handle valid
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    if (hSnapshot) {
        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(PROCESSENTRY32);
        if (Process32First(hSnapshot, &pe32)) {
            do {
                if (pe32.th32ProcessID == GetProcessId(handleToProc))
                {
                    wstring name = wstring(pe32.szExeFile);
                    wcout << "Process id: " << pe32.th32ProcessID << ", Exe filename: " << name << endl;
                }
            } while (Process32Next(hSnapshot, &pe32));
        }
        CloseHandle(hSnapshot);
    }

    //Cleanup is a must!
    CloseHandle(handleToProc);
    return 0;
}

//Create a handle to process
int getProc(HANDLE& handleToProc, DWORD pid)
{
    //Create a handle to the process
    handleToProc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
    if (handleToProc == nullptr)
    {
        DWORD error = GetLastError();

        cout << "Unable to open process. Error: " << error << "\n";
        return -1;
    }
    else
    {
        cout << "process opened.\n";
        return 0;
    }
}

//Get PID from user
void getPID(DWORD& PID)
{
    cout << "Please enter the PID to your target process\n";
    cin >> PID;
}

问题在于指向句柄分配的指针,然后检查有效句​​柄。

【讨论】:

  • 这不能回答所提出的问题。此外,一个好的答案至少应该解释问题是什么,以及建议的解决方案如何解决它。由于您没有发现问题,因此您提出的代码并不能解决它。请参阅How to Answer 寻求帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-26
相关资源
最近更新 更多