当前位置: 首页 > news >正文

[逆向工程]C++实现DLL注入:原理、实现与防御全解析(二十五)

[逆向工程]C++实现DLL注入:原理、实现与防御全解析(二十五)

引言

DLL注入(DLL Injection)是Windows系统下实现进程间通信、功能扩展、监控调试的核心技术之一。本文将从原理分析、代码实现、实战调试到防御方案,全方位讲解如何用C++实现DLL注入,并提供可直接编译的完整项目代码。

一、资源准备

1.资源准备

gmp.exe 被注入的程序

injector.exe 注入器

mandaohook.dll 需注入的dll

2.任务目标

将编写好的mandaohook.dll通过injector.exe注入器注入到gmp.exe可运行程序中。gmp.exe是一个密码学工具箱。

二、DLL注入的核心原理

DLL注入的本质是强制目标进程加载指定的DLL文件,其核心流程为:

  1. 获取目标进程句柄:通过进程ID或进程名定位目标
  2. 在目标进程中分配内存:用于存储DLL路径
  3. 写入DLL路径:将DLL的完整路径写入目标内存
  4. 创建远程线程:通过LoadLibrary加载DLL

三、关键API函数解析

API函数作用描述关键参数说明
OpenProcess打开目标进程dwProcessId:目标进程ID
VirtualAllocEx在目标进程分配内存lpAddress:分配内存地址
WriteProcessMemory向目标内存写入数据lpBaseAddress:目标内存地址
CreateRemoteThread在目标进程创建远程线程lpStartAddress:线程入口点
GetProcAddress获取LoadLibrary函数地址lpProcName:函数名

四、完整C++实现代码

1. 注入器代码(Injector.cpp)
#include <Windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <memory>// 自动释放资源模板
template<typename T>
struct HandleDeleter {void operator()(T* handle) const {if (handle) CloseHandle(handle);}
};
using UniqueHandle = std::unique_ptr<void, HandleDeleter<void>>;// 查找进程ID(优化版)
DWORD FindProcessId(const wchar_t* processName) {PROCESSENTRY32W pe = { sizeof(pe) };UniqueHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));if (!snapshot.get()) return 0;if (Process32FirstW(snapshot.get(), &pe)) {do {if (_wcsicmp(processName, pe.szExeFile) == 0) {return pe.th32ProcessID;}} while (Process32NextW(snapshot.get(), &pe));}return 0;
}// 注入主函数
int main() {// 1. 查找进程const DWORD pid = FindProcessId(L"gmp.exe");if (!pid) {std::wcerr << L"错误:未找到进程!" << std::endl;return EXIT_FAILURE;}// 2. 打开进程UniqueHandle hProcess(OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,FALSE, pid));if (!hProcess) {std::wcerr << L"打开进程失败(代码:" << GetLastError() << L")" << std::endl;return EXIT_FAILURE;}// 3. 获取DLL路径wchar_t dllPath[MAX_PATH];if (!GetFullPathNameW(L"mandaohook.dll", MAX_PATH, dllPath, nullptr)) {std::wcerr << L"获取路径失败(代码:" << GetLastError() << L")" << std::endl;return EXIT_FAILURE;}// 4. 分配内存const size_t pathSize = (wcslen(dllPath) + 1) * sizeof(wchar_t);UniqueHandle pRemoteMem(VirtualAllocEx(hProcess.get(), nullptr, pathSize, MEM_COMMIT, PAGE_READWRITE));if (!pRemoteMem) {std::wcerr << L"内存分配失败(代码:" << GetLastError() << L")" << std::endl;return EXIT_FAILURE;}// 5. 写入路径if (!WriteProcessMemory(hProcess.get(), pRemoteMem.get(), dllPath, pathSize, nullptr)) {std::wcerr << L"写入内存失败(代码:" << GetLastError() << L")" << std::endl;return EXIT_FAILURE;}// 6. 获取LoadLibrary地址const auto pLoadLibrary = reinterpret_cast<LPTHREAD_START_ROUTINE>(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW"));if (!pLoadLibrary) {std::wcerr << L"获取函数地址失败(代码:" << GetLastError() << L")" << std::endl;return EXIT_FAILURE;}// 7. 创建远程线程UniqueHandle hThread(CreateRemoteThread(hProcess.get(), nullptr, 0,pLoadLibrary, pRemoteMem.get(), 0, nullptr));if (!hThread) {std::wcerr << L"创建线程失败(代码:" << GetLastError() << L")" << std::endl;return EXIT_FAILURE;}// 8. 等待注入完成WaitForSingleObject(hThread.get(), INFINITE);std::wcout << L"注入成功!" << std::endl;return EXIT_SUCCESS; 
}

