首页 > 其他分享 >CMU-15213 笔记

CMU-15213 笔记

时间:2023-11-09 23:12:44浏览次数:49  
标签:15213 rbx mov 笔记 eax CMU rsp rax ecx

Recitation 4

讲了一些GDB常用操作,虽然不少已经在 CS61C 里面学过了,但是保险起见还是在这里再记录一下

几个不熟悉的

clear main // remove the breakpoint at function main
(gdb) print (char*) [0x...] // prints a string
(gdb) print argv[1]
(gdb) disassemble main // show the assembly instructions in main
print/x $rsi   // ‘/x’ means print in hexadecimal

要查看传入被调用函数的参数是什么,最好的办法就是直接看对应函数的汇编代码,

  • 一般来说,$rdi 保存第一个参数,$rsi保存第二个,$rax保存返回值

一个小技巧: 按 Enter 键就可以重复上一次操作

  • info breakpoints (i b)
  • List all breakpoints, along with whether or not they are enabled
  • delete [breakpoint] (d)
    • Delete a breakpoint
  • enable [breakpoint] (en)
  • Enable a breakpoint, If none specified, enables all breakpoints
  • disable [breakpoint] (dis)
  • Disable a breakpoint. If none specified, disables all breakpoints
  • info registers (i reg)
    • Print all the registers, along with their contents
  • print [any valid C expression] (p)
  • Can be used to study any kind of local variable or memory location
  • Use casting to get the right type (e.g. print *(long *)pointer)
  • Can format with things like /x (hex), /d (int), /s (string) etc.
  • x [some format specifier] [some memory address]
  • Examines memory. x ptr is the same as p *ptr
  • Can format with things like /x (hex), /d (int), /s (string) etc.
  • layout [next | prev | assembly | register] (la [n | p | asm | reg])
  • Show assembly code or registers in the top half of the window as you go
  • The TUI is buggy. If your screen begins glitching, you may have to restart GDB
  • Exit with <ctrl> x + <ctrl> a
  • focus [command | assembly | register] (fo [cmd | asm | reg])
  • Change the focus window within the TUI (buggy)

Bomblab

phase3

几个跳转指令

For unsigned comparisons:

JB/JNAE (CF = 1)           : Jump if below/not above or equal
JAE/JNB (CF = 0)           : Jump if above or equal/not below
JBE/JNA (CF = 1 or ZF = 1) : Jump if below or equal/not above
JA/JNBE (CF = 0 and ZF = 0): Jump if above/not below or equal

For signed comparisons:

JL/JNGE (SF <> OF)          : Jump if less/not greater or equal
JGE/JNL (SF = OF)           : Jump if greater or equal/not less
JLE/JNG (ZF = 1 or SF <> OF): Jump if less or equal/not greater
JG/JNLE (ZF = 0 and SF = OF): Jump if greater/not less or equal

phase3看着就是一堆switch语句,轻松搞定

phase4

phase4注意test的用法

将两个操作数进行按位AND,设结果是TEMP

  • SF = 将结果的最高位赋给SF标志位,例如结果最高位是1,SF就是1
  • 如果TEMP是0,ZF位置1;如果不是0,ZF位置0
  • 如果结果低8位中1的个数是偶数,PF=1;否则PF=0
  • CF位置0
  • OF位置0

一个经典应用之测试是否为零

