首页
社区
课程
招聘
[原创]DLL注入
2020-6-12 15:07 8776

[原创]DLL注入

2020-6-12 15:07
8776

/****************************************************************

前提:准备注入的dll存放在临时目录里面,命名为inject.dll

步骤一 去临时目录查看要注入的dll

步骤二 查找要注入的进程

步骤三 注入dll

***************************************************************/



#define _CRT_SECURE_NO_DEPRECATE

#include<windows.h>

#include <Tlhelp32.h>

#include <comdef.h>

#include <io.h>

#define DllPathSize 1024



int GetDllPath(char* DllPath);

int FindTargetPid(const char* FileName);                   

int InjectDll(int targetid,const char * DllPath);

int targetid = 0;


int main()

{

char DllPath[DllPathSize] = { 0 };

if (GetDllPath(DllPath))                                           // 准备注入的dll名称为inject.dll,存放在临时目录里面

{

if (FindTargetPid("XXXX.exe"))                       // 查找准备注入的进程

{

InjectDll(targetid, DllPath);                    // 注入dll

}

}

return 1;

}



int GetDllPath(char * DllPath)

{

GetTempPathA(DllPathSize -1 , DllPath);

strcat(DllPath, "inject.dll");

if (_access(DllPath, 0) == 0)

{

printf("DllPath: %s\n", DllPath);

return 1;

}

else 

{

printf("File do not exist\n");

return 0;

}

}



int FindTargetPid(const char * FileName)

{

PROCESSENTRY32 pi;

HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (hSnapshot == INVALID_HANDLE_VALUE)

{

printf("can not reateToolhelp32Snapshot \n");

targetid = 0;

return 0;

}


pi.dwSize = sizeof(PROCESSENTRY32);

BOOL bRet = Process32First(hSnapshot, &pi);

while (bRet)

{

_bstr_t ExeFile(pi.szExeFile);

if (strcmp(ExeFile, FileName) == 0)

{

targetid = pi.th32ProcessID;

printf("targetid: %d\n", targetid);

CloseHandle(hSnapshot);

return 1;

}

bRet = Process32Next(hSnapshot, &pi);

}

printf("don not find target pid\n");

return 0;

}




int InjectDll(int targetid,const char * DllPath)

