概述
- DLL文件如果不被进程加载就无效了
- 方法是强制让某进程加载DLL文件,强制手段通过创建远程线程将DLL注入到某个指定的进程中
使用CreateRemoteThread()函数创建远程线程
HANDLE CreateRemoteThread(
HANDLE hProcess, // handle to process
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
DWORD dwStackSize, // initial stack size
LPTHREAD_START_ROUTINE lpStartAddress, // thread function
LPVOID lpParameter, // thread argument
DWORD dwCreationFlags, // creation option
LPDWORD lpThreadId // thread identifier
);
HANDLE WINAPI CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
)
{
return CreateRemoteThread(GetCurrentProcess(),
lpThreadAttributes,
dwStackSize,
lpStartAddress,
lpParameter,
dwCreationFlags,
lpThreadId);
}
GetCurrentProcess()函数的功能是获取当前进程的句柄。
CreateRemoteProcess()函数是注入到其他进程的,其第一个参数是指定某进程的句柄。得到目标进程的PID(进程ID),就可以通过==OpenProcess()==函数获取该进程的句柄。
除了hProcess参数以外,关键的参数就只有lpStartAddress和lpParameter两个了。lpStartAddress指定线程函数的地址,lpParameter指定传递给线程函数的参数。每个进程的地址空间是隔离的,那么新创建的线程函数的地址也应该在目的进程中,而不应该在本进程中,同样的传递给线程函数的参数也应该在目的进程中。
注入DLL,线程函数的功能也就是加载DLL文件。加载DLL文件的方法是调用LoadLibrary()函数。
HMODULE LoadLibrary(
LPCTSTR lpFileName // file name of module
);
DWORD WINAPI ThreadProc(
LPVOID lpParameter // thread data
);
可以直接把LoadLibrary()函数作为线程函数创建到指定进程中。LoadLibrary()的参数是要加载的DLL文件的路径。这样,使用CreateRemoteThread()就可以创建一个远程线程了。
那就是如何将LoadLibrary()函数的地址放到目标进程空间中,还有如何把DLL文件路径也保存到目标进程空间中。
LoadLibrary()函数在Kernel32.dll这个系统DLL中,而Kernel32.dll这个DLL文件在任何进程中的加载位置都是相同的,也就是说,LoadLibrary()函数的地址在任何进程中的地址都是相同的,因此只要在进程中获取LoadLibrary()函数的地址后,该地址在目标进程中也是可以使用的。至于要注入的DLL文件如何写入目标进程中,那么就要依赖一个API函数了,
BOOL WriteProcessMemory(
HANDLE hProcess, // handle to process
LPVOID lpBaseAddress, // base of memory area
LPVOID lpBuffer, // data buffer
DWORD nSize, // number of bytes to write
LPDWORD lpNumberOfBytesWritten // number of bytes written
);
该函数的功能是把lpBuffer中的内容写到hProcess指定进程中的
lpBaseAddress地址处
hProcess:指定进程的进程句柄。
lpBaseAddress:指定写入内存的起始地址。
lpBuffer:指定要写入的内容的缓冲区。
nSize:指定写入内容的长度。
lpNumberOfBytesWritten:接收实际写入内容的长度。
使用该函数可以把DLL文件的地址写入目标进程中,这样就可以在目标进程中用LoadLibrary()加载该DLL文件。但是WriteProcessMemory()第二个参数是指定写入的起始地址,这个地址明显在目标进程中,那么这个地址是哪个地址?目标进程中的哪块内存允许把DLL文件的路径写进去呢?如何确定应该写入目标进程的哪个地址。应该先在目标进程中申请一块内存,然后把DLL文件的路径写入进去,这样就可以解决了。
在目标进程申请内存的函数如下
LPVOID VirtualAllocEx(
HANDLE hProcess, // process to allocate memory
LPVOID lpAddress, // desired starting address
SIZE_T dwSize, // size of region to allocate
DWORD flAllocationType, // type of allocation
DWORD flProtect // type of access protection
);
参数说明如下。
(1)hProcess:指定要申请内存的进程句柄。
(2)lpAddress:指定申请的起始位置。
(3)dwSize:指定申请的长度。
(4)flAllcationType:指定申请内存的状态类型。
(5)flProtect:指定申请内存的内存属性。
该函数的返回值返回目标进程申请到的内存块的起始地址。
对于DLL的卸载使用的API函数如下:
BOOL FreeLibrary(
HMODULE hModule // handle to DLL module
);
该函数的参数是要卸载的模块的句柄。
CString strdWord="FFF9AA1D"; DWORD dwWord=_tcstoul(strdWord,NULL,16); //16进制还可以是2、8、10进制
CString strdWord="124572112121"; DWORD dwWord=_tcstoul(strdWord,NULL,10); // 10进制
按照以上的方式,使用getpid获取指定名称进程pid,传入OpenProcess打开进程获取进程句柄。但是会发现这时候进程是无法打开的,或者说进程不能以完全访问的权限打开,因此必须提高本地程序的权限,这是远程注入线程引发的第一个问题
//获取进程name的ID
DWORD getPid(LPTSTR name)
{
HANDLE hProcSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//获取进程快照句柄
assert(hProcSnap!=INVALID_HANDLE_VALUE);
PROCESSENTRY32 pe32;
pe32.dwSize=sizeof(PROCESSENTRY32);
BOOL flag=Process32First(hProcSnap,&pe32);//获取列表的第一个进程
while(flag)
{
if(!_tcscmp(pe32.szExeFile,name))
{
CloseHandle(hProcSnap);
return pe32.th32ProcessID;//pid
}
flag=Process32Next(hProcSnap,&pe32);//获取下一个进程
}
CloseHandle(hProcSnap);
return 0;
}
最后
以上就是自然帅哥为你收集整理的C/C++ 远程线程注入的全部内容,希望文章能够帮你解决C/C++ 远程线程注入所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复