test ecx, ecx
jz somewhere
0000000000400fce <func4>: #传入的 %edx 为 0xe, %esi 为 0x0, %edi 为输入的第一个参数 a1
  400fce:	48 83 ec 08          	sub    $0x8,%rsp
  400fd2:	89 d0                	mov    %edx,%eax    # %eax = %edx
  400fd4:	29 f0                	sub    %esi,%eax    # %eax = %edx - %esi
  400fd6:	89 c1                	mov    %eax,%ecx    # %ecx = %eax
  400fd8:	c1 e9 1f             	shr    $0x1f,%ecx   # %ecx 逻辑右移 31 位(高位补0)
  400fdb:	01 c8                	add    %ecx,%eax    # %eax += 符号位
  400fdd:	d1 f8                	sar    %eax         # %eax >>= 1
  400fdf:	8d 0c 30             	lea    (%rax,%rsi,1),%ecx # %ecx = %rax + %rsi
  400fe2:	39 f9                	cmp    %edi,%ecx
  400fe4:	7e 0c                	jle    400ff2 <func4+0x24> #若 %ecx<=%edi, 跳转
  400fe6:	8d 51 ff             	lea    -0x1(%rcx),%edx  # %edx = %rcx - 1
  400fe9:	e8 e0 ff ff ff       	callq  400fce <func4>
  
  #以下两行似乎没有用
  400fee:	01 c0                	add    %eax,%eax   # %eax *= 2
  400ff0:	eb 15                	jmp    401007 <func4+0x39>
  
  400ff2:	b8 00 00 00 00       	mov    $0x0,%eax  # %eax = 0
  
  400ff7:	39 f9                	cmp    %edi,%ecx
  400ff9:	7d 0c                	jge    401007 <func4+0x39> # %ecx >= %edi 跳转
  400ffb:	8d 71 01             	lea    0x1(%rcx),%esi # %esi = %rcx + 1
  400ffe:	e8 cb ff ff ff       	callq  400fce <func4>
  
  # 这一行好像也没用
  401003:	8d 44 00 01          	lea    0x1(%rax,%rax,1),%eax # 2*%rax+1=%eax=0
  
  401007:	48 83 c4 08          	add    $0x8,%rsp
  
  40100b:	c3                   	retq   

只要第一个参数等于对应的 %ecx 即可

phase5

注意寄存器的关系

  • %cl%rcx 的低八位
  • %dl%rdx 的低八位
0x0000000000401062 <+0>:     push   %rbx
0x0000000000401063 <+1>:     sub    $0x20,%rsp
0x0000000000401067 <+5>:     mov    %rdi,%rbx       # %rbx = %rdi
0x000000000040106a <+8>:     mov    %fs:0x28,%rax   # canary被存入 %rax
0x0000000000401073 <+17>:    mov    %rax,0x18(%rsp) # canary被存入 0x18(%rsp)
0x0000000000401078 <+22>:    xor    %eax,%eax       # %eax = 0
0x000000000040107a <+24>:    callq  0x40131b <string_length>
0x000000000040107f <+29>:    cmp    $0x6,%eax
0x0000000000401082 <+32>:    je     0x4010d2 <phase_5+112> #字符串长度等于6 则跳转
0x0000000000401084 <+34>:    callq  0x40143a <explode_bomb>
0x0000000000401089 <+39>:    jmp    0x4010d2 <phase_5+112>

0x000000000040108b <+41>:    movzbl (%rbx,%rax,1),%ecx # %ecx 等于 (%rbx,%rax,1) 处的值

0x000000000040108f <+45>:    mov    %cl,(%rsp)     # %cl 是 %rcx 的低八位 
0x0000000000401092 <+48>:    mov    (%rsp),%rdx
# 下面这一句应该没用(马上被覆盖掉了)
0x0000000000401096 <+52>:    and    $0xf,%edx      # 上面一串相当于 %edx = (%rbx,%rax,1) 处的值的低四位

0x0000000000401099 <+55>:    movzbl 0x4024b0(%rdx),%edx
0x00000000004010a0 <+62>:    mov    %dl,0x10(%rsp,%rax,1)
0x00000000004010a4 <+66>:    add    $0x1,%rax
0x00000000004010a8 <+70>:    cmp    $0x6,%rax
0x00000000004010ac <+74>:    jne    0x40108b <phase_5+41>
0x00000000004010ae <+76>:    movb   $0x0,0x16(%rsp)
0x00000000004010b3 <+81>:    mov    $0x40245e,%esi    # 第二个操作数, 此处为"flyers"
0x00000000004010b8 <+86>:    lea    0x10(%rsp),%rdi   # 第一个操作数
0x00000000004010bd <+91>:    callq  0x401338 <strings_not_equal>
0x00000000004010c2 <+96>:    test   %eax,%eax
0x00000000004010c4 <+98>:    je     0x4010d9 <phase_5+119>
0x00000000004010c6 <+100>:   callq  0x40143a <explode_bomb>
0x00000000004010cb <+105>:   nopl   0x0(%rax,%rax,1)
0x00000000004010d0 <+110>:   jmp    0x4010d9 <phase_5+119>

