Dll进样器不适用于x64进程

时间:2016-02-08 01:38:58

标签: c++ visual-c++ dll-injection

我有一个代码,我想在x64进程中注入一个dll文件,但是这个代码不起作用,即使是为64位平台编译这个代码。

有人可以帮我这个吗?

欢迎提出任何建议。

这是我的完整代码,正在编译完美:

#include <iostream>
#include <direct.h>
#include <windows.h>
#include <stdlib.h>
#include <strsafe.h>
#include <tlhelp32.h>
#include <TlHelp32.h>
#include <tchar.h>
#include <Psapi.h>
#include <cstring>
#include <string>
#include "injector.h"

using namespace std;
typedef TCHAR *PTCHAR;

BOOL GetPrivileges();

bool Injector::InjectDll(DWORD processId, std::string dllPath)
{
    HANDLE hThread, hProcess;
    void*  pLibRemote = 0;  

    HMODULE hKernel32 = GetModuleHandleA("Kernel32");

    char DllFullPathName[_MAX_PATH];
    GetFullPathNameA(dllPath.c_str(), _MAX_PATH, DllFullPathName, NULL);
    printf("Loading dll: %s\n", DllFullPathName);

    GetPrivileges();

    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);

    char szLibPath[_MAX_PATH];
    strcpy_s(szLibPath, DllFullPathName);

    pLibRemote = VirtualAllocEx(hProcess, NULL, sizeof(szLibPath), MEM_COMMIT, PAGE_READWRITE);

    if (pLibRemote == NULL)
    {
        printf("Couldn't allocate memory, please restart with administrator privileges\n");
        return false;
    }

    WriteProcessMemory(hProcess, pLibRemote, (void*)szLibPath, sizeof(szLibPath), NULL);

    hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryW"), pLibRemote, 0, NULL);

    if (hThread == NULL)
    {
        printf("Couldn't load DLL");
        return false;
    }

    printf("Dll successfully loaded\n");

    return true;
}

DWORD GetPidFromName(PTCHAR processName)
{
  PROCESSENTRY32 proc32entry;
  proc32entry.dwSize = sizeof(PROCESSENTRY32);

  HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

  if(Process32First(snapshot, &proc32entry) == TRUE)
  {
    while(Process32Next(snapshot, &proc32entry) == TRUE)
    {
      if(_tcsicmp(proc32entry.szExeFile, processName) == 0)
      {
        CloseHandle(snapshot);
        return proc32entry.th32ProcessID;
      }
    }
  }

  CloseHandle(snapshot);

  return NULL;
}

BOOL GetPrivileges()
{
  HANDLE tokenHandle = NULL;
  TOKEN_PRIVILEGES tokenPriv;

  if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &tokenHandle))
    return false;

  if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tokenPriv.Privileges[0].Luid))
    return false;

  LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tokenPriv.Privileges[0].Luid);
  tokenPriv.PrivilegeCount = 1;
  tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

  return AdjustTokenPrivileges(tokenHandle, 0, &tokenPriv, sizeof(tokenPriv), NULL, NULL);
}


void RunApplication(LPCWSTR lpcszProc)
{

PROCESS_INFORMATION processInfo; 
STARTUPINFO startupInfo; 
memset(&startupInfo,0, sizeof(startupInfo));
memset(&processInfo,0, sizeof(processInfo));

startupInfo.cb = sizeof startupInfo ;
startupInfo.dwFlags = STARTF_USESHOWWINDOW;
startupInfo.wShowWindow = SW_HIDE;

if (CreateProcess(lpcszProc, NULL, NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo))
{
   WaitForSingleObject(processInfo.hProcess,INFINITE);
   CloseHandle(processInfo.hThread);
   CloseHandle(processInfo.hProcess);
}
else
{
}

}

int main(int argc, char *argv[])
{

wchar_t dir[MAX_PATH] = {}; 
GetSystemDirectory(dir, MAX_PATH); 

wcscat_s(dir, L"\\");

StringCchCat(dir, MAX_PATH, L"notepad.exe"); 


    Injector inject;
    RunApplication(dir);
    Sleep(2000);
    DWORD processId = GetPidFromName(TEXT("notepad.exe"));
    inject.InjectDll(processId, "teste.dll");

system("pause");

    return EXIT_SUCCESS;
}

Injector.h

#ifndef INJECTOR_H_INCLUDED
#define INJECTOR_H_INCLUDED

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

class Injector
{
public:
    /**
    * Loads a DLL into the remote process
    * @Return true on sucess, false on failure
    */
    bool InjectDll(DWORD processId, std::string dllPath);
private:
};

#endif // INJECTOR_H_INCLUDED

DLL的

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

BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        AllocConsole();
        freopen("CONOUT$", "w", stdout);

        printf("base address: %X\n", (DWORD)GetModuleHandle(NULL));

        break;
    case DLL_PROCESS_DETACH:
        FreeConsole();
    }

    return TRUE;
}

1 个答案:

答案 0 :(得分:0)

WaitForSingleObject直到子进程退出后才返回

WaitForSingleObject(processInfo.hProcess,INFINITE);

^这导致它等待过程返回,这意味着它退出了

将dwMilliseconds参数更改为3000,等待3秒,然后继续执行,这对于大多数进程来说都可以解决问题。