本文为看雪论坛优秀文章
看雪论坛作者ID:xmyxxh
一
DLL注入前提条件
1.windows在动态链接库的使用时在各个进程中的虚拟地址是相同的,所以注入器中的kernel32.dll地址可以当做要被注入的进程的地址用。
2.有相关的权限,注入器的权限要能打开目标权限,以及分配内存和写入内存。
二
DLL注入的相关步骤
1.打开要注入的进程。
三
实验过程
实验工具:
自己编写的注入器,和自己编译的一个简单的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;
}
}
看雪ID:xmyxxh
https://bbs.kanxue.com/user-home-943747.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!