当前位置:网站首页>sscanf 导致地址越界
sscanf 导致地址越界
2022-07-27 18:32:00 【Li-Yongjun】
问题
test.c
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int a = 100;
uint8_t b;
sscanf("0x15", "0x%x", &b);
printf("a = 0x%x\n", a);
printf("b = 0x%x\n", b);
return EXIT_SUCCESS;
}
$ ./test.out
a = 0x0
b = 0x15
a 的值为什么变成 0 了呢?
解答
因为 sscanf 在给 b 赋值时,由于指定的参数格式是 %x,所以 sscanf 认为 b 是一个 unsigned int 类型,所以把 &b 转换成了 unsigned int * 类型,这样在给 b 赋值时,就是按照 unsigned int 这么大空间进行赋值,结果就操作了别的变量的内存,导致程序出问题。
下图 a) 是我们期望的样子,可是由于 “%x”,导致 &b “管控”的空间从一个字节扩大到了四个字节,“侵占”了变量 a 的空间,如图 b),导致 a 的值被篡改。
避免
其实在编译时,编译器就已经发出了警告。所以我们在编写代码时,要时刻留意编译器报的警告,能够帮助我们纠正不少失误。
因此,提交代码的一个原则就是:尽量不引入新的警告。
$ gcc test.c -o test.out
test.c: In function ‘main’:
test.c:10:21: warning: format ‘%x’ expects argument of type ‘unsigned int *’, but argument 3 has type ‘uint8_t *’ {
aka ‘unsigned char *’} [-Wformat=]
10 | sscanf("0x15", "0x%x", &b);
| ~^ ~~
| | |
| | uint8_t * {
aka unsigned char *}
| unsigned int *
| %hhx
推荐写法
方法一:使用"%hhx"
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int a = 100;
uint8_t b;
sscanf("0x15", "0x%hhx", &b);
printf("a = 0x%x\n", a);
printf("b = 0x%x\n", b);
return EXIT_SUCCESS;
}
$ ./test.out
a = 0x64
b = 0x15
方法二:使用 int 类型中间变量进行转储。
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int a = 100;
uint8_t b;
int c;
sscanf("0x15", "0x%x", &c);
b = (uint8_t)c;
printf("a = 0x%x\n", a);
printf("b = 0x%x\n", b);
return EXIT_SUCCESS;
}
$ ./test.out
a = 0x64
b = 0x15
边栏推荐
- Global styles and icons
- 【深度学习】Pytorch Tensor 张量
- Kingbasees heterogeneous database migration guide (3. Kingbasees migration capability support system)
- Tencent jumped out with 38K and saw the real test ceiling
- 14天鸿蒙设备开发实战-第七章 设备联网上云 学习笔记
- 【Dart】一门为跨端开发而生的编程语言
- 关于栈迁移的那些事儿
- [deep learning] pytoch tensor
- Force deduction solution summary 592 fraction addition and subtraction
- Innovative cases | the growth strategy of digitalization of local life services and upgrading of Gaode brand
猜你喜欢

Uncaught SyntaxError: redeclaration of let page

Introduction to source insight 4.0

最新版web漏洞扫描工具AppScan\AWVS\Xray安装及使用教程

After working for bytek for two years, he got 15 offers at one go

程序中的地址如何转换?

IOU 目标跟踪其一:IOU Tracker

The variable "lattice" or class "lattice.latticeeasy" (matlab) is not defined

Arduino development (II)_ RGB light control method based on Arduino uno development board

全局样式与图标

自动化测试----unittest框架
随机推荐
Hexagon_V65_Programmers_Reference_Manual(7)
【Dart】一门为跨端开发而生的编程语言
VI working mode (3 kinds) and mode switching (conversion)
Ue5 uses DLSS (super sampling) to improve the FPS of the scene away from the optimization scheme of Caton
品牌列表案例
好开不贵,舒适安全!深度体验比亚迪宋Pro DM-i
sql编码bug
JVs basic framework function list
原生对象、内置对象、宿主对象的区别
R语言dplyr包进行数据分组聚合统计变换(Aggregating transforms)、计算dataframe数据的分组加和值(sum)
NATAPP内网穿透工具外网访问个人项目
vant组件库
Things about stack migration
MySQL basic queries and operators
Do you know about data synchronization?
最新版web漏洞扫描工具AppScan\AWVS\Xray安装及使用教程
JVs official account login configuration
基于文件上传漏洞获得网站 shell 权限
程序中的地址如何转换?
搭建discuz论坛并攻破盗取数据库