|
DLL远程线程注入初尝试 (qq.com)
DLL注入前提条件
1.windows在动态链接库的使用时在各个进程中的虚拟地址是相同的,所以注入器中的kernel32.dll地址可以当做要被注入的进程的地址用。
2.有相关的权限,注入器的权限要能打开目标权限,以及分配内存和写入内存。
二
DLL注入的相关步骤
1.打开要注入的进程。
2.给进程分配虚拟内存 VirtualAllocEx。
3.给分配的内存写入要注入的DLL目录。
4.找到 kernel32.dll 模块的里面的LoadLibrary函数的地址。
5.用CreatRemoTethread给目标进程注入dll。
6.关闭目标进程的句柄。
三
实验过程
实验工具:
自己编写的注入器,和自己编译的一个简单的DLL文件,x64dbg,win10记事本
实验流程:
1、先打开记事本。
2、然后拿x64dbg附加进程,然后在LoadLibrary函数打下断点,可以在x64dbg的符号表中查找。
编辑
3、运行注入器。
编辑
4、查看注入过程。
编辑
通过查看日志,可以发现线程已经被注入了。
并且rip停到了我们设置断点的位置。
编辑
并且可以看到rcx寄存器中地址存放的地址就是我们写入的地址(这里因为笔者嫌弃麻烦,直接把DLL文件放到了与记事本的同一目录下,所以输入 填写dll文件的名字就好了)。
转存失败重新上传取消
我们会发现在这个call 指令(f8)运行时rip就会立马跳转去,并且会显示出我们注入成功的,但是没看太明rip跳出去的地方是干什么的,因为我在messagebox下了断点也没有断下来,并且窗口直接跳出。
编辑
编辑
注入器和dll文件代码解析
DLL文件代码,IDE: VS2019 - BOOL APIENTRY DllMain( HMODULE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
- {
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
-
- OutputDebugString(L"DLL Inject Sucess");
- MessageBox(NULL, L"dll sucess", L"dll sucess", MB_OK);
- break;//加载DLL时运行d
- case DLL_THREAD_ATTACH: //释放DLL运行的
- OutputDebugString(L"DLL free Sucess");
- MessageBox(NULL, L"dll free", L"dll free", MB_OK);
- break;//加载DLL时运行d
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
- }
复制代码
注入器
- #include<stdio.h>
- #include<Windows.h>
- #include<iostream>
- #include<string>
- using namespace std;
- BOOL CreateRemoteDllInjectDll(DWORD dwProcessId, char *pdllname);
- int main() {
- DWORD dwProcessId;
- char DLLName[20]; //需要输入的DLL文件名字
- cout << "Pleace input DLLfile name :" << endl;
- cin >> DLLName;
- cout << "Pleace input PRocessID :" << endl;
- cin >> dwProcessId;
- CreateRemoteDllInjectDll(dwProcessId,DLLName);
-
- return 0;
-
- }
- /**
- 1.打开要注入的进程
- 2.给进程分配虚拟内存 VirtualAllocEx
- 3.给分配的内存写入要注入的DLL目录
- 4.找到 kernel32.dll 模块的里面的LoadLibrary函数的地址
- 5.用CreatRemoTethread给目标进程注入dll
- 6.关闭目标进程的句柄
- **/
- BOOL CreateRemoteDllInjectDll(DWORD dwProcessId, char *pdllname) {
- HANDLE hProcess = NULL;
- LPVOID pDLLAddr =NULL;\
- HMODULE hker=NULL;
- FARPROC pFunProcAddr =NULL;
- DWORD dwsize=0;
- hker = GetModuleHandleA("kernel32.dll"); //得到kernel32.dll进程中的地址
- if( NULL == hker) {
- puts("GetModuleHandle kernel32.dll is error");
- return false;
- }
-
- hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessId);//打开要注入的进程
- if( NULL == hProcess) { // 检查打开进程是否成功
- puts("OpenProcess is error");
- return false;
- }
- dwsize = strlen(pdllname)+1; //DLL文件目录的长度
- pDLLAddr = VirtualAllocEx(hProcess,NULL,dwsize,MEM_COMMIT,PAGE_READWRITE );
- //申请的内存空间,并且地址保存在pDLLAddr目录中
- if(pDLLAddr == NULL) { //检查
- puts("VirtualAllocEx is error");
- return false;
- }
- if(!WriteProcessMemory(hProcess,pDLLAddr,pdllname,dwsize,NULL)) {//把所需要的注入的dll文件目录字符注入给目标进程
- puts("WriteProcessMemory is error");
- return false;
- }
- pFunProcAddr = GetProcAddress(hker,"LoadLibraryA"); //得到loadlibrarya函数的地址
- if(pFunProcAddr == NULL) {
- puts("Get LoadLibraryA is error");
- return false;
-
- }
- HANDLE hRemotehandle = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)(pFunProcAddr),pDLLAddr,0,NULL); //创造远程线程
- if(!hRemotehandle) {
- puts(" CreateRemoteThread is error");
- return false;
- WaitForSingleObject(hRemotehandle, INFINITE);
- CloseHandle(hRemotehandle);//关闭句柄
- CloseHandle(hProcess);
- return 0;
-
- }
-
- }
复制代码
|
|