编译:

g++ -shared -o mandaohook.dll mandaohook.cpp -luser32 -lgdi32 -Wall

在这里插入图片描述

2.目标DLL头文件(mandaohook.h)
#pragma once
#include <Windows.h>LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam);
3. 目标DLL代码(mandaohook.cpp)
/*********************** myhook.cpp ***********************/
#include "mandaohook.h"// 全局变量
HHOOK g_hHook = NULL;
HWND g_hNotepadppWnd = NULL;// 前向声明线程函数
DWORD WINAPI ThreadProc(LPVOID lpParameter);//-----------------------------------------------------------------------------
// DLL入口函数
//-----------------------------------------------------------------------------
BOOL APIENTRY DllMain(HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:// 创建线程避免阻塞DllMainCreateThread(nullptr, 0, ThreadProc, hModule, 0, nullptr);break;case DLL_PROCESS_DETACH:if (g_hHook) {UnhookWindowsHookEx(g_hHook);g_hHook = nullptr;}break;}return TRUE;
}// 线程处理函数
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{HMODULE hModule = (HMODULE)lpParameter;// 使用 OutputDebugStringW 输出调试信息OutputDebugStringW(L"DLL成功注入gmp.exe!");MessageBoxW(nullptr, L"DLL成功注入gmp.exe!", L"提示", MB_OK);g_hNotepadppWnd = FindWindowExW(nullptr, nullptr, L"gmp.exe", nullptr);if (g_hNotepadppWnd) {g_hHook = SetWindowsHookExW(WH_KEYBOARD_LL,HookProc,hModule,0);}return 0;
}//-----------------------------------------------------------------------------
// 钩子处理函数
//-----------------------------------------------------------------------------
LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam)
{if (code == HC_ACTION) {const auto* pKbd = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);if (pKbd->vkCode == VK_F12 && (pKbd->flags & LLKHF_UP)) {MessageBoxW(g_hNotepadppWnd, L"安全提示:F12功能已被拦截!", L"安全防护", MB_ICONWARNING | MB_OK);return 1;}}return CallNextHookEx(g_hHook, code, wParam, lParam);
}

编译:

g++ -shared -o mandaohook.dll mandaohook.cpp -luser32 -lwininet -Wall -municode

在这里插入图片描述

五、测试结果

gmp.exe injector.exe mandaohook.dll放入同一个文件夹下:

在这里插入图片描述

1.先打开gmp.exe 工具

2.再打开DebugView

3.执行injector.exe 注入器注入

4.查看注入信息

可以先查看下gmp.exe PID
在这里插入图片描述
在这里插入图片描述

查看DebugView已注入。

六、技术难点与解决方案

1. 权限问题
  • 症状OpenProcess返回ERROR_ACCESS_DENIED
  • 解决:以管理员权限运行注入器
  • 代码实现
    #include <ShellAPI.h>
    ShellExecuteW(nullptr, L"runas", L"Injector.exe", nullptr, nullptr, SW_SHOW);
    
2. 路径转换问题
  • 症状:DLL路径包含中文字符导致写入失败
  • 解决:使用宽字符API并验证路径
    if (!PathFileExistsW(dllPath)) {// 处理路径不存在的情况
    }
    
3. 64/32位进程兼容
  • 症状:跨架构注入失败(如64位注入器操作32位进程)
  • 解决:使用Wow64DisableWow64FsRedirection
    PVOID oldValue = nullptr;
    Wow64DisableWow64FsRedirection(&oldValue);
    // 执行文件操作
    Wow64RevertWow64FsRedirection(oldValue);
    

七、防御DLL注入方案

  1. 进程保护:调用SetProcessMitigationPolicy
    PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY policy = {};
    policy.MicrosoftSignedOnly = 1;
    SetProcessMitigationPolicy(ProcessSignaturePolicy, &policy, sizeof(policy));
    
  2. 钩子检测:定期检查LoadLibrary调用栈
  3. 内存保护:启用DEP和ASLR
    #pragma comment(linker, "/DYNAMICBASE:YES")
    #pragma comment(linker, "/NXCOMPAT")
    

