概述
1. 原理
主要通过API:CreateRemoteThread 来进行远程线程注入
2.远程线程注入Dll的步骤
1.通过进程Id打开指定的进程 2.在指定的进程,分配一段大小为要导入的dll文件名长度的一段内存空间,将dll的文件名写入到分配的内存中。 3.获取目的进程中的loadLibrary的函数地址。 4.创建远程线程,通过上一步获得的loadlibrary函数进行dll导入。 5.释放内存,卸载dll。
3.代码远程注入注意点
1.不能调用除kernel32和user32之外动态库中的api函数。 2.不能使用static字符串 3. 去掉编译器的/GZ编译选项。这个选项是默认的,不然注入进去被注入的程序会崩溃。 4. 要么把ThreadFunc和AfterThreadFunc声明为static,要么关闭编译器的“增量连接(incremental linking)”(看附录C)。 5. ThreadFunc中的局部变量总大小必须小于4k字节。注意,当degug编译时,这4k中大约有10个字节会被事先占用。 (注入64位的程序,那么也需要64位的dll,主要用的函数:NtCreateThreadEx)
4.代码实现
//提升权限
BOOL cRemoteThreadInject::grantPriviledge(char* priName)
{
if(NULL == priName)
{
return FALSE;
}
TOKEN_PRIVILEGES tokenPriviledge, oldPriviledge;
DWORD dwRetLength = sizeof(oldPriviledge);
HANDLE tokenHandle = NULL;
LUID uId;
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &tokenHandle))
{
if (ERROR_NO_TOKEN != GetLastError())
{
return FALSE;
}
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenHandle))
{
return FALSE;
}
}
if (!LookupPrivilegeValue(NULL, priName, &uId))
{
CloseHandle(tokenHandle);
tokenHandle = NULL;
return FALSE;
}
tokenPriviledge.PrivilegeCount = 1;
tokenPriviledge.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tokenPriviledge.Privileges[0].Luid = uId;
if (!AdjustTokenPrivileges(tokenHandle, FALSE, &tokenPriviledge, sizeof(TOKEN_PRIVILEGES), &oldPriviledge, &dwRetLength))
{
CloseHandle(tokenHandle);
tokenHandle = NULL;
return FALSE;
}
return TRUE;
}
/*
函数功能:通过进程名称获取进程PID
参数1:进程名称
参数2:返回的进程pid
*/
BOOL cRemoteThreadInject::GetProcessId(IN char* processName, OUT DWORD* processId)
{
if(NULL == processName)
{
return FALSE;
}
HANDLE handle = NULL;
PROCESSENTRY32 processTry32 ={0};
processTry32.dwSize = sizeof(PROCESSENTRY32);
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(INVALID_HANDLE_VALUE == handle)
{
return FALSE;
}
Process32First(handle, &processTry32);
do{
if(lstrcmpi(processTry32.szExeFile, processName) == 0)
{
*processId = processTry32.th32ProcessID;
break;
}
}while(Process32Next(handle, &processTry32));
CloseHandle(handle);
handle = NULL;
if(0 == *processId)
{
return FALSE;
}
return TRUE;
}
/*
功能:注入dll文件到进程
参数1:进程的名称
参数2:注入dll的路径
*/
BOOL cRemoteThreadInject::injectDll(char* processName, char* dllPath)
{
if((NULL == processName) || (NULL == dllPath))
{
return FALSE;
}
DWORD processId = 0;
GetProcessId(processName, &processId);
if(processId <= 0)
{
return FALSE;
}
grantPriviledge("SE_DEBUG_NAME");
HANDLE handle = NULL;
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
if(NULL == handle)
{
return FALSE;
}
int dllPathLen = sizeof(dllPath) +1;
PVOID data = VirtualAllocEx(handle, NULL, dllPathLen, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(NULL == data)
{
CloseHandle(handle);
handle = NULL;
return FALSE;
}
SIZE_T RetLength = 0;
BOOL bWriteMem = WriteProcessMemory(handle, data, dllPath, strlen(dllPath)+1, &RetLength);
if(FALSE == bWriteMem)
{
return FALSE;
}
LPTHREAD_START_ROUTINE LoadLibraryAddress = NULL;
#ifdef _UNICODE
HMODULE Kernel32Module = GetModuleHandle(L"Kernel32");
LoadLibraryAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(Kernel32Module, "LoadLibraryW");
#else
HMODULE Kernel32Module = GetModuleHandle(_T("Kernel32"));
LoadLibraryAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(Kernel32Module, "LoadLibraryA");
#endif
HANDLE Threadhandle = CreateRemoteThread(handle, NULL, 0, LoadLibraryAddress, data, 0, NULL);
if (NULL == Threadhandle)
{
CloseHandle(handle);
handle = NULL;
return FALSE;
}
if (WaitForSingleObject(Threadhandle, INFINITE) == WAIT_FAILED)
{
return FALSE;
}
CloseHandle(handle);
handle = NULL;
CloseHandle(Threadhandle);
Threadhandle = NULL;
return TRUE;
}
/*
函数功能:卸载注入到进程后的dll
参数1:进程的名称
参数2:要卸载的dll
*/
BOOL cRemoteThreadInject::unitInjectDll(char* processName, char* dllPath)
{
if((NULL == processName) || (NULL == dllPath))
{
return FALSE;
}
DWORD processId = 0;
GetProcessId(processName, &processId);
if(processId <= 0)
{
return FALSE;
}
BOOL bMore = FALSE;
BOOL bFound = FALSE;
HANDLE hSnapshot, hProcess, hThread;
HMODULE hModule = NULL;
MODULEENTRY32 me = {sizeof(me)};
LPTHREAD_START_ROUTINE pThreadProc;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processId);
bMore = Module32First(hSnapshot, &me);
for(; bMore; bMore = Module32Next(hSnapshot, &me))
{
if(!_tcsicmp(me.szModule, dllPath) || !_tcsicmp(me.szExePath, dllPath))
{
bFound = TRUE;
break;
}
}
if(!bFound)
{
CloseHandle(hSnapshot);
return FALSE;
}
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
if(NULL == hProcess)
{
return FALSE;
}
hModule = GetModuleHandle("kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, me.modBaseAddr, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hProcess);
hProcess = NULL;
CloseHandle(hThread);
hThread = NULL;
CloseHandle(hSnapshot);
hSnapshot = NULL;
return TRUE;
}
最后:
最近我整理了整套《JAVA核心知识点总结》,说实话 ,作为一名Java程序员,不论你需不需要面试都应该好好看下这份资料。拿到手总是不亏的~我的不少粉丝也因此拿到腾讯字节快手等公司的Offer
进【Java进阶之路群】,找管理员获取哦-!
最后
以上就是伶俐小懒虫为你收集整理的一文带你实现远程线程注入和卸载1. 原理2.远程线程注入Dll的步骤3.代码远程注入注意点4.代码实现最后:的全部内容,希望文章能够帮你解决一文带你实现远程线程注入和卸载1. 原理2.远程线程注入Dll的步骤3.代码远程注入注意点4.代码实现最后:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复