0x00000000004010d2 <+112>:   mov    $0x0,%eax

0x00000000004010d7 <+117>:   jmp    0x40108b <phase_5+41>

0x00000000004010d9 <+119>:   mov    0x18(%rsp),%rax

0x00000000004010de <+124>:   xor    %fs:0x28,%rax
0x00000000004010e7 <+133>:   je     0x4010ee <phase_5+140>
0x00000000004010e9 <+135>:   callq  0x400b30 <__stack_chk_fail@plt>
0x00000000004010ee <+140>:   add    $0x20,%rsp
0x00000000004010f2 <+144>:   pop    %rbx
0x00000000004010f3 <+145>:   retq

注意几个 mov 指令的区别

假设 %dh =8D,%eax=98765432 
movb %dh %al %eax=9876548D 
movsbl %dh %eax %eax=FFFFFF8D 
movzbl %dh %eax %eax=0000008D
(gdb) x/16x 0x4024b0
0x4024b0:       0x7564616d      0x73726569      0x746f666e      0x6c796276
0x4024c0:       0x79206f53      0x7420756f      0x6b6e6968      0x756f7920
0x4024d0:       0x6e616320      0x6f747320      0x68742070      0x6f622065
0x4024e0:       0x7720626d      0x20687469      0x6c727463      0x202c632d

(gdb) x/16x 0x40245e
0x40245e:       0x65796c66      0x00007372      0x00000000      0x00000000
0x40246e:       0x0f7c0000      0x00000040      0x0fb90000      0x00000040
0x40247e:       0x0f830000      0x00000040      0x0f8a0000      0x00000040
0x40248e:       0x0f910000      0x00000040      0x0f980000      0x00000040

所以感觉就是根据输入的,来从给定的 0x4024b0 里面找到一样的就行

所以依次应该是:

  • 0x66对应第9个,则输入的第一个字符的ASCII码最后一位应为0x9

  • 0x6c - 0xf, 0x79 - 0xe, 0x65 - 0x5, 0x72 - 0x6, 0x73 - 0x7

直接用字母,答案应该为 ionefg

phase6

  • rbxrbpr12r13r14r15 都是被调用者保存
  • r10r11raxrdirsirdxrcxr8r9 都是调用者保存

这是一个链表!!!!!

一开始是为了检验链表不能连自身,所以要检测相邻的数字不一样

0x00000000004010f4 <+0>:     push   %r14
0x00000000004010f6 <+2>:     push   %r13
0x00000000004010f8 <+4>:     push   %r12
0x00000000004010fa <+6>:     push   %rbp
0x00000000004010fb <+7>:     push   %rbx
0x00000000004010fc <+8>:     sub    $0x50,%rsp
0x0000000000401100 <+12>:    mov    %rsp,%r13  # 数组开始的地方, 即a
0x0000000000401103 <+15>:    mov    %rsp,%rsi
0x0000000000401106 <+18>:    callq  0x40145c <read_six_numbers>

0x000000000040110b <+23>:    mov    %rsp,%r14   # 数组开始的地方, 即a
0x000000000040110e <+26>:    mov    $0x0,%r12d  # %r12 的低32位清零