八、实战调试技巧

  1. 调试输出:使用OutputDebugStringW
    OutputDebugStringW(L"[DEBUG] DLL已加载");
    
  2. 日志文件:写入临时文件监控行为
    FILE* f = _wfopen(L"C:\\inject_log.txt", L"a+");
    fwprintf(f, L"PID:%d 已注入\n", GetCurrentProcessId());
    fclose(f);
    
  3. Process Monitor:监控进程的DLL加载事件

如果本教程对您有帮助,请点赞❤️收藏⭐关注支持!欢迎在评论区留言交流技术细节!

相关文章:

[逆向工程]C++实现DLL注入:原理、实现与防御全解析(二十五)

[逆向工程]C实现DLL注入&#xff1a;原理、实现与防御全解析&#xff08;二十五&#xff09; 引言 DLL注入&#xff08;DLL Injection&#xff09;是Windows系统下实现进程间通信、功能扩展、监控调试的核心技术之一。本文将从原理分析、代码实现、实战调试到防御方案&#x…...

gcc/g++常用参数

1.介绍 gcc用于编译c语言&#xff0c;g用于编译c 源代码生成可执行文件过程&#xff0c;预处理-编译-汇编-链接。https://zhuanlan.zhihu.com/p/476697014 2.常用参数说明 2.1编译过程控制 参数作用-oOutput&#xff0c;指定输出名字-cCompile&#xff0c;编译源文件生成对…...

51单片机课设基于GM65模块的二维码加条形码识别

系统组成 主控单元&#xff1a;51单片机&#xff08;如STC89C52&#xff09;作为核心控制器&#xff0c;协调各模块工作。 扫描模块&#xff1a;GM65条码扫描头&#xff0c;支持二维码/条形码识别&#xff0c;通过串口&#xff08;UART&#xff09;与单片机通信。 显示模块&a…...

物联网赋能7×24H无人值守共享自习室系统设计与实践!

随着"全民学习"浪潮的兴起&#xff0c;共享自习室市场也欣欣向荣&#xff0c;今天就带大家了解下在物联网的加持下&#xff0c;无人共享自习室系统的设计与实际方法。 一、物联网系统整体架构 1.1 系统分层设计 层级技术组成核心功能用户端微信小程序/H5预约选座、…...

基于多头自注意力机制(MHSA)增强的YOLOv11主干网络—面向高精度目标检测的结构创新与性能优化

深度学习在计算机视觉领域的快速发展推动了目标检测算法的持续进步。作为实时检测框架的典型代表&#xff0c;YOLO系列凭借其高效性与准确性备受关注。本文提出一种基于多头自注意力机制(Multi-Head Self-Attention, MHSA)增强的YOLOv11主干网络结构&#xff0c;旨在提升模型在…...

使用Spring Boot与Spring Security构建安全的RESTful API

使用Spring Boot与Spring Security构建安全的RESTful API 引言 在现代Web应用开发中&#xff0c;安全性是不可忽视的重要环节。Spring Boot和Spring Security作为Java生态中的主流框架&#xff0c;为开发者提供了强大的工具来构建安全的RESTful API。本文将详细介绍如何结合S…...

小刚说C语言刷题—1230蝴蝶结

1.题目描述 请输出 n 行的蝴蝶结的形状&#xff0c;n 一定是一个奇数&#xff01; 输入 一个整数 n &#xff0c;代表图形的行数&#xff01; 输出 n 行的图形。 样例 输入 9 输出 ***** **** *** ** * ** *** **** ***** 2.参考代码&#xff08;C语言版&#xff09…...

利用SenseGlove触觉手套开发XR手术训练体验

VirtualiSurg和VR触觉 作为领先的培训平台&#xff0c;VirtualiSurg自2017年以来一直利用扩展现实 (XR) 和触觉技术&#xff0c;为全球医疗保健行业提供个性化、数据驱动的学习解决方案。该平台赋能医疗专业人员进行协作式学习和培训&#xff0c;提升他们的技能&#xff0c;使…...

CT重建笔记(五)—2D平行束投影公式

