Qt开发-共享内存使用范例,配合开发者密钥使用后台调试程序或者进入调试模式

发布时间 2023-05-10 08:58:20作者: 轩先生。

共享内存

就之前不是开发了一个Leventure_DeveloperKey用以调试程序嘛,在这里简单聊一下调试模式的方案。

这里的调试分为了两种,一种是调试模式,一种是开发者模式。需要这两种模式的原因也很简单:1.在远程调试的时候,我可能需要程序从头开始进入调试,这就要求程序一直卡在开头的某个位置。2.在程序使用的时候可能需要一些特殊的按钮,这个按钮就可以让它有一个后门,让它能够以一些特别的状态进入开发者模式,比如一些设置,一些按钮,可以直达某个函数或者某个接口。

为了实现这个功能,主要是要通过一个Leventure_DeveloperKey的认证,也就是当我们打开这个Leventure_DeveloperKey的时候,需要让系统内的所有程序都认识到这个程序的存在,而且要根据不同模式的设置,其他程序对这个程序的认知还不同。

之前的方案是直接修改窗口名称,比如现在是调试模式,就叫DebugMode,现在是开发者模式,就叫Developer,每次程序启动的时候都需要扫描系统内所有程序的窗口名称,并从中扫描出需要的窗口。

但是这样有两个问题:一是修改窗口名称,获取窗口名称的代码比较复杂,读取窗口名称的函数并没有想象中的那么方便。二是这个方案并不跨平台,在windows下可以用,但是在别的平台下就不可用了。

鉴于以上原因,我们就需要一个新的方案:

共享内存的方案

共享内存是一种高效的进程间通讯方式,其基本原理是将同一个物理内存块映射到多个进程的虚拟地址空间中,从而使这些进程可以直接读写相同的内存区域。不同于消息传递或管道等方式,共享内存数据不需要进行复制,因此它更加高效,能够大幅度减少CPU时间和内存的开销。

在使用共享内存时,需要三个步骤:

创建共享内存区域,并将其挂载在进程虚拟地址空间中。
在多个进程之间共享访问该内存区域的句柄/标识符。
通过该句柄/标识符,在多个进程中读写共享内存中的数据。
共享内存的优点包括:

高效:共享内存不需要复制大量数据,因此速度较快,对系统资源使用较少。
方便:所有映射到该内存区域的进程都可以方便地访问该内存,无需通过其他IPC机制来传递数据。
灵活:长期存在,可随时修改数据。
可扩展性强:可以增加多个进程共享单个内存区域。
然而,使用共享内存也需要注意一定的安全问题,如避免出现数据混乱、避免重复映射等。

共享内存使用场景:

共享内存是一种在进程之间传递数据的高效方法,因为它避免了数据复制的不必要开销。共享内存适用于以下情况:

数据量较大:如果数据量很大,将它们复制到其他进程中可能会导致性能问题和额外的系统负担。使用共享内存可以避免这些问题。

进程需要频繁访问相同的数据:如果多个进程需要对同一个数据集进行频繁的读写访问,则使用共享内存往往比使用管道或套接字等 IPC 机制更有效。

需要高速通信:共享内存操作非常快速,因为它直接访问内存而无需复制数据或通过加/解锁来同步访问。这使得它特别适合需要快速通信的应用程序,例如实时数据流、多媒体传输等。

进程需要使用共享的状态信息:如果多个进程或线程需要访问使用相同的状态信息,则将这些信息放在共享内存区域中是最好的方式之一。

给定应用程序的要求:有些应用程序需要使用共享内存进行通信。这主要取决于应用程序的设计、复杂性和性能需求。

值得注意的是,使用共享内存要小心,因为多个进程同时访问同一块内存可能会导致数据不一致问题。因此,在使用共享内存时需要正确地管理锁和同步机制以确保数据的正确性。

使用例:

Leventure_DeveloperKey中可以放上如下代码:

#include <QtSharedMemory>
#include <QString>

int main(int argc, char *argv[])
{
	// 创建共享内存,并指定唯一的键名
	QSharedMemory sharedMemory("Leventure_Developer");

	// 如果共享内存已经被创建过,则释放它
	if (!sharedMemory.create(sizeof(QString))) {
		sharedMemory.attach();
		sharedMemory.deleteLater();
		sharedMemory.create(sizeof(QString));
	}

	// 将要写入共享内存的字符串
	QString developer = "Developer";

	// 锁定共享内存,确保数据可以正确写入
	if (sharedMemory.lock()) {

		// 将字符串拷贝到共享内存中
		QString *data = (QString*)sharedMemory.data();
		*data = developer;

		// 解锁共享内存
		sharedMemory.unlock();
	}

	return 0;
}

在需要植入后门程序的代码中放入类似代码:

#include <QtSharedMemory>
#include <QString>

int main(int argc, char *argv[])
{
	// 创建共享内存,并指定唯一的键名
	QSharedMemory sharedMemory("Leventure_Developer");

	// 锁定共享内存,以便读取数据
	if (sharedMemory.lock()) {

		// 从共享内存中读取数据并转换为 QString 类型
		QString *data = (QString*)sharedMemory.data();
		QString developer = *data;

		// 解锁共享内存
		sharedMemory.unlock();

		// 处理从共享内存读取到的数据
		qDebug() << developer;
	}

	return 0;
}