【安全学习之路】Day47

最近做一些crackme,感觉对内存里面程序数据的存储不是很熟练,再学学二进制方面的东西

C++二进制

编码规则

8位
S DDDDDDD
符号位 数据位
CPU擅长位运算和加运算
而乘法,将乘数拆开

将乘运算变成了位运算和加运算

除法中
A/C=A(1/C)=A(2N/C)*(1/2N)

乘以2^N分之一,也就是右移N位
其中关键的只剩(2^N/C)这个值是多少
而所有C都被分解为质数,也就是只要将

以此类推的值存在计算机里面。
而有多少个以此类推的值? 开根N就行了,因为C开质数最多到根号C,


减法问题
现在只有加法和位运算
假设AB都是单字节,即00到ff

将A-B变成A+(100-B)-100
这里的100其实是100h。
为什么要100h呢,现在A和B都是十六进制00到ff,那100h是有进位的,换而言之是A和B都到达不了的
这里引入二进制位的概念,B加B反等于ff。
而ff+1就是100h了。
所以B+B反+1=100h
能够换出来一个100h-B
以位运算B反和B的相加和1相加来抵消掉减法,然后后面那个-100h,其实是进位抵消,意思是之前在正和反相加的情况下,必然会进位,且进位只进1,所以-100h,只要看成抹掉进位就行了。
(100-B)这个也就是求补,是一种运算,为neg

在求负数补码的时候,只要写出正的码,求反然后加一就可以了。
在遇到需要推算,例如0x86时
1 0000110
可以看到首位为1,负数
后面的是经过求反加一来的,退回来就是-1求反
也就是
0 0000101
0 1111010
-7A
这就是换算出来的结果
。例外0x80
1 0000000
以此为例都是负数的极小值
-128
-32768
......

在小数的时候

比较好理解。
然后在二进制里面的0.1是2^-1,为0.5。
以此类推0.01 0.25
0.001 0.125
我们本来有一个 0.625十进制
换算到二进制里面其实就是0.125+0.5
为0.101。

第二种,乘2法

第一次乘2,整数位没有1,记0
第二次,整数位有1,记1。以此类推

可以看到小数经常遇到精度的问题

因此常常通过确认精度来舍弃一些位置,来确认到自己输入的数是想要的结果。


现在计算机里面小数的存放规则
S EEEEEEEE DDDDDDDDDDDDDDDDDDDDDDD
共32位
符号位 移位标记位 数据位
比如23.625
换算成二进制
10111.101
变成1.0111101 *10^4
这里的4就是移位标记的东西,但是有些时候是左移,有些时候右移
则本来0......最大值
变成 负二分之一最大值.......0.......二分之一最大值

我们这里的10^4,这个4变成最大值-1+4。
也就是最大值 --- 10000 +3
所以这里面变成了
S EEEEEEEE DDDDDDDDDDDDDDDDDDDDDDD
0 10000011 DDDDDDDDDDDDDDDDDDDDDDD
之后的D部分变成了去掉最高位的其他部分0111101
0 10000011 01111010000000000000000
其他位置补0
然后因为小端序存储
0100 0001 1011 1101 0000 0000 0000 0000
4 1 B D 0 0 0 0
就是00 00 BD 41

本文作者:Corax0o0

本文链接:https://www.cnblogs.com/Corax0o0/p/17788497.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Corax0o0  阅读(11)  评论(0编辑  收藏  举报
   
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.