#pragma once #include <Windows.h> class InectDll { public: InectDll(void); ~InectDll(void); static BOOL InjectDll(const char *DllFullPath, LPCTSTR ProcessName); static BOOL InjectDll(const char *DllFullPath, const DWORD dwRemoteProcessId); private: static int processNameToId(LPCTSTR lpszProcessName); static int EnableDebugPriv(const char * name); };
#include "InectDll.h" #include <Windows.h> #include <stdio.h> #include <Tlhelp32.h> InectDll::InectDll(void) { } InectDll::~InectDll(void) { } int InectDll::processNameToId(LPCTSTR lpszProcessName) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) { return -1; } PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); if (!Process32First(hSnapshot, &pe)) { CloseHandle(hSnapshot); return -2; } while (Process32Next(hSnapshot, &pe)) { if (!strcmp(lpszProcessName, pe.szExeFile)) { CloseHandle(hSnapshot); return pe.th32ProcessID; } } CloseHandle(hSnapshot); return 0; } int InectDll::EnableDebugPriv(const char * name) { HANDLE hToken; TOKEN_PRIVILEGES tp; LUID luid; BOOL bRet = 0; //打开进程令牌环 bRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken); if ( !bRet) { return -1; } //获得进程本地唯一ID bRet = LookupPrivilegeValue(NULL,name,&luid); if (!bRet) { return -2; } tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; tp.Privileges[0].Luid = luid; //调整权限 bRet = AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL); if (!bRet) { return -3; } return 0; } BOOL InectDll::InjectDll(const char *DllFullPath, const DWORD dwRemoteProcessId) { if (DllFullPath == NULL) { return FALSE; } HANDLE hRemoteProcess; int nRet = EnableDebugPriv(SE_DEBUG_NAME); if ( nRet < 0) { return FALSE; } //打开远程线程 hRemoteProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE ,FALSE, dwRemoteProcessId ); if ( hRemoteProcess == INVALID_HANDLE_VALUE) return FALSE; //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名空间 char *pszLibFileRemote = (char *) VirtualAllocEx( hRemoteProcess, NULL, lstrlen(DllFullPath)+1, MEM_COMMIT, PAGE_READWRITE); //使用WriteProcessMemory函数将DLL的路径名写入到远程进程的内存空间 BOOL bRet = WriteProcessMemory(hRemoteProcess, pszLibFileRemote, (void *) DllFullPath, lstrlen(DllFullPath)+1, NULL); if (!bRet) { return FALSE; } //计算LoadLibraryA的入口地址 PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA"); //启动远程线程LoadLibraryA,通过远程线程调用创建新的线程 HANDLE hRemoteThread = INVALID_HANDLE_VALUE; if( (hRemoteThread = CreateRemoteThread( hRemoteProcess, NULL, 0, pfnStartAddr, pszLibFileRemote, 0, NULL) ) == NULL) { DWORD dwError = GetLastError(); printf("CreateRemoteThread error!\n The last error is : %d",dwError); CloseHandle(hRemoteProcess); CloseHandle(hRemoteThread); return FALSE; } CloseHandle(hRemoteProcess); CloseHandle(hRemoteThread); return TRUE; } BOOL InectDll::InjectDll( const char *DllFullPath, LPCTSTR ProcessName ) { int Processid = processNameToId(ProcessName); if (Processid < 1) { return FALSE; } return InjectDll(DllFullPath,Processid); }
main.cpp
#include <stdio.h>
#include "InectDll.h"
void main()
{
InectDll::InjectDll("D:\\Project\\testdll1\\Debug\\testdll1.dll","NOTEPAD.EXE");
getchar();
}