{


HANDLE hDesProcess = OpenProcess(PROCESS_ALL_ACCESS, false, targetid);

if (!hDesProcess)

{

printf("OpenProcess error\n");

return 0;

}


LPVOID pRemoteBuf = VirtualAllocEx(hDesProcess, NULL, DllPathSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

if (pRemoteBuf == NULL)

{

printf("VirtualAllocEx error\n");

return 0;

}


bool ret = WriteProcessMemory(hDesProcess, pRemoteBuf, DllPath, DllPathSize, NULL);

if (ret == 0)

{

printf("WriteProcessMemory error\n");

return 0;

}


HMODULE hMod = GetModuleHandleA("kernel32.dll");

LPTHREAD_START_ROUTINE pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryA");


if (pThreadProc == 0)

{

printf("pThreadProc error\n");

return 0;

}


HANDLE hThread = CreateRemoteThread(hDesProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);

if (hThread == NULL)

{

printf("CreateRemoteThread error\n");

return 0;

}

CloseHandle(hDesProcess);

return 1;

}



[培训]内核驱动高级班,冲击BAT一流互联网大厂工 作,每周日13:00-18:00直播授课

收藏
点赞2
打赏
分享
最新回复 (11)
雪    币: 2680
活跃值: (3312)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Mr.hack 2020-6-12 17:38
2
0
创建远程线程这种注入方式太简单粗暴了,隐蔽性差
雪    币: 167
活跃值: (876)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
taolaoda 2020-6-19 02:14
3
0
巧了我昨天远程线程注入也是使用的创建进程快照然后遍历的
雪    币: 1979
活跃值: (107)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wx_月⃟月⃟來⃟⃟ 2020-7-31 22:11
4
0
请问大牛,是否可以给个实际软体和dll,然後实际将dll注入当作范例?
雪    币: 248
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
HmbGK 2020-8-1 00:02
5
0

 小白已学习  谢谢楼主分享的源码

附上学习理解的 代码

#define _CRT_SECURE_NO_DEPRECATE
//头文件区
#include<windows.h>

#include <cstdlib>

#include <Tlhelp32.h>

#include <comdef.h>

#include <io.h>

#define DllPathSize 1024//常量值




//声明的子程序
int 取系统临时目录(char* 参数_输出结果); //整数型 函数名 (字节指针型 参数名)

int 取进程PID(const char* 进程名称);

int InjectDll(int targetid, const char * DllPath);

int 进程PID = 0;


//程序开始函数入口
int main()

{

	char 局部_临时目录[DllPathSize] = { 0 };//局部变量_字节型_1024长度

	if (取系统临时目录(局部_临时目录))                                           // 准备注入的dll名称为inject.dll,存放在临时目录里面
	{
		if (取进程PID("xxxxx.exe"))                       // 查找准备注入的进程

		{

			InjectDll(进程PID, 局部_临时目录);                    // 注入dll
			system("pause");
		}

	}

	return 1;

}




//取系统临时目录
int 取系统临时目录(char * 参数_输出结果)

{

	GetTempPathA(DllPathSize - 1, 参数_输出结果);//API 取临时目录(常量值, 参数_输出结果)

	strcat(参数_输出结果, "inject.dll");//API 字符串相加(参数_输出结果,自定义常量)

	if (_access(参数_输出结果, 0) == 0)            //判断 文件是否存在(参数_输出结果,判断类型)

	{

		printf("DLL路径: %s\n", 参数_输出结果);     //文件存在  打印输出数据  并返回 1

		return 1;

	}

	else

	{

		printf("inject.dll文件不存在\n");            //文件不存在  打印输出数据  并返回 0

		return 0;

	}

}




//取进程PID
int 取进程PID(const char * 参数_进程名称)
{
	PROCESSENTRY32 类型_进程信息;//进程信息结构体

	HANDLE  局部_快照句柄 = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//拍摄指定进程以及这些进程使用的堆,模块和线程的快照。

	if (局部_快照句柄 == INVALID_HANDLE_VALUE)                            //如果局部_快照句柄=无效的句柄

	{

		printf("can not reateToolhelp32Snapshot \n");                      //打印输出字符 

		进程PID = 0;                                                       //进程PID=0 返回

		return 0;

	}



	类型_进程信息.dwSize = sizeof(PROCESSENTRY32);                         //数据类型长度=取结构体数据长度

	BOOL 句柄_是否成功 = Process32First(局部_快照句柄, &类型_进程信息);            //此函数检有关系统快照中遇到的第一个进程的信息。

	while (句柄_是否成功)
	{
		_bstr_t 局部_进程名称(类型_进程信息.szExeFile);                                 //从进程信息结构体当中取出进程名称

		if (strcmp(局部_进程名称, 参数_进程名称) == 0)                                //判断进程信息结构体当中的进程名是否和参数进程名称相等
		{
			进程PID = 类型_进程信息.th32ProcessID;                                   //从结构体当中取出PID赋值给全局变量

			printf("进程PID: %d\n", 进程PID);                                     //打印输出数据

			CloseHandle(局部_快照句柄);                                          //关闭打开的快照句柄

			return 1;                                                  //返回1

		}

		句柄_是否成功 = Process32Next(局部_快照句柄, &类型_进程信息);

	}

	printf("进程快照句柄获取失败\n");

	return 0;

}






//远程线程注入DLL
int InjectDll(int 进程PID, const char * DLL路径)
{
	HANDLE 局部_进程句柄 = OpenProcess(PROCESS_ALL_ACCESS, false, 进程PID); //获取进程句柄

	if (!局部_进程句柄)                                                    //判断进程句柄            
	{
		printf("获取进程句柄失败\n");
		return 0;
	}
	LPVOID 局部_新内存地址 = VirtualAllocEx(局部_进程句柄, NULL, DllPathSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);//远程申请内存地址



	if (局部_新内存地址 == NULL)
	{
		printf("申请内存失败\n");
		return 0;
	}



	bool 局部_写内存 = WriteProcessMemory(局部_进程句柄, 局部_新内存地址, DLL路径, DllPathSize, NULL);//写进程内存

	if (局部_写内存 == 0)

	{
		printf("写内存失败\n");
		return 0;
	}



	HMODULE 局部_模块句柄 = GetModuleHandleA("kernel32.dll");

	LPTHREAD_START_ROUTINE 局部_函数地址 = (LPTHREAD_START_ROUTINE)GetProcAddress(局部_模块句柄, "LoadLibraryA");



	if (局部_函数地址 == 0)
	{
		printf("获取函数地址失败\n");
		return 0;
	}



	HANDLE 局部_线程句柄 = CreateRemoteThread(局部_进程句柄, NULL, 0, 局部_函数地址, 局部_新内存地址, 0, NULL);//创建远程线程

	if (局部_线程句柄 == NULL)
	{
		printf("创建远程线程失败\n");
		return 0;
	}
	CloseHandle(局部_进程句柄);
	return 1;
}


最后于 2020-8-1 00:04 被HmbGK编辑 ,原因:
雪    币: 123
活跃值: (316)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
taizhong 2020-8-2 13:38
6
0
楼上易语言大手子,...........
雪    币: 129
活跃值: (1273)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
琳宇 2020-8-5 16:17
7
0
这种办法感觉很容易检测出来
雪    币: 11363
活跃值: (4949)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
hhkqqs 1 2020-8-5 23:51
8
0
琳宇 这种办法感觉很容易检测出来
不用感觉,我直接告诉你一种检测办法,hook NtOpenFile,查AccessMask的FILE_EXECUTE标志位,为真则取文件哈希值,不在白名单,芜湖起飞
雪    币: 2680
活跃值: (3312)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Mr.hack 2020-8-6 16:44
9
0
hhkqqs 不用感觉,我直接告诉你一种检测办法,hook NtOpenFile,查AccessMask的FILE_EXECUTE标志位,为真则取文件哈希值,不在白名单,芜湖起飞[em_41]
多数?情况下是hook CreateRemoteThread
雪    币: 11363
活跃值: (4949)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
hhkqqs 1 2020-8-6 23:46
10
0
Mr.hack 多数?情况下是hook CreateRemoteThread
也就应付下那些初级的c&p罢了,call入口点还可以插apc/hijack rip/iat hook/…… hook NtOpenFile基本能废掉LdrLoadDll
雪    币: 667
活跃值: (322)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
www明天 2020-10-18 11:33
11
0
5楼的写法其实很正常,支持全球化的开发工具,都支持这种写法。变量和函数名只是链接符号
雪    币: 129
活跃值: (1273)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
琳宇 2021-8-9 12:58
12
0
hhkqqs 也就应付下那些初级的c&p罢了,call入口点还可以插apc/hijack rip/iat hook/…… hook NtOpenFile基本能废掉LdrLoadDll
loaddll倒是简单,大不了自己写一个。
游客
登录 | 注册 方可回帖
返回