0x0000000000401114 <+32>:    mov    %r13,%rbp   # 数组开始的地方, 即a
0x0000000000401117 <+35>:    mov    0x0(%r13),%eax # %eax = a[i-1]
0x000000000040111b <+39>:    sub    $0x1,%eax      # %eax = a[i-1] - 1 
0x000000000040111e <+42>:    cmp    $0x5,%eax
0x0000000000401121 <+45>:    jbe    0x401128 <phase_6+52>  # 检查 a[i-1] - 1 <= 5
0x0000000000401123 <+47>:    callq  0x40143a <explode_bomb>
0x0000000000401128 <+52>:    add    $0x1,%r12d
0x000000000040112c <+56>:    cmp    $0x6,%r12d  # 循环5次, 令 i = %r12d (1到5)
0x0000000000401130 <+60>:    je     0x401153 <phase_6+95>
0x0000000000401132 <+62>:    mov    %r12d,%ebx  # %ebx = i

0x0000000000401135 <+65>:    movslq %ebx,%rax   # 符号扩展后送到 %rax (就是i)
0x0000000000401138 <+68>:    mov    (%rsp,%rax,4),%eax  # %eax = a[i]
0x000000000040113b <+71>:    cmp    %eax,0x0(%rbp)
0x000000000040113e <+74>:    jne    0x401145 <phase_6+81> # 需要 %eax = a[i] != a[i-1]
0x0000000000401140 <+76>:    callq  0x40143a <explode_bomb>
0x0000000000401145 <+81>:    add    $0x1,%ebx
0x0000000000401148 <+84>:    cmp    $0x5,%ebx
0x000000000040114b <+87>:    jle    0x401135 <phase_6+65>
0x000000000040114d <+89>:    add    $0x4,%r13  # a数组指针推后一个
0x0000000000401151 <+93>:    jmp    0x401114 <phase_6+32>

0x0000000000401153 <+95>:    lea    0x18(%rsp),%rsi
--Type <RET> for more, q to quit, c to continue without paging--
0x0000000000401158 <+100>:   mov    %r14,%rax  # $rax = 数组开头地址
0x000000000040115b <+103>:   mov    $0x7,%ecx  # %ecx = 7

0x0000000000401160 <+108>:   mov    %ecx,%edx  # %edx = 7
0x0000000000401162 <+110>:   sub    (%rax),%edx # %edx -= (%rax) 即 a[i]
0x0000000000401164 <+112>:   mov    %edx,(%rax) # 以上相当于 a[i] = 7 - a[i]
0x0000000000401166 <+114>:   add    $0x4,%rax
0x000000000040116a <+118>:   cmp    %rsi,%rax
0x000000000040116d <+121>:   jne    0x401160 <phase_6+108>
0x000000000040116f <+123>:   mov    $0x0,%esi
0x0000000000401174 <+128>:   jmp    0x401197 <phase_6+163>

0x0000000000401176 <+130>:   mov    0x8(%rdx),%rdx
0x000000000040117a <+134>:   add    $0x1,%eax
0x000000000040117d <+137>:   cmp    %ecx,%eax  # %ecx 被<+163>赋值为 a[j] 
0x000000000040117f <+139>:   jne    0x401176 <phase_6+130> # 相当于令 %rdx = node[6-j]的第三个数
0x0000000000401181 <+141>:   jmp    0x401188 <phase_6+148>

0x0000000000401183 <+143>:   mov    $0x6032d0,%edx

0x0000000000401188 <+148>:   mov    %rdx,0x20(%rsp,%rsi,2)
0x000000000040118d <+153>:   add    $0x4,%rsi
0x0000000000401191 <+157>:   cmp    $0x18,%rsi
0x0000000000401195 <+161>:   je     0x4011ab <phase_6+183>

0x0000000000401197 <+163>:   mov    (%rsp,%rsi,1),%ecx  # %ecx = a[j] 
0x000000000040119a <+166>:   cmp    $0x1,%ecx
0x000000000040119d <+169>:   jle    0x401183 <phase_6+143>  # a[j] <= 1 跳转
0x000000000040119f <+171>:   mov    $0x1,%eax
0x00000000004011a4 <+176>:   mov    $0x6032d0,%edx
0x00000000004011a9 <+181>:   jmp    0x401176 <phase_6+130>

