Windows逆向工程入门之指针类型
- 公开视频 -> 链接点击跳转公开课程
- 博客首页 -> 链接点击跳转博客主页
目录
1. 指针特性
1.1 指针的优点
1.2 指针的缺点
2. 智能指针
2.1 智能指针的优点
2.2 智能指针的缺点
3. 指针的安全攻防
3.1 指针使用
3.2 指针运算
3.3 指针引用
3.4 参数传递
3.5 多级指针
3.6 指针数组
3.7 数组指针
3.8 函数指针
5. 逆向工程中的指针分析
6. 拓展知识点
6.1 指针与内存布局
1. 指针特性
1.1 指针的优点
- 灵活性:
- 指针可以动态分配和管理内存,提供了更高的灵活性。
- 通过指针,可以实现数据的共享和动态扩展。
- 高效性:
- 使用指针传递参数可以避免数据的复制,节省内存空间并提高效率。
- 指针操作直接作用于内存地址,速度更快。
1.2 指针的缺点
- 安全性:
- 指针的误用容易导致内存泄漏、悬挂指针(指向已释放的内存)和野指针(指向未分配的内存)。
- 复杂性:
- 大量使用指针会增加代码的复杂性,容易出错。
- 维护性:
- 指针操作使代码的可读性下降,维护困难。
2. 智能指针
2.1 智能指针的优点
-
自动化:
- 智能指针在脱离作用域时会自动释放内存,避免内存泄漏。
- 常见的智能指针包括
std::unique_ptr、std::shared_ptr和std::weak_ptr。
-
安全性:
- 智能指针通过引用计数和自动管理内存,避免了悬挂指针和野指针的问题。
2.2 智能指针的缺点
- 性能开销:
- 智能指针的实现需要额外的引用计数和内存管理逻辑,相比普通指针开销更大。
- 复杂性:
- 智能指针的使用需要遵循一定的规则,如避免循环引用。
3. 指针的安全攻防
在逆向工程中,指针的操作是分析程序行为的重要线索,同时也是漏洞攻击的关键点。以下是指针的常见操作及其在逆向工程中的表现。
3.1 指针使用
指针的声明和初始化:
int a = 10; int* ptr = &a; // 指针ptr指向变量a的地址
在汇编中表现为:
mov eax, dword ptr [ebp-4] ; 取变量a的地址
mov dword ptr [ebp-8], eax ; 将地址存储到指针ptr
3.2 指针运算
指针支持算术运算,例如:
int arr[] = {1, 2, 3, 4, 5};
int* ptr = arr; // 指向数组首地址
ptr++; // 指针移动到下一个元素
在汇编中表现为:
mov eax, dword ptr [ebp-8] ; 取指针值
add eax, 4 ; 指针移动4字节(sizeof(int))
mov dword ptr [ebp-8], eax ; 更新指针值
3.3 指针引用
通过指针访问和修改变量:
*ptr = 20; // 修改ptr指向的地址的值
在汇编中表现为:
mov eax, dword ptr [ebp-8] ; 取指针值
mov dword ptr [eax], 20 ; 修改指针指向地址的值
3.4 参数传递
指针可以作为函数参数,用于传递数据地址。例如:
void Fun(int* ptr) { *ptr = 20; }
在汇编中表现为:
mov eax, dword ptr [ebp+8] ; 获取函数参数(指针)
mov dword ptr [eax], 20 ; 修改指针指向的值
3.5 多级指针
多级指针是指向指针的指针。例如:
int a = 10; int* ptr1 = &a;
int** ptr2 = &ptr1;
在汇编中表现为:
lea eax, dword ptr [ebp-4] ; 取ptr1的地址
mov dword ptr [ebp-8], eax ; 将地址存储到ptr2
3.6 指针数组
指针数组是存储指针的数组。例如:
const char* strArr[] = {"Hello", "World"};
在汇编中表现为:
mov dword ptr [ebp-10], offset Hello
mov dword ptr [ebp-0C], offset World
3.7 数组指针
数组指针是指向数组的指针。例如:
int arr[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; int (*parr)[3] = arr; // 指向二维数组
在汇编中表现为:
mov eax, offset arr ; 取数组首地址
mov dword ptr [ebp-4], eax ; 存储到数组指针
3.8 函数指针
函数指针用于存储函数的地址。例如:
int Add(int a, int b) { return a + b; } int (*pFun)(int, int) = Add; int result = pFun(1, 2);
在汇编中表现为:
mov eax, offset Add ; 取函数地址
mov dword ptr [ebp-4], eax ; 存储到函数指针
call dword ptr [ebp-4] ; 调用函数指针
#include <iostream>void Fun1(int* a)
{//mov eax, dword ptr[a]//mov dword ptr[eax], 2*a = 2;printf("Fun1 -> a -> %d \r\n", *a);a = NULL;
}void Fun2(int& a)
{//mov eax, dword ptr[a]//mov dword ptr[eax], 3a = 3;printf("Fun2 -> a -> %d \r\n", a);a = NULL;
}int* Fun3()
{// 禁止返回局部变量的指针或引用// malloc// new// virtualalloc//int a = 1;//return &a;return NULL;
}int Add(int num1, int num2)
{int ret = num1 + num2;return ret;
}int aaaaaaa;int main()
{aaaaaaa = 1;/*segment regcs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000段选择子RPL 2 请求特权级别TI 1 查询寄存器 0 - GDTR / 1 - LDTRINDEXcs=0008 0000 0000 0000 1000RPL 00 TI 0 INDEX 0000 0000 0000 1 00cf9b00`0000ffffss=0010 0000 0000 0001 0000RPL 00TI 0 INDEX 0000 0000 0001 000cf9300`0000ffff0: kd> reax=00000001 ebx=aa173600 ecx=aa173600 edx=00000031 esi=81a4c060 edi=926d1428eip=81945dc4 esp=aa1735f8 ebp=aa1736d0 iopl=0 nv up ei pl zr na pe nccs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246nt!RtlpBreakWithStatusInstruction:81945dc4 cc int 30: kd> r ldtrldtr=000000000: kd> r gdtrgdtr=80d0a0000: kd> dq 80d0a000ReadVirtual: 80d0a000 not properly sign extended80d0a000 00000000`00000000 00cf9b00`0000ffff80d0a010 00cf9300`0000ffff 00cffb00`0000ffff80d0a020 00cff300`0000ffff 80008bd0`700020ab80d0a030 804093d0`c0004a60 0040f300`00000fff80d0a040 0000f200`0400ffff 00000000`0000000080d0a050 810089a5`00600068 810089a5`00c8006880d0a060 00cff200`0000ffff 00000000`0000000080d0a070 800092d0`a00003ff 00000000`000000000: kd> dg csP Si Gr Pr LoSel Base Limit Type l ze an es ng Flags---- -------- -------- ---------- - -- -- -- -- --------0008 00000000 ffffffff Code RE Ac 0 Bg Pg P Nl 00000c9b0: kd> dg ssP Si Gr Pr LoSel Base Limit Type l ze an es ng Flags---- -------- -------- ---------- - -- -- -- -- --------0010 00000000 ffffffff Data RW Ac 0 Bg Pg P Nl 00000c930: kd> dg fsP Si Gr Pr LoSel Base Limit Type l ze an es ng Flags---- -------- -------- ---------- - -- -- -- -- --------0030 80d0c000 00004a60 Data RW Ac 0 Bg By P Nl 00000493*/ __asm{mov eax, dword ptr ds:[0x400000] // ds.Base + 0x400000mov eax, dword ptr fs:[0] // fs.Base(80d0c000) + 0x0xor eax, eax}/*指针 - 引用指针变量也是变量的一种 - 通常用于存储变量的内存地址数据类型 变量名 = 初始值;数据类型* 变量名 = 初始值;空指针int* ptr = NULL;int* ptr = nullptr;指向变量的指针int a = 1;int b = 2;int* ptr = &a;解引用ptr = b;*ptr = b;指针运算int arr[] = {1, 2, 3};int* ptr = arr;ptr[2];ptr++;多级指针int* ptr1;int** ptr11;int*** ptr111;函数指针CALL*/int num1 = NULL;int num2 = NULL;// 空指针int* ptr1 = NULL;int* ptr2 = nullptr;/*005E443F C7 45 F4 00 00 00 00 mov dword ptr [ebp-0Ch],0005E4446 C7 45 E8 00 00 00 00 mov dword ptr [ebp-18h],0005E444D C7 45 DC 00 00 00 00 mov dword ptr [ebp-24h],0005E4454 C7 45 D0 00 00 00 00 mov dword ptr [ebp-30h],0*/// 指向变量的指针ptr1 = &num1;ptr2 = &num2;/*005E445B 8D 45 F4 lea eax,[ebp-0Ch]005E445E 89 45 DC mov dword ptr [ebp-24h],eax005E4461 8D 45 E8 lea eax,[ebp-18h]005E4464 89 45 D0 mov dword ptr [ebp-30h],eaxptr20x0113F884 9c f8 13 01 ??..ptr10x0113F890 a8 f8 13 01 ??..num20x0113F89C 00 00 00 00 ....num10x0113F8A8 00 00 00 00 ....*/// 解引用*ptr1 = 1;*ptr2 = 2;/*003A4467 8B 45 DC mov eax,dword ptr [ebp-24h] 003A446A C7 00 01 00 00 00 mov dword ptr [eax],1 003A4470 8B 45 D0 mov eax,dword ptr [ebp-30h] 003A4473 C7 00 02 00 00 00 mov dword ptr [eax],2*/// 指针运算//printf("%d \r\n", sizeof(char)); -1//printf("%d \r\n", sizeof(short)); -2//printf("%d \r\n", sizeof(int)); -4//printf("%d \r\n", sizeof(long)); -4//printf("%d \r\n", sizeof(long long)); -8//printf("%d \r\n", sizeof(char*)); -4//printf("%d \r\n", sizeof(short*)); -4//printf("%d \r\n", sizeof(int*)); -4//printf("%d \r\n", sizeof(long*)); -4//printf("%d \r\n", sizeof(long long*)); -4int arr[] = { 1,2,3,4,5 };int* ptr3 = arr;ptr3++;ptr3 = ptr3 + 4;//srand(time(NULL));////for (size_t i = 0; i < 50; i++)//{// if (i % 10 == 0)// {// printf("\r\n");// }//// printf("0x%02x, ", rand() % 50 + 1);//}// 0x2d082e30char arrp[] ={0x16, 0x2b, 0x04, 0x17, 0x2e, 0x19, 0x15, 0x2d, 0x08, 0x2e,0x30, 0x0e, 0x25, 0x23, 0x1b, 0x01, 0x0f, 0x09, 0x05, 0x24,0x1b, 0x26, 0x16, 0x28, 0x2b, 0x32, 0x1a, 0x0c, 0x1a, 0x0c,0x2e, 0x30, 0x2f, 0x1c, 0x02, 0x1c, 0x19, 0x0c, 0x17, 0x16,0x06, 0x0e, 0x31, 0x06, 0x09, 0x0b, 0x1a, 0x09, 0x0f, 0x26,};char* arrp1 = arrp;*(arrp1 + 2) = 1;arrp1[2] = 2;short* arrp2 = (short*)arrp;*(arrp2 + 2) = 1;arrp2[2] = 2;int* arrp3 = (int*)arrp;*(arrp3 + 2) = 1;arrp3[2] = 2;/*指针占用内存大小为x86 - 4Bytex64 - 8Bytechar* ptr1 = arr;ptr1++; // ptr1 = ptr1 + (sizeof(char) * 1);short* ptr2 = arr;ptr2++; // ptr2 = ptr2 + sizeof(short);int* ptr3 = arr;ptr3++; // ptr3 = ptr3 + sizeof(int);ptr3 = ptr3 + 4; // ptr3 = ptr3 + (sizeof(int) * 4);*/// 引用int a = 10;int b = 20;int& ref = a;ref = 2;int* p = &a;*p = 3;// 指针常量int* const p1 = &a;//p1 = &b;*p1 = 1;// 常量指针const int* p2 = &a;p2 = &b;//*p2 = 2;/*00465314 C7 45 9C 0A 00 00 00 mov dword ptr [a],0Ah 0046531B 8D 45 9C lea eax,[a] 0046531E 89 45 90 mov dword ptr [ref],eax 00465321 8B 45 90 mov eax,dword ptr [ref] 00465324 C7 00 02 00 00 00 mov dword ptr [eax],2 0046532A 8D 45 9C lea eax,[a] 0046532D 89 45 84 mov dword ptr [p],eax 00465330 8B 45 84 mov eax,dword ptr [p] 00465333 C7 00 03 00 00 00 mov dword ptr [eax],3 */// 参数传递a = 1;//mov eax, dword ptr[a]//push eaxprintf("main -> a -> %d \r\n", a);//lea eax, [a]//push eaxFun1(&a);printf("main -> a -> %d \r\n", a);//lea eax, [a]//push eaxFun2(a);printf("main -> a -> %d \r\n", a);// 多级指针int num_1 = 0xCC; int* ptr_1 = &num_1;int** ptr_2 = &ptr_1;int*** ptr_3 = &ptr_2;*ptr_1 = 0xFF;**ptr_2 = 0xCC;***ptr_3 = 0xAA;/*ptr_30x0019FE14 20 fe 19 00 ?..ptr_20x0019FE20 2c fe 19 00 ,?..ptr_10x0019FE2C 38 fe 19 00 8?..num_10x0019FE38 cc 00 00 00 ?...00411BE2 mov dword ptr [ebp+FFFFFF54h],0CCh00411BEC lea eax,[ebp+FFFFFF54h]00411BF2 mov dword ptr [ebp+FFFFFF48h],eax00411BF8 lea eax,[ebp+FFFFFF48h]00411BFE mov dword ptr [ebp+FFFFFF3Ch],eax00411C04 lea eax,[ebp+FFFFFF3Ch]00411C0A mov dword ptr [ebp+FFFFFF30h],eax00411C10 mov eax,dword ptr [ebp+FFFFFF48h]00411C16 mov dword ptr [eax],0FFh00411C1C mov eax,dword ptr [ebp+FFFFFF3Ch]00411C22 mov ecx,dword ptr [eax]00411C24 mov dword ptr [ecx],0CCh00411C2A mov eax,dword ptr [ebp+FFFFFF30h]00411C30 mov ecx,dword ptr [eax]00411C32 mov edx,dword ptr [ecx]00411C34 mov dword ptr [edx],0AAh*/// 指针数组const char* strArr[] = { "Hello", "World" };// 数组指针int Arr_int[3][3] ={{1,2,3},{4,5,6},{7,8,9},};int(*parr_int)[3] = Arr_int;parr_int[1][2] = 0xCC;/*00411E6A B8 0C 00 00 00 mov eax,0Ch 00411E6F C1 E0 00 shl eax,0 00411E72 03 85 88 FE FF FF add eax,dword ptr [parr_int] 00411E78 B9 04 00 00 00 mov ecx,4 00411E7D D1 E1 shl ecx,1 00411E7F C7 04 08 CC 00 00 00 mov dword ptr [eax+ecx],0CCh */*(*(parr_int + 1) + 2) = 0xAA;/*00411E86 8B 85 88 FE FF FF mov eax,dword ptr [parr_int]00411E8C C7 40 14 AA 00 00 00 mov dword ptr [eax+14h],0AAh*/// 函数指针int ret = Add(1, 2);/*00415DF3 6A 02 push 2 00415DF5 6A 01 push 1 00415DF7 E8 D3 B5 FF FF call Add (04113CFh) 00415DFC 83 C4 08 add esp,8 00415DFF 89 85 7C FE FF FF mov dword ptr [ret],eax CALL指令执行地址 00415DF7CALL指令返回地址 00415DFCCALL指令跳转地址 04113CFhCALL指令内存数据 E8 XX XX XX XXCALL指令内存数据 = CALL指令跳转地址 - CALL指令返回地址0FFFFB5D3h = 04113CFh - 00415DFChCALL指令跳转地址 = CALL指令内存数据 + CALL指令返回地址04113CFh = 0FFFFB5D3h + 00415DFChCALL指令执行地址 00401EC0CALL指令返回地址 00401EC5CALL指令跳转地址 00401E80CALL指令内存数据 FFFFFFBB*/int (*pFun)(int num1, int num2) = Add;ret = pFun(2, 2);/*00415E11 6A 02 push 2 00415E13 6A 02 push 2 00415E15 FF 95 70 FE FF FF call dword ptr [pFun] 00415E1B 83 C4 08 add esp,8 00415E25 89 85 7C FE FF FF mov dword ptr [ret],eax*/return 0;
}
5. 逆向工程中的指针分析
在逆向工程中,指针的使用是分析程序逻辑和定位漏洞的关键。以下是常见的分析场景:
-
动态内存分配:
- 分析
malloc、new、VirtualAlloc等内存分配函数的调用。 - 识别内存泄漏和未释放的指针。
- 分析
-
函数调用:
- 通过函数指针的调用,分析程序的动态行为。
- 识别虚函数表和多态行为。
-
漏洞利用:
- 分析指针越界、悬挂指针和野指针的使用场景。
- 识别栈溢出和堆溢出等安全漏洞。
6. 拓展知识点
6.1 指针与内存布局
-
指针的大小依赖于系统架构:
- 32位系统:指针大小为4字节。
- 64位系统:指针大小为8字节。
-
指针在内存中的存储:
- 指针本身存储在栈或堆中。
- 指针指向的内容存储在对应的内存区域(如全局区、栈区或堆区)。
相关文章:
Windows逆向工程入门之指针类型
公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 1. 指针特性 1.1 指针的优点 1.2 指针的缺点 2. 智能指针 2.1 智能指针的优点 2.2 智能指针的缺点 3. 指针的安全攻防 3.1 指针使用 3.2 指针运算 3.3 指针引用 3.4 参数传递 …...
PHP+Apache+MySQL安装(Windows)
一、安装教程 参考链接1 参考链接2 二、问题描述 PHP安装目录下找不到php8apache2_4.dll PHP安装包下载错误 Apache Service Monitor: request operation has failed! 定位问题: 查看【事件查看器】 解决问题 安装或更新与PHP版本相对应的Visual C Redistribu…...
算法基础 -- 堆排序之C语言实现
C语言实现堆排序(Heap Sort) 1. 代码实现 下面是 C语言实现的堆排序接口,支持 通用数据类型排序,并采用 函数指针 进行 自定义比较,适用于 整数排序 或 结构体排序。 完整代码 大根堆 #include <stdio.h> #…...
Hutool - Extra:功能丰富的扩展模块
一、简介 Hutool - Extra 作为 Hutool 工具包的扩展模块,对众多第三方库和功能进行了封装,极大地丰富了 Hutool 的功能体系。它涵盖了模板引擎、邮件发送、Servlet 处理、二维码生成、Emoji 处理、FTP 操作以及分词等多个方面,为开发者在不同…...
C++ 中的继承详解(上)
目录 1、继承的概念及定义 1.1、继承的概念 1.2、继承定义 1.2.1、定义格式 1.2.2、继承方式 1.2.3、继承基类成员访问方式的变化 2、基类和派生类对象赋值转换 3、继承中的作用域 4、派生类的默认成员函数 补充:封装的层次(实际上有很多层的,这…...
halcon三维点云数据处理(二十五)moments_object_model_3d
目录 一、moments_object_model_3d例程二、moments_object_model_3d函数三、效果图 一、moments_object_model_3d例程 这个例子说明了如何使用moments_object_model_3d运算符来将3D数据与x、y、z坐标轴对齐。在实际应用中,通过3D传感器获取的物体模型可能具有一个与…...
Mac M3/M4 本地部署Deepseek并集成vscode
Mac 部署 使用傻瓜集成平台ollama,ollama平台依赖于docker,Mac的M3/M4 因doesn’t have VT-X/AMD-v enabled 所以VB,VM无法使用,导致docker无法启动,需要使用docker的替代品podman, 它完全兼容docker brew install p…...
2024年职高单招或高考计算机类投档线
问题: 这些学校2024年职高单招或高考计算机类投档线分别是多少 回答: 部分学校2024年职高单招或高考计算机类投档线如下: 湖南工业职业技术学院 职高单招:未查询到2024年职高单招计算机类专业明确的录取分数线信息。但在2024年…...
Unity Excel导表工具转Lua文件
思路介绍 借助EPPlus读取Excel文件中的配置数据,根据指定的不同类型的数据配置规则来解析成对应的代码文本,将解析出的字符串内容写入到XXX.lua.txt文件中即可 EPPlus常用API //命名空间 using OfficeOpenXml;//Excel文件路径 var fileExcel new File…...
SpringBoot项目集成MinIO
最近在学习MinIO,所以想让自己的SpringBoot项目集成MinIO,在网上查阅资料,并进行操作的过程中遇到一些问题,所以想把自己遇到的坑和完成步骤记录下来供自己和各位查阅。 一. MinIO的下载安装以及基本使用 1. 下载地址:https://d…...
第30篇 基于ARM A9处理器用C语言实现中断<六>
Q:怎样设计基于ARM A9处理器的C语言程序在数码管上滚动显示字符? A:使用A9 Private Timer中断源,控制字符滚动的速度;按键产生中断可以控制字符暂停/继续滚动。 本实验在DE1-SoC开发板的6个七段数码管*HEX5~HEX0*上…...
Flutter 中的单例模式
传统: class RouterManager {// 单例模式static final RouterManager _instance RouterManager._internal();factory RouterManager() {return _instance;}RouterManager._internal(); }传递参数进行初始化时: class RouterManager {// 私有静态实例&a…...
8.python文件
文章目录 1.**文件**1.1**文件是什么**1.2**文件路径**1.3**文件操作**1.3.1**打开文件**1.3.2**关闭文件**1.3.3**写文件**1.3.4**读文件** 1.4**关于中文的处理**1.5**使用上下文管理器** 大家好,我是晓星航。今天为大家带来的是 python文件 相关的讲解࿰…...
2025vue4.x全栈学习关键技术分析线路图
关键升级点说明: 编译优化 :Vue 4.x采用WASM编译提速300% 智能工具链 :Vite插件市场新增AI代码审查模块 跨平台能力 :Uni-App支持原生ARCore/ARKit调用 安全增强 :默认启用WebAuthn生物认证…...
革新之力:数字科技——重塑未来的超越想象之旅
在21世纪的科技浪潮中,数字科技如同一股不可阻挡的洪流,正以前所未有的速度和广度改变着我们的生活、工作乃至整个社会的结构。它不仅是技术的简单迭代,更是对人类社会认知边界的拓宽,对经济模式、社会治理、文化形态等多方面的深…...
超级详细,知识图谱系统的理论详解+部署过程
知识图谱系统(Knowledge Graph System)是一种用于表示、存储、查询和推理知识的系统。它通过结构化的方式将现实世界中的实体、概念及其相互关系组织成一个图结构,从而帮助机器理解和处理复杂的知识。 知识图谱的核心组成部分 实体(Entities): 实体是知识图谱中的节点,…...
电路笔记 (信号): opa tips 放大器反馈电阻并联电容抑制高频噪声的详细推导(传递函数分析)
1. 高频噪声传递函数分析 (1)电路结构 输入信号通过 R 1 R_1 R1 和 C NI C_{\text{NI}} CNI 的并联组合连接到运放的同相输入端。反馈电阻 R 2 R_2 R2 连接在运放的输出端和反相输入端之间。 Layer 1 - 30p R2 R1 R3R1//R2 IN OUT 反向放大电…...
DeepSeek安装部署笔记(一)
Ollamaopen-WebUI部署 DeepSeek安装部署笔记第一步 Ollama安装1.安装ollama:官网https://ollama.com/下载2.上面安装完成,在cmd命令行: 第二步 给DeepSeek添加OpenWebUI界面(重点)1.安装conda:用它来管理py…...
【JavaEE进阶】Spring MVC(4)-图书管理系统案例
欢迎关注个人主页:逸狼 创造不易,可以点点赞吗 如有错误,欢迎指出~ 图书管理系统 创建书籍类BookInfo import lombok.Data;import java.math.BigDecimal;Data //这个类基本上是和数据库对应起来的 public class BookInfo {private Integer id…...
Ubuntu部署ktransformers
准备工作 一台服务器 CPU:500G GPU:48G(NVIDIA4090) 系统:Ubuntu20.04(github的文档好像用的是22.04) 第一步:下载权重文件 1.下载hfd wget https://hf-mirror.com/hfd/hfd.s…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