写的又回去了&#xff0c;因为我发现我理解不够透彻&#xff0c;反正想到啥写啥&#xff0c;尽量保证内容质量好简洁易懂 2D平行束投影公式 p ( s , θ ) ∫ ∫ f ( x , y ) δ ( x c o s θ y s i n θ − s ) d x d y p(s,\theta)\int \int f(x,y)\delta(x cos\theta ysi…...

【Java】应对高并发的思路

在Java中应对高并发场景需要结合多方面的技术手段和设计模式&#xff0c;从线程管理、数据结构、同步机制到异步处理、IO优化等&#xff0c;都需要合理设计和配置。以下是Java在高并发场景下的主要应对策略和最佳实践&#xff1a; 1. 线程管理 1.1 线程池&#xff08;ThreadPo…...

从数据分析到数据可视化:揭开数据背后的故事

从数据分析到数据可视化:揭开数据背后的故事 大家好,今天咱们聊聊“从数据分析到数据可视化”的完整流程。说实话,数据分析和可视化这俩词听起来高大上,但咱们平时就是围绕这俩词打转——数据分析帮我们找故事,可视化则帮我们讲故事。没有它们,数据就是死的;有了它们,数…...

WPS JS宏实现去掉文档中的所有空行

WPS改造系列文章&#xff1a; 1.在WPS中通过JavaScript宏&#xff08;JSA&#xff09;调用本地DeepSeek API优化文档教程&#xff1a;在WPS中通过JavaScript宏&#xff08;JSA&#xff09;调用本地DeepSeek API优化文档教程_wps javascript-CSDN博客 2.在WPS中通过JavaScrip…...

【2025年软考中级】第一章1.6 安全性、可靠性、性能评价

文章目录 安全性、可靠性、性能评价计算机可靠性可靠性指标串并联系统可靠性并联系统可靠性N模元余系统 计算机系统性能评价信息安全加密技术对称&#xff08;私钥&#xff09;加密技术非对称加密技术&#xff08;公钥&#xff09;对称和非对称加密算法的区别数字信封原理数字签…...

MODBUS RTU通信协议详解与调试指南

一、MODBUS RTU简介 MODBUS RTU&#xff08;Remote Terminal Unit&#xff09;是一种基于串行通信&#xff08;RS-485/RS-232&#xff09;的工业标准协议&#xff0c;采用二进制数据格式&#xff0c;具有高效、可靠的特点&#xff0c;广泛应用于PLC、传感器、变频器等工业设备…...

【深度学习新浪潮】大模型时代,我们还需要学习传统机器学习么?

在大模型时代,AI 工程师仍需掌握传统机器学习知识,这不仅是技术互补的需求,更是应对复杂场景和职业发展的关键。以下从必要性和学习路径两方面展开分析: 一、传统机器学习在大模型时代的必要性 技术互补性 大模型(如GPT、BERT)擅长处理复杂语义和生成任务,但在数据量少…...

深入解析Spring Boot与Spring Security的集成实践

深入解析Spring Boot与Spring Security的集成实践 引言 在现代Web应用开发中&#xff0c;安全性是一个不可忽视的重要方面。Spring Security作为Spring生态中的安全框架&#xff0c;提供了强大的认证和授权功能。本文将结合Spring Boot&#xff0c;详细介绍如何集成Spring Se…...

嵌入式学习笔记 - STM32 使用一个外部触发同时启动两个定时器

一个定时器是同时可以设置成主模式跟从模式的&#xff0c; 下面例子中&#xff0c; 一 TM1首先被配置为主模式&#xff0c; 通过MMS001&#xff1a;使能 – 计数器使能信号CNT_EN被用于作为触发输出(TRGO)。见寄存器描述&#xff0c;此位默认为000&#xff0c;这时从模式状态…...

JWT令牌验证

一、JWT 验证方式详解 JWT&#xff08;JSON Web Token&#xff09;的验证核心是确保令牌未被篡改且符合业务规则&#xff0c;主要分为以下步骤&#xff1a; 1. 令牌解析与基础校验 收到客户端传递的 JWT 后&#xff0c;首先按 . 分割为三部分&#xff1a;Header、Payload、S…...

Go语言 GORM框架 使用指南

