安全拷贝函数safe_memcpy实现分析
创作时间:
作者:
@小白创作中心
安全拷贝函数safe_memcpy实现分析
引用
CSDN
1.
https://blog.csdn.net/wangzhicheng1983/article/details/117366294
memcpy是C语言中常用的内存拷贝函数,但其存在缓冲区溢出和重叠拷贝等安全风险。本文将分析memcpy的缺陷,并介绍一个更安全的内存拷贝函数safe_memcpy的实现原理和使用方法。
一、memcpy缺陷分析
- memcpy原型:
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
// 函数返回dest指针
- 缺陷分析:
(1)memcpy容易发生缓冲区溢出,如果dest长度小于待拷贝的字节数n,那么程序将发生缓冲区溢出;
(2)如果dest是高地址,src是低地址,拷贝可能发生错误,即源地址和目的地址重合部分在拷贝时被修改。
综上所述:memcpy参数较为简单,没有对程序安全性做进一步限制,将导致某些致命错误。
二、safe_memcpy实现分析
- 原型:
bool safe_memcpy(void *dst, const void *src, size_t len, const void *start, const void *end);
// dst指向目的地址
// src指向源地址
// len是待拷贝的字节数
// start指向目的地址开始地址
// end指向目的地址结束地址 即最后一个元素的后一个地址
- 实现分析:
safe_memcpy.hpp
#pragma once
#include <stdint.h>
#include <string.h>
static inline bool between(const uint8_t *start, const uint8_t *end, const uint8_t *p) {
return (p < end) && (p >= start); // 注意是p < end不是p <= end
}
static inline bool safe_check(void *dst, size_t len, const void *start, const void *end) {
if (len < 1) {
return false;
}
if (!dst || !start || !end) {
return false;
}
void *last_pos = ((uint8_t *)dst) + len - 1;
if (last_pos < dst) { // last_pos不能小于dst
return false;
}
return between((uint8_t *)start, (uint8_t *)end, (uint8_t *)dst) && // dst在start与end之间
between((uint8_t *)start, (uint8_t *)end, (uint8_t *)last_pos); // last_pos即待拷贝区间最后元素地址也必须在start与end之间
}
static inline bool safe_memcpy(void *dst, const void *src, size_t len, const void *start, const void *end) {
if (!safe_check(dst, len, start, end)) {
return false;
}
if (!src) {
return false;
}
memcpy(dst, src, len);
return true;
}
(1)解决缓冲区溢出问题:调用safe_memcpy需要指定目的地址的开始和结束地址,safe_memcpy会检查目标空间是否能够容纳待拷贝字节数;
(2)解决低地址向高地址拷贝错误:如果源地址和目的地址部分区间重叠,通过指定start和end,safe_memcpy使用between((uint8_t *)start, (uint8_t *)end, (uint8_t *)last_pos)可以进行安全性判断。
- 测试:
test.cpp
#include <iostream>
#include "safe_memcpy.hpp"
int main() {
char src[64] = "123";
char dst[64] = "";
safe_memcpy(dst, src, strlen(src), dst, dst + 64);
std::cout << dst << std::endl;
return 0;
}
热门推荐
证人证言的游戏文案高级:法律领域的精深探索
中储粮和中储的关系是怎样的?这种关系对相关行业有哪些影响?
中国篮球已跌入谷底 世界篮球的潮流 中国篮球需要做出哪些改变?
2024年城市排行榜出炉!乌鲁木齐位列三线城市第一名
孩子学美术的十大好处汇总,画画特长班锻炼内容可不少
强制执行多久查询一次财产
数据中心中的FPGA硬件加速器
吃辣真的会伤胃?适量吃辣是关键
你的颈椎还好吗?这4种方法在家就能自测颈椎病,转发分享给家人
如何在杭州办理退休手续?办理杭州退休手续需要准备哪些材料?
什么是股票股息及其对投资者的意义?股票股息的分配方式有哪些特点?
PMP项目管理资格认证:全球通行的项目管理专业资质
国家药监局发布“十大用药提示”,这些用药误区你中招了吗?
易经中的枭神是什么意思
CMA、CPA、ACCA和CFA四大证书的区别,到底该如何选择?
笔记本电脑漏电怎么办?专业排查与解决方案
撰写具有竞争力的留学申请推荐信:技巧与策略
国考笔试成绩与最终分数计算方法详解:2024版国考分数计算攻略
深入探究三教文化:儒、佛、道的融合与发展对人类文明的重要意义
投诉单位少交公积金需要什么证明?
晚上咳嗽睡不着怎么办?这些方法帮你缓解咳嗽,改善睡眠
社保退休金算法是怎样的?职工办退休需要什么手续?
股票进阶分析-21日均线卖出法
解读香港开户政策:大陆居民在香港开账户之合法与限制
协商退房:与开发商沟通的关键步骤
Android存储文件路径详解
王熙凤为什么不听从秦可卿的建议去拯救贾府?
鲍鱼、鱼翅、燕窝、海参,真的大补吗?看过这篇,帮你省钱
人民法院会发送验证码以增强安全性,确保身份验证准确无误。
文玩玉竹:寓意、文化内涵与收藏价值全方位解析