一个%02X格式化输出引发的“血案”
来源:互联网 发布:windows player播放 编辑:程序博客网 时间:2024/04/30 11:27
今天在写一个PE文件解析器的时候,大致写了这样一段代码:
本以为0X88没有超出%02X的格式限制。输出应该是88,殊不知输出的结果是FFFFFF88。正当我百思不得其解时,我修改了一下宏定义那句:
#define BYTE unsigned char
结果发现输出按照88正常输出。经过查找资料和反汇编分析,我得到了正确的结论,分析如下:
①%X默认的输出宽度为整型的宽度,在32位编译器中即4字节。这点验证可查看反汇编(VC++6.0):定义时虽然是byte ptr [ebp-4]只占用栈中一个字节,但是在输出时要按照4字节输出,则先将其用movsx带符号扩展为四个字节再输出。而由于定义时是一个有符号数,那么88H即10001000,符号位为1,则补齐四字节时前面全部补全为1,带符号扩展得到FFFFFF88,输出也为FFFFFF88。
②当我将#define BYTE char修改为#define BYTE unsigned char时,虽然也是扩展,但由于是一个无符号数,符号位为0,前面全部补0即0X00000088,在以%02X输出时为88。反汇编如下(虽然没有用不带符号扩展指令,但是and eax,0XFF的效果是一样的,都将高为全部置为0):
总结:
①%X默认按照int的宽度输出,%lx默认按照long的宽度输出(32位编译器下二者无差别);而%默认llx则是按照long long的宽度输出。
②不足默认宽度的会被宽展为指定宽度,并且扩展时依据符号进行扩展。
③%0NX,如果要输出值的字符个数大于N则“0N”的修饰无用,不要误认为输出的值占的字符个数和N有必然联系。
④基础知识的细节很重要,但是调试技术的掌握更为重要。
- 一个%02X格式化输出引发的“血案”
- 一个 * 引发的血案
- 一个“-”引发的血案
- 一个"/"引发的血案
- 一个松果引发的血案
- 一个memset引发的血案
- 一个包子引发的血案?
- 一个斜杠引发的血案
- 一个逗号引发的"血案"
- 一个static 引发的“血案”
- 一个分号引发的血案
- 一个key引发的血案
- 一个变量引发的血案
- 一个return引发的血案
- 一个ViewSwitcher引发的血案!
- 一个分号引发的“血案”
- 一个static引发的血案
- 一个2803引发的血案
- 【Java多线程与并发库】03 传统线程互斥技术 synchronized
- Python爬虫——自制简单搜索引擎GUI版
- ionic纯html,js实现toast提示框
- Glide加载自定义大小图片在刷新时图片忽大忽小问题解决
- effective cpp24, 46需要类型转换时请为模板定义非成员函数
- 一个%02X格式化输出引发的“血案”
- 141. Linked List Cycle
- Leetcode-100: Same Tree
- C++11 之 公有继承
- 微信开发第一篇
- opencv3.0 截取任意形状封闭图形
- Linux 下hosts文件
- 算法题/找出数组中出现最多的数
- 从零实现一个高性能网络爬虫(一)网络请求分析及代码实现