在 Go 语言社区中&#xff0c;数据库交互一直是开发者们关注的重点领域&#xff0c;不同开发者基于自身的需求和偏好&#xff0c;形成了两种主要的技术选型流派。一部分开发者钟情于像sqlx这类简洁的库&#xff0c;尽管其功能并非一应俱全&#xff0c;但它赋予开发者对 SQL 语句…...

c#车检车构客户管理系统软件车辆年审短信提醒软件

# CMS_VehicleInspection 车检车构客户管理系统软件车辆年审短信提醒软件 # 开发背景 软件是给泸州某公司开发的车检车构客户管理系统软件。用于在车检年审到期前一个月给客户发送车检短信提醒 # 功能描述 主要功能&#xff1a;车辆年审前一个月给客户发年审短信提醒&#xf…...

匿名函数与闭包(Anonymous Functions and Closures)-《Go语言实战指南》原创

Go 支持将函数当作值来使用&#xff0c;也允许定义匿名函数&#xff0c;并通过闭包实现对外部变量的捕获与持续访问。这一特性使函数式编程风格在 Go 中成为可能。 一、什么是匿名函数&#xff1f; 匿名函数是没有名字的函数&#xff0c;可以定义后立即调用&#xff0c;或赋值…...

兰亭妙微:用系统化思维重构智能座舱 UI 体验

兰亭妙微设计专注于以产品逻辑驱动的界面体验优化&#xff0c;服务领域覆盖AI交互、智能穿戴、IoT设备、智慧出行等多个技术密集型产业。我们倡导以“系统性设计”为方法论&#xff0c;在用户需求与技术边界之间找到最优解。 此次智能驾驶项目&#xff0c;我们为某车载平台提供…...

Flowbite 和 daisyUI 那个好用?

Flowbite 和 daisyUI 都是基于 Tailwind CSS 的组件库&#xff0c;它们各有特色&#xff0c;选哪个更好用&#xff0c;取决于你的项目需求和设计偏好。 简要结论 对比项daisyUIFlowbite上手难度简单&#xff0c;类名即组件略复杂&#xff08;多用 HTML 结构&#xff09;Vue 支…...

中间网络工程师知识点5

1.PKI证书主要用于确保主体公钥的合法性 2.VLAN帧的最小帧长是64字节,其中表示帧优先级的字是PRI 3.WIFI6是2.4GHZ和5GHZ频段的,理论吞吐量最高可达9.6Gbps,遵从协议802.11ax,支持完整版的MU-MIMO 4.在大型无线网络中,AP通过DHCP option43端口来获取AC的IP地址 5.项目…...

二、数据模型

二、数据模型 数据模型回顾 数据模型&#xff08;Data Model&#xff09; 是信息领域采用的模型将现实世界的各种事物以及事物之间的联系&#xff0c;表示为数据以及数据之间的联系是对现实世界数据特征的抽象和模拟用来描述数据、组织数据和操作数是数据库系统的核心和基础 …...

获取淘宝店铺所有商品信息接口数据指南

在电商运营和数据分析中&#xff0c;获取淘宝店铺的商品信息是常见的需求。淘宝开放平台提供了丰富的 API 接口&#xff0c;方便开发者获取商品的详细信息&#xff0c;包括商品列表、商品详情、销量等。本文将详细介绍如何从零开始获取淘宝店铺的所有商品信息&#xff0c;包括注…...

目标检测工作原理:从滑动窗口到Haar特征检测的完整实现

目标检测探索指南 &#x1f50d; 目标检测就像是一位细心的侦探&#xff01;我们需要在图像中寻找并定位特定的目标&#xff0c;就像侦探在现场搜寻线索一样。让我们一起来探索这个充满挑战的图像处理领域吧&#xff01; 目录 1. 什么是目标检测&#xff1f;2. 滑动窗口检测3.…...

【LUT技术专题】针对降噪优化的通道感知轻量级LUT算法:DnLUT

DnLUT&#xff1a;Ultra-Efficient Color Image Denoising via Channel-Aware Lookup&#xff08;2025 CVPR&#xff09; 专题介绍一、研究背景二、DnLUT方法2.1 Pairwise Channel Mixer2.2 Rotation Non-overlapping Kernel&#xff08;L型卷积&#xff09; 三、实验结果四、总…...

支持同步观看的媒体服务器GhostHub