0x00000000004011ab <+183>:   mov    0x20(%rsp),%rbx  # %rbx = 被放进去的第一个数
0x00000000004011b0 <+188>:   lea    0x28(%rsp),%rax  # %rax = 被放进去的第二个数对应的地址
0x00000000004011b5 <+193>:   lea    0x50(%rsp),%rsi  # 0x00402210对应的地址(对应理论上的第七个数)
0x00000000004011ba <+198>:   mov    %rbx,%rcx		 # %rcx = 被放进去的第一个数
# 在链表中 %rcx 的下一个是 %rdx
0x00000000004011bd <+201>:   mov    (%rax),%rdx		 # %rdx = 被放进去的第i+1个数
0x00000000004011c0 <+204>:   mov    %rdx,0x8(%rcx)   # 把 b[i+1] 放到 0x8(%rcx)
0x00000000004011c4 <+208>:   add    $0x8,%rax
--Type <RET> for more, q to quit, c to continue without paging--
0x00000000004011c8 <+212>:   cmp    %rsi,%rax        # 需要 %rsi = %rax
0x00000000004011cb <+215>:   je     0x4011d2 <phase_6+222>
0x00000000004011cd <+217>:   mov    %rdx,%rcx
0x00000000004011d0 <+220>:   jmp    0x4011bd <phase_6+201>
0x00000000004011d2 <+222>:   movq   $0x0,0x8(%rdx)
0x00000000004011da <+230>:   mov    $0x5,%ebp

0x00000000004011df <+235>:   mov    0x8(%rbx),%rax
0x00000000004011e3 <+239>:   mov    (%rax),%eax
0x00000000004011e5 <+241>:   cmp    %eax,(%rbx)
0x00000000004011e7 <+243>:   jge    0x4011ee <phase_6+250> # (%rbx) >= %eax = (%rax) = [0x8(%rbx)] 即链表递减
0x00000000004011e9 <+245>:   callq  0x40143a <explode_bomb>
0x00000000004011ee <+250>:   mov    0x8(%rbx),%rbx
0x00000000004011f2 <+254>:   sub    $0x1,%ebp
0x00000000004011f5 <+257>:   jne    0x4011df <phase_6+235>
0x00000000004011f7 <+259>:   add    $0x50,%rsp
0x00000000004011fb <+263>:   pop    %rbx
0x00000000004011fc <+264>:   pop    %rbp
0x00000000004011fd <+265>:   pop    %r12
0x00000000004011ff <+267>:   pop    %r13
0x0000000000401201 <+269>:   pop    %r14
0x0000000000401203 <+271>:   retq

其中第<+143> <+176>行的东西是这个,看起来是记录什么东西,也许是原始数组或者序号(输入是 1 2 3 4 5 6)

(gdb) x/32x 0x6032d0
0x6032d0 <node1>:       0x0000014c      0x00000001      0x006032e0      0x00000000
0x6032e0 <node2>:       0x000000a8      0x00000002      0x006032f0      0x00000000
0x6032f0 <node3>:       0x0000039c      0x00000003      0x00603300      0x00000000
0x603300 <node4>:       0x000002b3      0x00000004      0x00603310      0x00000000
0x603310 <node5>:       0x000001dd      0x00000005      0x00603320      0x00000000
0x603320 <node6>:       0x000001bb      0x00000006      0x00000000      0x00000000
0x603330:       0x00000000      0x00000000      0x00000000      0x00000000
0x603340 <host_table>:  0x00402629      0x00000000      0x00402643      0x00000000

做到后面发现这个应该是一个链表,顺序是 1<-2<-3<-4<-5<-6

输入进去的数组存放在 0x7fffffffdc70

标签:15213,rbx,mov,笔记,eax,CMU,rsp,rax,ecx
From: https://www.cnblogs.com/520Enterprise/p/CMU-15213.html

