返回信息流请教一下下面的代码:
//: C03:FloatingAsBinary.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
//{L} printBinary
//{T} 3.14159
#include "printBinary.h"
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
if(argc != 2) {
cout << "Must provide a number" << endl;
exit(1);
}
double d = atof(argv[1]);
unsigned char* cp =
reinterpret_cast<unsigned char*>(&d);
for(int i = sizeof(double); i > 0 ; i -= 2) {
printBinary(cp[i-1]);
printBinary(cp[i]);//假设double为8字节,cp[8]应该越界了吧?
}
} ///:~
这段代码里面,假设double占8个字节,那么指向这个内存的char指针+8之后,不应已经越界了?
但是书本里面却用这个代码来打印double的二进制表示。(Thinking in c++代码)
printBinary的定义如下:
//: C03:printBinary.cpp {O}
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
#include <iostream>
void printBinary(const unsigned char val) {
for(int i = 7; i >= 0; i--)
if(val & (1 << i))
std::cout << "1";
else
std::cout << "0";
} ///:~
这是一条镜像帖。来源:北邮人论坛 / cpp / #76973同步于 2014/2/16
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
[讨论]请教一个C++问题
wugh
2014/2/16镜像同步4 回复
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
//
double d = atof(argv[1]);
unsigned char* cp = reinterpret_cast<unsigned char*>(&d);
mov eax, [ebp+arg_4] ; argv[0]
add eax, 4 ; (char*) [+1]
mov eax, [eax] ; get argv[1]
mov [esp+20h+var_20], eax ; push parameter
call _atof
fstp [esp+20h+var_10] ; pull double result into [esp + 0x20 - 0x10]
lea eax, [esp+20h+var_10] ; get address
mov [esp+20h+var_4], eax ; reinterpret_cast, *cp
之后访存cp[]为栈内存访存~高危!可用于溢出攻击,溢出范围为整个运行栈!
例如:
printf("%d\n", cp[0x400]); // *(cp + 1024)
mov eax, [esp+20h+var_4] ; get cp[0]
add eax, 400h ; (char*) [+1024]
mov al, [eax] ; (char)
movzx eax, al ; (int)
mov [esp+20h+var_1C], eax ; push parameter
mov [esp+20h+var_20], offset d ; "%d\n"
call _printf
【 在 wugh 的大作中提到: 】
: 请教一下下面的代码:
: //: C03:FloatingAsBinary.cpp
: // From Thinking in C++, 2nd Edition
: ...................
确实有这个溢出的风险,但是我是想问一下上面那个代码能不能正确打印
double(假设8个字节,IEEE754标准表示)的二进制表示?
【 在 tonyjansan 的大作中提到: 】
: [code=c]
: //
: double d = atof(argv[1]);
: ...................
不能!
没仔细看你引用的printBinary实现,本身逐字节的遍历就不对:
逆序遍历的时候如你所指出的,首字节(0x0偏址,i = 0时跳出循环)未遍历到,多遍历了0x8偏址(i = sizeof(double),越界访问)。
【 在 wugh 的大作中提到: 】
: 确实有这个溢出的风险,但是我是想问一下上面那个代码能不能正确打印
: double(假设8个字节,IEEE754标准表示)的二进制表示?
好的,谢谢啦,
【 在 tonyjansan 的大作中提到: 】
: 不能!
: 没仔细看你引用的printBinary实现,本身逐字节的遍历就不对:
: 逆序遍历的时候如你所指出的,首字节(0x0偏址,i = 0时跳出循环)未遍历到,多遍历了0x8偏址(i = sizeof(double),越界访问)。
: ...................