简介 什么是 GhostHub &#xff1f; GhostHub 是一个基于滑动界面的媒体服务器&#xff0c;旨在实现实时同步、聊天和隧道分享。它允许用户快速共享和浏览媒体内容&#xff0c;无需复杂的配置或帐户。 主要特点 零配置: 即开即用&#xff0c;无需安装或创建帐户。滑动浏览: 提…...

告别 pip:使用 uv 加速你的 Python 包管理

使用 uv:更快的 Python 包管理工具 随着 Python 生态的演进,包管理工具也在不断升级迭代。uv 是 Astral(同样维护 ruff 的团队)推出的下一代 Python 包与项目管理器,主打 单一可执行文件、极致性能,可在多数场景下取代 pip、pip-tools、pipx 与 virtualenv 等传统工具,…...

使用glsl 来做视频矫正

描述、优点 使用glsl来代替opencv的undistort 和 鱼眼矫正,并且最后使用opencv的LUT给glsl 来使用,来达到加速的目的,并且做到和opencv 一模一样的效果,达到实时视频的加速矫正。 优点: 没有cuda,也可以做到实时视频矫正,包含各类板子和amd的cpu,intel核显 矫正的基本作…...

【VSCode】快捷键合集(持续更新~)

一、基础编辑操作 注释/取消注释 Ctrl /&#xff1a;快速注释或取消注释当前行或选中行。ctrlshift/&#xff1a;块注释 代码格式化 • Shift Alt F&#xff1a;格式化整个文档&#xff0c;统一代码风格。 行操作 • Alt ↑/↓&#xff1a;向上/向下移动当前行。 • Shi…...

MATLAB学习笔记(七):MATLAB建模城市的雨季防洪排污的问题

使用 MATLAB 对城市雨季防洪排污问题进行建模与仿真&#xff0c;需要结合数学模型、工程经验和 MATLAB 的数值计算、数据可视化及优化工具。以下是详细的步骤指南&#xff0c;包含实际案例和代码示例&#xff1a; 一、问题分析与建模框架 1. 问题拆解 • 核心目标&#xff1a; …...

由浮点数x的位级表示求其整型值

由浮点数x的位级表示&#xff0c;得到浮点数的十进制表示&#xff0c;在超过32位整型数的表示范围时&#xff0c;返回0X80000000&#xff1b;在32位整型数的表示范围内时&#xff0c;返回强制转化为整型的值。舍入时采用向0舍入。 程序代码 typedef unsigned long int float_…...

【Qt】Qt常见控件的相关知识点

1.close退出槽函数 2.设置快捷键&#xff0c;QMenu 。 适用&字母就能设置快捷键&#xff0c;运行qt程序&#xff0c;最后就可以按Alt对应的字母进行快捷操作。 3.QMenuBar内存泄露问题 如果ui已经自动生成了menubar&#xff0c;我们再次生成一个新的菜单栏&#xff0c;而…...

数据结构*优先级队列(堆)

什么是优先级队列(堆) 优先级队列一般通过堆&#xff08;Heap&#xff09;这种数据结构来实现&#xff0c;堆是一种特殊的完全二叉树&#xff0c;其每个节点都满足堆的性质。如下图所示就是一个堆&#xff1a; 堆的存储方式 由于堆是一棵完全二叉树&#xff0c;所以也满足二…...

Windows本地化部署Dify完整指南

Windows本地化部署Dify完整指南 作者&#xff1a;朱元禄 版权声明&#xff1a;本文为朱元禄原创文章&#xff0c;转载请注明出处及作者信息 关键词&#xff1a;Dify部署,Windows安装Dify,Dify本地化,Dify教程,Dify配置,朱元禄 一、Docker Desktop安装与配置 1.1 下载Docker De…...

全局异常处理:如何优雅地统一管理业务异常

在软件开发中&#xff0c;异常处理是保证系统健壮性的重要环节。一个良好的异常处理机制不仅能提高代码的可维护性&#xff0c;还能为使用者提供清晰的错误反馈。本文将介绍如何通过全局异常处理和业务异常统一处理来编写更加优雅的代码。 一、传统异常处理的痛点 1.1 典型问…...

AI517 AI本地部署 docker微调(失败)

本地部署AI 计划使用OLLAMA进行本地部署 修改DNS 访问github 刷新缓存 配置环境变量 OLLAMA安装成功 部署成功 计划使用docker进行微调 下载安装docker 虚拟化已开启 开启上面这些 准备下载ubuntu docker ragflow dify 用git去泡...

