意识流 拆弹 笔记 phase_0

08049462 <phase_0>:
 8049462:	55                   	push   %ebp
 8049463:	89 e5                	mov    %esp,%ebp
 8049465:	83 ec 08             	sub    $0x8,%esp
 8049468:	83 ec 08             	sub    $0x8,%esp
 804946b:	68 dc b1 04 08       	push   $0x804b1dc
 8049470:	ff 75 08             	pushl  0x8(%ebp)
 8049473:	e8 0e 08 00 00       	call   8049c86 <strings_not_equal>
 8049478:	83 c4 10             	add    $0x10,%esp
 804947b:	85 c0                	test   %eax,%eax
 804947d:	74 0c                	je     804948b <phase_0+0x29>
 804947f:	e8 6a 0a 00 00       	call   8049eee <explode_bomb>
 8049484:	b8 00 00 00 00       	mov    $0x0,%eax
 8049489:	eb 05                	jmp    8049490 <phase_0+0x2e>
 804948b:	b8 01 00 00 00       	mov    $0x1,%eax
 8049490:	c9                   	leave  
 8049491:	c3                   	ret    

push %ebp 将ebp寄存器在main中的旧值压入栈中保存
mov %esp,%ebp 把上一个栈帧的栈底赋值给被调用的这个函数的栈帧的栈顶寄存器,实现新开了一块进程(我是这么理解的),参考了esp和ebp的作用博客
下面的两行sub,实际上是完成了对栈帧空间的分配和栈帧空间需要满足16字节的倍数的ABI规定要求的栈帧空间的大小。(这里不太关心这一部分,所以接着往后看)

下面三行,push,pushl,call三个动作,完成的是对strings_not_equal函数的调用,这个函数位于8049c86这个偏量上。
第一条push语句,将这个函数的第二个参数(注意,是第二个!!),这个参数的值是一个常量,把这个压入栈帧中,这是一个地址。(为什么是地址?常数不可以吗?-先存疑-)
第二条push语句,是将ebp寄存器的值加上0x8以后,这样一个地址中保存的内容,压入到栈帧中。这也是函数的第一个参数。(写到这里就还产生了一个问题,是不是在汇编语言中传参数的时候传的都是某个地址?然后函数到对应的栈帧的某个地方去“挖”对应的内容?)
第三条涉及到strings_not_equal,通过看这个函数定义(去哪里找?用less打开这个汇编然后搜索么?),可以知道这个是用来比较两个字符串是否相等的。这两个参数实际上是两个字符串参数的地址(噢这里就明白了上面为什么要传递地址了,因为要传递的内容是字符串。虽然这样但是,传递其他东西的时候是不是需要也传递地址?这个我写到这里感觉也应该是的,因为汇编操作的本来就是寄存器,然后涉及到值的时候,如果不是常数这种可以通过$balabala来表示的,都是暂且被存在栈中,要找只能通过地址访问(也就是偏移量访问))。说回来,这个strings_not_equal函数在比较两个字符串之后,将存储结果存放在了eax寄存器中。(为什么是eax??)

后一条add的指令,依然是对栈帧空间的维护,我们暂且也跳过。

下面那个test指令,是测试eax寄存器的值,是通过eax与eax自身每一位来按位与,根据操作结果设置标志寄存器。

下面那个je指令,是看之前test的这个eax寄存器中的值是否为0,如果是0,就跳转到804948b那个位置去执行,看最左边一栏,就可以找到804948b这个位置。而在这个位置对应的这个动作,其实就是向eax寄存器中存入1 。(为什么这里是前一个赋值给后一个?难道不是后一个赋值给前一个吗?)
接着跳转后的这个,就是一个leave,就是退出了当前phase_0函数的运行。

这里,je是承接上面的test来的。test对%eax寄存器中的东西按位与,只有%eax中的每一位都为真,才为真。(所以这个地方我提出两个猜想,第一个是上一步比较字符串的时候,是不是字符串也算是按位比较?然后把按位比较的结果存入%eax?然后这里再按位与,全1出1,有0出0,最终把整体的比较结果给到标志位?因为je也是看的标志位的结果嘛。这种猜想有个问题就是字符串很长的时候,一个寄存器存不下,就不行。所以我问了我们班学委,他的想法是这个test仅仅相当于把%eax的值传给了符号位,=这里还要再考证,再学习,然后把结果到时候写回来=)

但是这里je是比较标志位和0的关系?这是怎么一回事。。。感觉应该是汇编语言里头真是0假是1?不然上面那个strings_not_equal也就不对了

查了一下je,je本身就是要检查标志位,如果标志位是0就跳转,1就是不跳转。比较的就是这个。(看了好几个网站,都没有明确的说,直到看到这个,模模糊糊应该是这个意思吧)大神的指点
所以这里也就解释了为什么前面是strings_not_equal,而不是strings_equal这种?我觉得是这样。

扯远了。看个热闹,脑袋里有个印象就行了。
说回最最上面那个汇编。
可以看到,strings_not_equal这个函数,是比较两个字符串的值。根据过程调用的知识,传入的两个参数,这个函数的第一个参数是第二个被压进来的,也就是那个%0x8(%ebp),第二个参数是第一个被压进来的,也就是$0x804b1dc。第一个参数,0x8那个,就是用户输入给程序的密码(拆解字符串)的地址,那么,第二个参数,$0x804balabala那个,就是拿来比较的字符串。这俩输入的要一致,才能让strings_not_equal返回0,才能通过第一关。

——————————
接下来就是要查看
$0x804b1dc
这个位置存放的到底是个什么字符串?
使用gdb。

gdb 中, b *0xbalabala 为在汇编中的0xbalabala位置设置断点,程序运行到那里会停止。
r为运行程序

出现了两个问题,一个是Starting program: /home/bigriver/bomb
/bin/bash: /home/bigriver/bomb: Permission denied
/bin/bash: line 0: exec: /home/bigriver/bomb: cannot execute: Permission denied

这个是文件的读写权限不够高,我使用了
chmod 777 bomb
来解决。

第二个是Starting program: /home/bigriver/bomb
/bin/bash: /home/bigriver/bomb: cannot execute binary file: Exec format error
/bin/bash: /home/bigriver/bomb: Success
During startup program exited with code 126.

这里主要是32位机和64位机不太一样,所以解析出问题了。回宿舍再看看。

装了个32位的ubuntu在vmware上,wsl不能用32位的…也不知道是我没找到方法?

x 显示数据内容
x/40c 位置 查看从某个位置开始的四十个字节的内容。去掉C,看到的就是对应位置的一堆数字。(那么这些数字是什么意思?这里还要去看看)。这应该就是每个字节作为字符和不作为字符输出的区别吧。
或者使用x/1s 位置 来输出位置之后一个字符串的内容(1 string)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值