简介:集训Day4,复习前天汇编知识,对系统栈有更进一步了解
小端序标记法
字节序
程序的运行都会放在内存中,在计算机内存中或网络传输时的储存数据的方式的使用字节序(Byte Ordering)
其中分为
- 小端序
- 大端序
例子
1 | BYTE b = 0x12; |
注:char类型1字节,int类型4字节……
TYPE | Name | SIZE | 大端序类型 | 小端序类型 |
---|---|---|---|---|
BYTE | b | 1 | [12] | [12] |
WORD | w | 2 | [12][34] | [34][12] |
DWORD | dw | 4 | [12][34][56][78] | [78][56][34][12] |
char | str | 5 | [61][62][64][65][00] | [61][62][63][64][65][00] |
这里要注意char型的大端序类型与小端序类型一致是因为char类型的大小就是1字节
对于一个字符串来说,最后一个字节会存[0][0]代表字符串的结束标志
通过上面的例子,可得出定义,其储存数据的方式是高位在地址的高端,低位在地址的低端
大端序与小端序
小端序:逆序方式储存,进行算术运算以及对数据进行拓展/缩小时效率高
大端序:直观,常用于大型UNIX服务器的RISC系列的CPU中,此外,也用于网络协议中
OD查看小端序
就在下方的内存区中,可以很直观得去看
栈
栈的作用
- 暂时保存函数内的局部变量
- 调用函数时传递参数
- 保存函数返回后的地址
栈的特征
- 先进后出
- 逆向拓展
调试SWAP
使用VS可以用F10逐过程调试,F11逐语句调试,这里调试一个很简单的SWAP函数,对计算机如何运行程序有了更深入的了解
代码如下
1 | #include <stdio.h> |
图1
在监视1窗口下可以自己添加需要监视的值,这里我添加了a,b,temp的地址,因为还没调用swap函数,所以现在temp的值不存在。
如图所示
a的地址的值是0x00bff82c,a的值在{}中,为1
b的地址的值是0x00bff820,b的值在{}中,为0
栈的情况:(可能会有错误,待修正)
定义了整形a,b 就先将a,b压栈
然后再调用swap函数之前,还会将&a,&b压栈
栈 | 值 |
---|---|
a | 1 |
b | 0 |
&b | 0x00bff820 |
&a | 0x00bff82c |
图2
随后单步执行,进入函数内部,这里我没写好,swap函数的形参与实参同名了,当然两者不是一回事。我在这里假设,swap函数中的a是aa,b是bb
如图所示
aa的地址的值是0x00bff748,aa的值是a的地址的值,也就是0x00bff82c
bb同理
temp为int类型变量,初始没有赋值,其地址的值为0x00bff738
在该函数中,所进行的操作为
- 将aa的值,也就是a的值赋给temp变量
- 将bb的值,也就是b的值赋给aa,这样aa的值就不是a的值而是b的值
- 把temp的值赋给bb,bb的值变为a的值
栈的情况:
定义了整形temp,temp压栈
下面一系列运算,会将栈中的数据取出放入寄存器中进行运算
栈 | 值 |
---|---|
a | 1 |
b | 0 |
&b | 0x00bff820 |
&a | 0x00bff82c |
temp | 1 |
图3
如图,经过swap函数
原本0x00bff82c{1}变为0x00bff82c{0}
原本0x00bff820{0}变为0x00bff820{1}
SWAP汇编代码分析
懒得再OD里打开了,直接用VS看吧
右键-反汇编-看到其汇编代码
1 | int main() |
对于汇编代码的分析就直接在后面注释了(只写了看得懂的-_-b)
参考资料
逆向工程核心原理第三、四、五章