C++(初阶)(十八)——AVL树

AVL树 AVL树概念实现AVL树的结点插入插入方法 平衡因子更新更新停止条件旋转右单旋左单旋左右双旋右左双旋 遍历AVL平衡检测 完整代码 概念 1&#xff0c;AVL树是最先发明的⾃平衡⼆叉查找树&#xff0c;AVL树是⼀颗⾼度平衡搜索⼆叉树&#xff0c; 通过控制高度差去控制平衡。…...

2022河南CCPC(前四题)

签到题目 #include <bits/stdc.h> using namespace std; #define int long long #define PII pair<int,int> #define fi first #define se second #define endl \n #define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);void solve() {int n;cin>>…...

【滑动窗口】LeetCode 1658题解 | 将 x 减到 0 的最小操作数

将 x 减到 0 的最小操作数 一、题目链接二、题目三、题目解析四、算法原理五、编写代码六、时空复杂度 一、题目链接 将 x 减到 0 的最小操作数 二、题目 三、题目解析 以示例1为例&#xff1a; 四、算法原理 像"题目解析"中正面删除并修改数组元素的操作太困难&…...

电机试验平台:创新科技推动电动机研究发展

电机试验平台是电机制造和研发过程中不可或缺的重要设备&#xff0c;其功能涵盖了电机性能测试、电机寿命测试、电机质量评估等多个方面。随着科技的不断发展和电机应用领域的日益扩大&#xff0c;对电机试验平台的要求也越来越高。本文将从现代化电机试验平台的设计与应用两个…...

linux-软件的安装与部署、web应用部署到阿里云

一、软件安装方式概述 CentOS安装软件的方式主要包括&#xff1a; - 源码安装 - rpm安装&#xff08;二进制安装&#xff09; - yum安装&#xff08;在线安装&#xff09; 1.源码安装&#xff1a; 源码包是指C等语言所开发的源代码文件的一个压缩包&#xff0c;通常压缩为.…...

Qt Widgets模块功能详细说明,基本控件:QLabel(一)

一、基本控件&#xff08;Widgets&#xff09; Qt 提供了丰富的基本控件&#xff0c;如按钮、标签、文本框、复选框、单选按钮、列表框、组合框、菜单、工具栏等。 1、QLabel 1.1、概述 (用途、继承关系) QLabel 是 Qt 框架中用于显示文本、图像或动画的控件&#xff0c;属…...

Ubuntu 安装 squid

1. 安装Squid及工具 Debian/Ubuntu sudo apt update sudo apt install squid apache2-utils CentOS/RHEL sudo yum install squid httpd-tools 2. 创建用户名密码文件 创建密码文件&#xff08;首次使用 -c 参数&#xff0c;后续添加用户省略&#xff09; sudo htpasswd…...

中药药效成分群的合成生物学研究进展-文献精读130

Advances in synthetic biology for producing potent pharmaceutical ingredients of traditional Chinese medicine 中药药效成分群的合成生物学研究进展 摘要 中药是中华民族的文化瑰宝&#xff0c;也是我国在新药创制领域的重要驱动力。许多中药材来源于稀缺物种&#xf…...

芯片生态链深度解析(三):芯片设计篇——数字文明的造物主战争

【开篇&#xff1a;设计——数字文明的“造物主战场”】 当英伟达的H100芯片以576TB/s显存带宽重构AI算力边界&#xff0c;当阿里平头哥倚天710以RISC-V架构实现性能对标ARM的突破&#xff0c;这场围绕芯片设计的全球竞赛早已超越技术本身&#xff0c;成为算法、架构与生态标准…...

Echart地图数据源获取

DataV.GeoAtlas地理小工具系列 选择需要的区域地图,选中后输出即可: 地图钻取代码 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>map</title><style>html, body, #map{margin: 0;…...

【C++ - 仿mudou库one thread one loop式高并发服务器实现】

文章目录 项目介绍项目模块和服务器主要设计模式项目主要流程前置知识1.bind函数2.定时器任务TimerTask和时间轮思想TimerWheel3.正则表达式4.通用型容器Any类 服务器设计模式1&#xff09;单Reactor单线程模式2&#xff09;单Reactor多线程模式3&#xff09;多Reactor多线程模…...