二进制数学

本文最后更新于 2022年2月25日 中午

咳咳,由于打比赛老是基础不牢,地动山摇,故开此篇以文字形式记录下,把二进制牢牢的记住!

第一个问题:计算机是如何存储数字的?

答:

首先是整数:

计算机中所有的整数都是以补码的形式存储的。整数的补吗就是它本身,负数的补码是它除了符号位的位数取反(这样做生成的叫反码)加一。

使用补码,可以将符号和数值统一处理,加法和减法也可以统一处理(CPU 只有加法器)

其余知识点,如浮点数表示等参考别人的资料,知道这点就很关键。

第二个知识点:【内存】中数据的存储(更新了十六进制数大小端存储)

十六进制和整型数据的存储

计算机中,二进制数可以转为十六进制数,一个十六进制数相当于 4 个 2 进制,也就是 4 个 bit,两个十六进制数为一个字节

大端:数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中

小端:数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中,内存储存即是小端序

在 pwn 中,内存一个地址即是以小端序存储的 unsigned int64 数字,在进行程序的输入时,伪造地址需要自行以字节码的形式将对应内存改成以数字形式存储在该处的样子(十六进制小端序,C 语言认可十六进制),输入顺序是从低地址到高地址。

由于是伪造,正常逻辑是输入可见的 ASCII 码字符,伪造逻辑不考虑这个,只考虑数字的内存形式,输入十六进制小端序形式的字节字符串数据即可伪造好地址!

例子:

1
2
3
4
5
6
7
8
9
int a = 0x123;
//在内存中,int类型有4个字节,2个二进制数为一个字节
//所以有8个十六进制进制数
//补齐0是 0x 00 00 01 23
// 数据高位-------------数据低位
// 内存中:
// 大端 00 00 01 23
// 小端 23 01 00 00
// 低地址-----------------高地址
1
2
3
4
5
6
7
8
9
10
11
from pwn import *

# p8 ubyte format requires 0 <= number <= 255
In [7]: p8(0x10)
Out[7]: b'\x10'

In [8]: p8(16)
Out[8]: b'\x10'

In [16]: p32(0x8048799)
Out[16]: b'\x99\x87\x04\x08'

第三个知识点 数字操作(python 实现)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# number & 0xff 意思是获取后两位十六进制,即一个字节
In [32]: 123222 & 0xff
Out[32]: 86

In [33]: hex(123222)
Out[33]: '0x1e156'

# number >> 8 意思是右移8位二进制,即去末尾一个字节
In [37]: 0x1e156 >> 8
Out[37]: 481

In [38]: hex(481)
Out[38]: '0x1e1'

# number << 8 意思是左移8位二进制,即从左往右添8个0
In [39]: 1 << 8
Out[39]: 256

python 原生实现数字转字节:

1
2
3
4
5
6
7
# 整数.to_bytes(字节长度,字节顺序,*字节符号)
In [67]: (230).to_bytes(1,'little',signed=False)
Out[67]: b'\xe6'

# 字节转数字,负数是补码
In [70]: int.from_bytes(b'\xfc\x00',byteorder='big',signed=True)
Out[70]: -1024

泄露的内存数,转换为数字:

1
2
3
4
5
6
7
8
9
10
11
In [4]: u32(b'\x23\x01\x00\x00')
Out[4]: 291

In [6]: 0x123
Out[6]: 291

In [14]: u32(b'\x12\x31\x23\x13')
Out[14]: 321073426

In [15]: 0x13233112
Out[15]: 321073426
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# %256 求余256 得到这个数的低8位
In [1]: 0x7fff7 % 256
Out[1]: 247

In [2]: hex(247)
Out[2]: '0xf7'

# /256 除以256 左移位8bit
In [10]: 0x7fff7 / 256
Out[10]: 2047.96484375

In [11]: int(0x7fff7 / 256)
Out[11]: 2047

In [12]: hex(2047)
Out[12]: '0x7ff'

二进制数学
https://k3ppf0r.github.io/2022/02/04/基础/二进制数学/
作者
k3ppf0r
发布于
2022年2月4日
许可协议