相关文章

  • 学习笔记9
    第六章知识点信号和中断中断是从I/O设备或协处理器发送到CPU的外部请求,它将CPU从正常执行转移到中断处理。人员中断来源来自硬件的中断来自他人的中断自己造成的中断紧急程度不可屏蔽可屏蔽进程中断来自硬件的中断来自他人的中断自己造成的中断硬件......
  • linux驱动模型--Apple的学习笔记
    一,前言既然是复习设备驱动,第一步当然是做一个最简单的基于设备树的驱动applechar,然后insmod和rmmod使用下,接着要回忆下driver和device是怎么match的,且把相关结构体复习下。看了下结构体发现有点忘记了,另外match的函数也忘记了。有些东西不需要死记硬背,通过代码分析的方法论找到它即......
  • 【论文阅读笔记】【OCR-文本识别】 Scene Text Recognition with Permuted Autoregres
    PARSeqECCV2022读论文思考的问题论文试图解决什么问题?一些文本识别模型会对semantic信息建模,从而辅助某些困难情况下的文本识别传统的auto-regressive方式限制了语义信息的传输方向;双向的auto-regressive聚合增加了不必要的计算量和复杂度;聚合视觉模型和语言......
  • 【Django-DRF笔记】使用md笔记0基础到高手. 第(5)篇:Django-DRF序列化和反序列化
    本文从分析现在流行的前后端分离Web应用模式说起,然后介绍如何设计RESTAPI,通过使用Django来实现一个RESTAPI为例,明确后端开发RESTAPI要做的最核心工作,然后介绍DjangoRESTframework能帮助我们简化开发RESTAPI的工作。DRF完整版笔记直接地址:请移步这里共5章,24子模块,总计......
  • openGauss学习笔记-118 openGauss 数据库管理-设置数据库审计-维护审计日志
    openGauss学习笔记-118openGauss数据库管理-设置数据库审计-维护审计日志118.1前提条件用户必须拥有审计权限。118.2背景信息与审计日志相关的配置参数及其含义请参见表1。表1审计日志相关配置参数配置项含义默认值audit_directory审计文件的存储目录。/......
  • 【刷题笔记】104. Maximum Depth of Binary Tree
    题目Givenabinarytree,finditsmaximumdepth.Themaximumdepthisthenumberofnodesalongthelongestpathfromtherootnodedowntothefarthestleafnode.Note:Aleafisanodewithnochildren.Example:Givenbinarytree[3,9,20,null,null,15,7],......
  • 大数据-笔记-1
    大数据-笔记-1文章地址:https://www.cnblogs.com/rabbit-dayi/1.安装2.查看三台虚拟机IP设置静态IP3.修改IPV4为manualIP地址如下:gataway:192.168.83.2mask:24master:192.168.83.10slv1:192.168.83.11slv2:192.168.83.123.关闭防火墙su[输入密......
  • sharding分表应用笔记(二)——按时间分表策略配置
    sharding分表应用笔记(二)——按时间分表策略配置目录sharding分表应用笔记(二)——按时间分表策略配置1背景2配置2.1命名空间配置2.2策略接口实现2.2.1时间精确分片策略2.2.2时间范围分片策略3外部链接1背景应用背景:物理数据源只有一个;对于部分数据量大的表实行按月分表处......
  • 【python进阶】14大模块200页知识体系md笔记,第5篇:python下的linux命令使用
    本文从14大模块展示了python高级用的应用。分别有Linux命令,多任务编程、网络编程、Http协议和静态Web编程、html+css、JavaScript、jQuery、MySql数据库的各种用法、python的闭包和装饰器、mini-web框架、正则表达式等相关文章的详细讲述。全套Python笔记直接地址:请移步这里共......
  • 【学习笔记】树的直径
    树的直径定义为树上任意两点间最长的简单路径求法1:两次dfs适用范围:树上所有边边权都非负算法过程:以树上任意一点开始第一次dfs,找到距其最远的点\(z\),再以\(z\)为起始点进行第二次dfs,找到距其最远的点\(z\prime\),则\(zz\prime\)即为所求。......