DLL注入

时间:2021-08-16 08:36:39

最近的项目涉及了软件破解方面的知识,记录一下。

将dll注入另一个进程。

// Inject.cpp : Defines the exported functions for the DLL application.
// #include "stdafx.h"
#include <TlHelp32.h>
#include <Psapi.h>
#include <tchar.h> // LoadLibrary的不同版本
#if defined _UNICODE
#define _LoadLibrary "LoadLibraryW" //_UNICODE
#else
#define _LoadLibrary "LoadLibraryA" //_MBCS
#endif // 根据进程名获取PID
DWORD GetPID(LPTSTR lpProcess)
{
HANDLE hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, ); // 获取进程快照句柄 PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
BOOL flag = Process32First(hProcSnap, &pe32); // 获取列表的第一个进程 while(flag)
{
if(!_tcsicmp(pe32.szExeFile, lpProcess))
{
CloseHandle(hProcSnap);
return pe32.th32ProcessID; //pid
}
flag=Process32Next(hProcSnap, &pe32); //获取下一个进程
} CloseHandle(hProcSnap);
return ;
} // 获取适当的Privilege
// hProcess 当前进程的handle
// Privilege 需要的Privilege
// 成功返回TRUE,失败返回FALSE
BOOL AdjustProcessPrivilege(HANDLE hProcess, TCHAR *Privilege)
{
HANDLE hToken=NULL;
OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken); //打开进程令牌环 if(NULL==hToken)
return FALSE; LUID luid;
if(!LookupPrivilegeValue(NULL, Privilege, &luid)) // 获得进程本地唯一ID
{
CloseHandle(hToken);
return FALSE;
} TOKEN_PRIVILEGES token_privileges;
token_privileges.PrivilegeCount =;
token_privileges.Privileges[].Attributes = SE_PRIVILEGE_ENABLED;
token_privileges.Privileges[].Luid = luid; //调整进程权限
if(!AdjustTokenPrivileges(hToken, FALSE, &token_privileges, NULL, NULL, NULL))
{
CloseHandle(hToken);
return FALSE;
} CloseHandle(hToken); return TRUE;
} // 在进程中查找dll
HMODULE CheckProcessModule(LPTSTR lpRemoteProcess, LPTSTR lpInjectDll)
{
DWORD nRemotePID = GetPID(lpRemoteProcess);
HANDLE hRemoteProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, nRemotePID); HMODULE hMods[];
DWORD cbNeeded = ; // Get a handle to the process.
if( EnumProcessModules(hRemoteProcess, hMods, sizeof(hMods), &cbNeeded))
{
for (UINT i=; i<(cbNeeded/sizeof(HMODULE)); i++)
{
TCHAR szModName[MAX_PATH]; // Get the full path to the module's file.
if (GetModuleFileNameEx(hRemoteProcess, hMods[i], szModName, sizeof(szModName)/sizeof(TCHAR)))
{
if (!_tcsicmp(lpInjectDll, szModName))
{
CloseHandle(hRemoteProcess);
return hMods[i];
}
}
}
} CloseHandle(hRemoteProcess);
return NULL;
} BOOL InjectDll(LPTSTR lpRemoteProcess, LPTSTR lpInjectDll, BOOL bInject)
{
// 获取SeDebugPrivilege权限
if(FALSE == AdjustProcessPrivilege(GetCurrentProcess(), _T("SeDebugPrivilege")))
return FALSE; // 函数准备
LPTHREAD_START_ROUTINE pfnThread = NULL;
HINSTANCE hMod = GetModuleHandle(_T("kernel32.dll"));
if (bInject)
pfnThread = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod,_LoadLibrary); // LoadLibrary注入
else
pfnThread = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"FreeLibrary"); // FreeLibrary卸载
if(NULL == pfnThread)
return FALSE; __try
{
// 获取目标进程ID
DWORD nRemotePID = GetPID(lpRemoteProcess);
// 打开目标进程
HANDLE hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, nRemotePID);
if(hRemoteProcess == NULL)
{
return FALSE;
} if (bInject) //注入
{
// 在远端进程中分配内存
LPVOID ModName = VirtualAllocEx(hRemoteProcess, NULL, (_tcslen(lpInjectDll)+)*sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);
if(!ModName)
__leave; // 在远端进程中写入dll的文件名
if( == WriteProcessMemory(hRemoteProcess, ModName, lpInjectDll, (_tcslen(lpInjectDll)+)*sizeof(TCHAR), NULL))
__leave; // 创建远程线程
HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, , pfnThread, ModName, , NULL);
if(NULL == hRemoteThread)
__leave;
WaitForSingleObject(hRemoteThread,INFINITE); VirtualFreeEx(hRemoteProcess, ModName, , MEM_RELEASE);
CloseHandle(hRemoteThread);
}
else //卸载
{
// 在进程中查找需要卸载的dll
HMODULE hTarget = CheckProcessModule(lpRemoteProcess, lpInjectDll);
// 创建远程线程
HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, , pfnThread, hTarget, , NULL);
if(NULL == hRemoteThread)
__leave;
WaitForSingleObject(hRemoteThread,INFINITE); CloseHandle(hRemoteThread);
} CloseHandle(hRemoteProcess);
return TRUE;
}
__finally
{
} return FALSE;
}

以上已经将dll成功注入到目标进程,但是怎样让注入的dll执行?可以在dll加载时,执行一段代码。

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Fun(); // 需要执行的代码
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}