watch (*p) 是 p 所指的内存的内容, 查看地址,一般是我们所需要的。 我们就是要看某地址上的数据是怎样变化的,虽然这个地址具体位置只有编译器知道。...c. watch 一个数组或内存区间 char buf[128], watch buf, 是对buf 的128个数据进行了监视....此时不是采用硬件断点,而是软中断实现的。 软中断方式去检查内存变量是比较耗费cpu资源的。 精确的指明地址是硬件中断。 2. 当你设置的观察点是一个局部变量时。...(由于效率问题你需要适当控制内存断点设置,当然,对这个小程序无所谓.) —————————————- 看一下mem 数组, 内存数据是怎样被写入的。...Old value = “0123456” New value = “01234567” initBuf (pBuf=0x6010a0 “”) at test.cpp:26 使用
本节我们需要重点关注的问题有: CPU是如何从调用者跳转到被调用函数执行的? 参数是如何从调用者传递给被调用函数的? 函数局部变量所占内存是怎么在栈上分配的?...因为栈的分配是操作系统自动完成的,程序启动时操作系统就会给我们分配一大块内存用作函数调用栈,程序到底使用了多少栈内存由rsp栈顶寄存器来确定。...20>:mov $0x1,%edi #sum函数的第1个参数放入edi寄存器 前两条指令负责把main函数得到的两个参数保存在main函数的栈帧里面,可以看到,这里使用了rbp加偏移量的方式来访问栈内存...edx寄存器 0x0000000000400533 :mov -0x18(%rbp),%eax # 从临时变量中读取第2个到eax寄存器 通过rbp寄存器加偏移量的方式把main传递给sum...加偏移量的方式来访问局部和临时变量,而go编译器则使用rsp寄存器加偏移量的方式来访问它们; ret指令负责把call指令入栈的返回地址出栈给rip,从而实现从被调用函数返回到调用函数继续执行; gcc
(esp、ebp) 特殊寄存器(被特定的汇编指令使用,不能用来任意存储数据) 段地址寄存器(ss、cs、ds、es、fs、gs) 存储内存分段地址 ss 存储函数调用栈...修改返回地址 让其指向内存中已有的某个函数 要完成的任务:在内存中确定要调用的函数地址,覆盖要攻击的函数地址 通常使用lic动态连接库中的系统级的函数获取当前进程的控制权限 payload...)查看汇编 运行程序时用不断增加输入长度来试探 覆盖函数的基地址 address of system() system() 在内存中的地址,用来覆盖返回地址 看看程序如何调用动态链接库 首先确定动态链接库在内存的起始地址...,再加上函数在动态库中的相对偏移量,最终得到函数在内存的绝对地址 ASLR 被关闭的前提下 通过调试工具在运行程序过程中直接查看 system() 的地址 查看动态库在内存的起始地址 再在动态库内查看函数的相对偏移位置...表中该函数的入口点位置,从而定位到该函数在 GOT 中的条目 如何确定函数 B 在内存中的地址 假如我们知道了函数 A 的运行时地址(读取 GOT 表内容),也知道函数 A 和函数 B 在动态链接库内的相对位置
摘要:当程序运行出现段错误时,目标文件没有调试符号,也没配置产生 core dump,如何定位到出错的文件和函数,并尽可能提供更详细的一些信息,如参数,代码等。...00007f93d96cf3cc ,这是出错时指令寄存器 ip 指向的位置,而末尾的 7f93d9674000 是进程启动后 libc-2.27.so 在内存中的动态位置(同一个程序多次启动后起始位置不一样...整行代码的意思要把 rdi 寄存器的某个偏移处的数据复制给 eax 寄存器,前面我们知道引起错误的原因是 用户态程序,读内存越界,原因是非法地址,而不是没权限,所以就是说读取 0xc0(%rdi) 发生错误...由此我们大概知道这里是读取函数的第一个参数的某个偏移量,推测第一个参数是一个结构,这个偏移量是结构的某个成员,而这个结构的地址目前是个无效地址,所以取偏移量会引起读取内存出错。...= -1) return -1 看函数名感觉是判断当前的流 FILE 是否是宽字节流,推测是从 FILE 结构里取信息,结果 FILE 结构地址非法,所以内存读取错误,直接就段错误了。
解决方案 话不多说,先上答案:在运行容器的时候,使用参数--cap-add sys_ptrace,比如: docker run --cap-add sys_ptrace homqyy/example_http...问题原因 由于docker运行的容器默认是将“追踪”能力给关掉的,因此我们需要手动的打开。...,但在docker中却无法使用的工具或运行的程序,比如tcpdump时,不妨直接打开它,以排查是否与能力相关。...如果打开全能力后就能正常使用或运行,则再根据“capabilities(7) — Linux manual page”去找对应的能力选项 最后通过--cap-add来开启必须的能力即可(不推荐大家直接使用...--privileged的原因是,不安全)。
break filename:function 在源文件filename的function函数的入口处停住。 break *address 在程序运行的内存地址处停住。...(除了浮点寄存器) info all-registers 查看所有寄存器的情况。...(包括浮点寄存器) info registers 查看所指定的寄存器的情况。 jump 指定下一条语句的运行点。...可以是文件的行号,可以是file:line格式,可以是+num这种偏移量格式。表示着下一条运行语句从哪里开始。...jump 这里的是代码行的内存地址。
我们在调用 setB 的地方打断点,执行到断点后,用 step 进入到函数,然后查看相应寄存器的值和汇编代码。整个过程如下图: 这里的汇编代码展示了如何通过 this 指针和偏移量访问 b。...这种约定目的是为了提高函数调用的效率,因为使用寄存器传递参数比使用栈更快。 而将寄存器上的参数又移动到栈上,是为了保证寄存器中的值不被覆盖。因为寄存器是有限的资源,在函数中可能会被多次用于不同的目的。...这是因为 x86_64 的指令集和其操作模式通常支持使用寄存器间接寻址方式访问数据。使用rax等通用寄存器作为中间步骤,是一种更通用和兼容的方法。...在程序启动时,操作系统可以快速地为.bss段分配内存并将其初始化为零,而无需从磁盘读取大量的零值数据,可以提高程序的加载速度。...前面使用 GDB 进行调试时,之所以观察到内存地址是固定不变的,这是因为 GDB 默认禁用了 ASLR,以便于调试过程中更容易重现问题。
gdb 调试qemu: 打开新的窗口: cd lab make qemu-gdb 在另外一个终端: make make gdb 开始使用gdb调试,首先进入实模式; IBM PC从物理地址0x000ffff0...引导加载程序必须执行的两个主要功能: 将处理器从实模式切换到 32位保护模式; 通过x86的特殊I / O指令直接访问IDE磁盘设备寄存器,从硬盘读取内核; 引导加载程序的源代码: boot/boot.S...GDT从实模式切换到保护模式 # 并使用段转换以保证虚拟地址和它们的物理地址相同 # 因此 # 有效内存映射在切换期间不会更改。...ELF 程序标头来决定如何加载这些部分,程序标头指定要加载到内存中的ELF对象的哪些部分以及每个目标地址应占据的位置。...在BIOS进入引导加载程序时检查0x00100000处的8个内存字,然后在引导加载程序进入内核时再次检查。
让我们仔细看看出错期间的寄存器 (gdb) info registers 我们的有效负载向程序发送了足够多的A以写入RBP寄存器,导致程序跳转到内存中的0x414141414141....注:计算机通过寄存器管理堆栈。寄存器作为内存中的专用位置,在使用数据时存储数据。大多数寄存器临时存储用于处理的值。在堆栈中存储最后一个程序请求地址的小寄存器称为堆栈指针。...运行以下命令并记录每个寄存器的地址,因为我们需要它们来完成练习(您的主机上的寄存器值可能不同): (gdb) x $rsp (gdb) x $rbp 8....运行以下命令并记录每个寄存器的地址,因为我们需要它们来完成练习(您的主机上的寄存器值可能不同): (gdb) x/120x $rsp 9....gdb中分配断点并读取RSP值时所做的那样。
比如程序出现 段错误(内存地址不合法)时,就可以通过 GDB 找到程序哪里访问了不合法的内存地址而导致的。...本文不是介绍 GDB 的使用方式,而是大概介绍 GDB 的实现原理,当然 GDB 是一个庞大而复杂的项目,不可能只通过一篇文章就能解释清楚,所以本文主要是介绍 GDB 使用的核心的技术 - ptrace...) 来获取被调试进程 addr 处虚拟内存地址的数据,但每次只能读取一个大小为 4字节的数据。...,主要是通过调用 access_process_vm() 函数来读取被调试进程 addr 处的虚拟内存地址的数据。...而父进程(调试进程)接收到 SIGCHLD 后,就可以对被调试的进程进行各种操作,比如读取被调试进程内存的数据和寄存器的数据,或者通过调用 ptrace(PTRACE_CONT, child,...)
本文将介绍如何使用内存映射文件加快PyTorch数据集的加载速度 在使用Pytorch训练神经网络时,最常见的与速度相关的瓶颈是数据加载的模块。...但是如果数据本地存储,我们可以通过将整个数据集组合成一个文件,然后映射到内存中来优化读取操作,这样我们每次文件读取数据时就不需要访问磁盘,而是从内存中直接读取可以加快运行速度。...这个系统调用会接收一个虚拟内存地址(VA),长度(len),protection,一些标志位,一个打开文件的文件描述符,和偏移量(offset)。...Dataset是我们进行数据集处理的实际部分,在这里我们编写训练时读取数据的过程,包括将样本加载到内存和进行必要的转换。...从下面的结果中,我们可以看到我们的数据集比普通数据集快 30 倍以上: 总结 本文中介绍的方法在加速Pytorch的数据读取是非常有效的,尤其是使用大文件时,但是这个方法需要很大的内存,在做离线训练时是没有问题的
来源:DeepHub IMBA本文约1800字,建议阅读9分钟本文将介绍如何使用内存映射文件加快PyTorch数据集的加载速度。...但是如果数据本地存储,我们可以通过将整个数据集组合成一个文件,然后映射到内存中来优化读取操作,这样我们每次文件读取数据时就不需要访问磁盘,而是从内存中直接读取可以加快运行速度。...这个系统调用会接收一个虚拟内存地址(VA),长度(len),protection,一些标志位,一个打开文件的文件描述符,和偏移量(offset)。...Dataset是我们进行数据集处理的实际部分,在这里我们编写训练时读取数据的过程,包括将样本加载到内存和进行必要的转换。...从下面的结果中,我们可以看到我们的数据集比普通数据集快 30 倍以上: 总结 本文中介绍的方法在加速Pytorch的数据读取是非常有效的,尤其是使用大文件时,但是这个方法需要很大的内存,在做离线训练时是没有问题的
0x10000 读取8个扇区大小的ELF头到内存地址0x10000 校验ELF header中的模数,判断是否为0x464C457FU 读取ELF header中的程序段到内存中 跳转到操作系统入口 Bootloader...它需要完成如下的两步操作: bootloader如何读取硬盘扇区的 bootloader是如何加载ELF格式的OS 执行完bootasm.S后,系统进入保护模式, 进行bootmain.c开始加载OS...定义ELF头指针,指向0x10000 读取8个扇区大小的ELF头到内存地址0x10000 校验ELF header中的模数,判断是否为0x464C457FU 读取ELF header中的程序段到内存中...跳转到操作系统入口 bootloader如何读取硬盘扇区的 bootloader是如何加载ELF格式的OS bootloader如何读取硬盘扇区的 * bootloader进入保护模式并载入c程序...参数值,向下(栈顶方向)能获取函数局部变量值,而该地址处又存储着上一层函数调用时的ebp值 举一个实际的例子查看ebp与esp两个寄存器如何构建出完整的函数栈: leave等同于movl %ebp,
,我们以几个重要的内存地址为线索,介绍了 x86 系统在上电开机之后: CPU 如何执行第一条指令; BIOS 中的程序如何被执行; 操作系统的引导代码(bootloader) 被读取到物理内存中被执行...; 下一个环节,就应该是引导程序(bootloader)把操作系统程序,读取到内存中,然后跳入到操作系统的第一条指令处开始执行。...那么在使用的地方,将会填上 0x0200,表示:引用的这个位置是距离代码段开始地址的 512 字节处。 以上的这些地址,指的就是汇编地址。...在读取第 65 KB 数据(扇区 129)之前,把段寄存器 ds 设置为 0x3000,这样读取的数据就从 0x3000:0x0000 处开始存放了。...注意:此时数据段寄存器 ds 仍然没有改变,仍然是 bootloader 中使用的 0x2000。
printf函数(或类似的输出函数)got表中,从而以欺骗的方式在执行printf时实际执行的是system函数,获得bash读取栈和任意地址 任意地址读 假设向程序中输入多个格式字符 0x61616161...处便是aaaa字符串开始的地方 0x61616161是输出的第6个字符,所以使用%6$s 即可读出该地址,这便是手工计算偏移量的方法 任意地址写 直接使用pwntools的fmtstr_payload...7 解题步骤 使用gdb确定字符串参数的偏移量 如果程序中存在敏感的系统函数,可以直接打印,否则: 获取某I\O函数a的got表地址 获取对应的libc.so版本,从而得到system函数的地址 修改函数...flag.txt文件的内容(flag内容限制在21个字符内),然后将内容赋值给v9 也就是说flag是已经加载到程序中的,只要控制程序读取到此段地址内的值,即可不用管程序的其他代码 使用gdb调试,得到用户输入的字符串偏移量是...10(加上前6个寄存器) 0x00007fffffffe978│+0x0000: 0x0000000000400890 → mov edi, 0x4009b8 ← $rsp
多态在我们日常工作中用的算是比较多的一种特性,业界编译器往往是通过虚函数来实现运行时多态,而涉及到虚函数的内存布局往往是最麻烦且容易出错的,本文从一个简单的例子入手,借助gcc和gdb,对内存布局进行分析...在下面的内容中,将通过gdb来分析其内存布局。...在上述汇编中处,调用了operator new进行内存分配,然后将地址放于寄存器rax中,在处调用Base2构造函数,继续分析: (gdb) p/x $rax $2 = 0x612c20...在此,先给出结论:将对象从当前这个类型转换为该对象的实际类型的地址偏移量。...内存泄漏-原因、避免以及定位 GDB调试-从入门实践到原理 【线上问题】P1级公司故障,年终奖不保 【性能优化】高效内存池的设计与实现 2万字|30张图带你领略glibc内存管理精髓
我们遵循`smc`调用约定[05],存储 W0 寄存器中的函数标识符和寄存器 X1-X6 中的参数 (即使我们只使用一个参数)。...我们的 EL1 配置是根据这些要求定义的,并且 实现这一点,我们使用了来自两者的系统配置寄存器值 内核源代码和将在下面介绍的 EL2 预言机 部分,但现在我们可以放心地假设这些是任意选择的 价值观。...1级块条目指向1GB 使用 VA 位 [29:0] 作为 PA 偏移和级别 2 的内存区域 块条目指向 2MB 区域,其中 bits[20:0] 用作偏移量。...使用的标志值表示非安全内存区域,(U/P)XN 禁用, 内存属性间接寄存器中定义的普通内存 (MAIR_EL1) 和访问权限 (AP),允许读取/写入 EL1 并且不允许 访问 EL0。...请注意,由于我们还没有启用 MMU(如图 在接下来的指令中执行的反汇编),所有内存 使用 gdb 访问指的是 PA,这就是我们可以直接检查页面的原因 表和结果 PA。
内存和寄存器查看:gdb允许查看程序运行时的内存内容和寄存器状态。这对于分析程序的内部状态和执行路径非常有用。...2.3、gdb调试正在运行进程的高级功能2.3.1、进程内存和寄存器的查看与修改(1)查看内存:可以使用x命令来查看内存中的内容。...例如,要以十六进制格式查看地址为0x1000处的内存内容:x/x 0x1000(2)修改内存:可以使用set命令来修改内存中的内容。...例如,要将地址为0x1000处的内存内容设置为0x55,可以执行以下命令:set {int}0x1000 = 0x55(3)查看寄存器:可以使用info registers命令来查看当前进程的寄存器状态...分析性能问题:当程序在断点处中断时,可以使用gdb的各种命令来分析性能问题:info functions:列出程序中的所有函数,可以帮助查找可能的瓶颈函数。
格式 break 函数名 break 行号 break 文件名:行号 break 文件名:函数名 break + 偏移量 break - 偏移量 break * 地址 举例 (gdb) b print...$,可以显示寄存器的内容。...o 显示为八进制数 t 显示为二进制数 a 地址 c 显示为ascii f 浮点小数 s 显示为字符串 i 显示为机器语言(仅在显示内存的x命令中可用) 显示内存 x命令可以显示内存的内容 格式 x...end 程序在指定的断点处暂停,就会自动执行命令。...与前面的条件断点组合使用,可以在断点暂停时执行复杂的动作。
⑤ 实验室使用的OK6410开发板定制的编译器为32位的,其交叉编译工具链主要arm-linux-gcc,arm-linux-g++arm-linux-gdb等构成。...SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量。 SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小。...使用fork()函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间,包括进程的上下文、代码段、进程堆栈、内存信息、打开的文件描述符、符号控制设定、进程优先级、进程组号、当前工作目录...两者的区别: (1)_exit()函数的作用最为简单:直接使进程终止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构; (2)exit()函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序...,不能随机读取设备内存中的某一数据,读取数据需要按照先后顺序进行。
领取专属 10元无门槛券
手把手带您无忧上云