[Advance] How to debug a program (上)

 

Tool GDB

Examining Memory (data or in machine instructions)

You can use the command x (for “examine”) to examine memory in any of several formats, independently of your program's data types.

x/nfu addr

x addr

x

n, the repeat count

The repeat count is a decimal integer; the default is 1. It specifies how much memory (counting by units u) to display.

f, the display format

The display format is one of the formats used by print (`x', `d', `u', `o', `t', `a', `c', `f', `s'), and in addition `i' (for machine instructions). The default is `x' (hexadecimal) initially. The default changes each time you use either x or print.

x -- Print as integer in hexadecimal.

d -- Print as integer in signed decimal.

u -- Print as integer in unsigned decimal.

o -- Print as integer in octal.

t -- Print as integer in binary. The letter `t' stands for “two”. 1

a -- Print as an address, both absolute in hexadecimal and as an offset from the nearest preceding symbol. You can use this format used to discover where (in what function) an unknown address is located:

          (gdb) p/a 0x54320

          $3 = 0x54320 <_initialize_vx+396>

c -- Regard as an integer and print it as a character constant.

f -- Regard as a floating point number and print using typical floating point syntax.

s --Regard as a string

u, the unit size  -- The unit size is any of

b -- Bytes.

h -- Halfwords (two bytes).

w -- Words (four bytes). This is the initial default.

g -- Giant words (eight bytes).

Each time you specify a unit size with x, that size becomes the default unit the next time you use x. For the `i' format, the unit size is ignored and is normally not written. For the `s' format (string), the unit size defaults to `b', unless it is explicitly given. Use x /hs to display 16-bit char strings and x /ws to display 32-bit strings. The next use of x /s will again display 8-bit strings. Note that the results depend on the programming language of the current compilation unit. If the language is C, the `s' modifier will use the UTF-16 encoding while `w' will use UTF-32. The encoding is set by the programming language and cannot be altered.

Example:

x/4xw $sp -- print the four words (`w') of memory above the stack pointer  in hexadecimal (`x').

x/3uh 0x54320 -- display three halfwords (h) of memory, formatted as unsigned decimal integers (`u'), starting at address 0x54320.

x/5i $pc-6 -- examines machine instructions.

Registers

The names of registers are different for each machine; use info registers to see the names 
used on your machine.
info registers– check register names
gdb four “standard” register:
$pc -- the program counter register, $RIP
$sp -- the stack pointer register, $RSP
$fp -- a pointer to the current stack frame, “base pointer” register, $RBP
$ps -- a register that contains the processor status
Example:
p/x $pc
x/i $pc

GDB conversation

If displaying variable, which is a address, gdb will try to display its content(value) together. 
Format:
Address:  content(value) 
Example:
(gdb) x/x $pc  -- $pc is a address
0x40071e <_Z3addii+4>:  0x10ec8348
(gdb) x/i $pc
0x40071e <_Z3addii+4>:  sub    $0x10,%rsp
(gdb) x/xg $pc
0x40071e <_Z3addii+4>:  0x89fc7d8910ec8348
(gdb) p $pc – print value of $pc only
$9 = (void (*)()) 0x40071e <add(int, int)+4>
(gdb) p/x $pc
$10 = 0x40071e 

Advance guide for debugging a program

Introduce

Any program only includes data and machine instructions.
Machine instructions: user code(Text), static lib code and shared lib code. We can 
disassemble program at any program memory.
Data: initialized data, uninitialized data (bss), Heap(malloc arena), stack and registers. 
Commonly, the code(machine instruction) won’t change when running a program. It means 
if we track data, we can know the all program status according to machine instruction.
This means gdb x command can be a general tool for program debug.

Virtual memory

Modern operating systems and architectures provide virtual memory. Through hardware support and additional code in the operating system, virtual memory allows each user process to act as though it is the only thing running on the computer. It gives each process a completely separate address space.

Through pmap, user can check process' memory map, such as:

$ pmap 23814  # If you don't have pmap installed, use 'cat /proc/23814/maps'

Process memory layout

 

It is for 64-bit systems. On 32-bit systems the shared libraries are usually found at the lowest address, followed by the text segment, then everything else.

The text, or code, segment contains the actual program and any statically linked libraries. On 64-bit systems it generally starts at 0x400000 (32-bit systems like to place it at 0x8047000).

The data and BSS segments come next. The data segment contains all initialized global variables as well as static strings (eg, those used in printf). The BSS, or "block started by segment" region holds all uninitialized global variables (those which by C convention are initialized automatically to 0).

After that comes the heap, where all memory obtained via malloc() is located. The heap grows upwards as more memory is requested.

Then we have any shared libraries such as the loader, libc, malloc, etc.

Finally we have the stack, which it should be noted grows downward as it expands.

Downward-growing stack

Programs use the stack to store temporary, or automatic variables, arguments passed during a function call, and information needed to return to a previous point in the program when a function call is made.

There are also three registers that are important at this point - RBP, RSP, and RIP. RSP is the stack pointer. The stack works just like a LIFO queue with push() and pop() operations. RSP tracks the next available position in this queue.

The stack frame is essentially the region of the stack that is presently active, or that corresponds to the presently executing function. It is pointed to by RBP, the "base pointer," and is used in combination with an offset to reference all local variables. Every time a function is called, RBP is updated to point to its stack frame.  

RIP is the instruction pointer. It holds the address of the instruction that the CPU just loaded and is presently executing.

The diagram above shows a snapshot of the stack for a program that is presently in func1(), which was called from main(). In order for the stack to look this way, some things must have happened when func1() was called. These steps are defined by the C calling convention. [2]

1. The arguments to func1() were pushed onto the stack.
2. func1() was called.
3. RBP was pushed onto the stack.
4. RSP was moved to RBP.
5. Space for the local variables was allocated on the stack.
6. Local variables were set to initial values (if provided).

Steps 3 through 6 are called the function prelude.

图3 带有基指针的栈帧

System calls

The only way to enter supervisor mode is to go through predefined entry points in the kernel. 
One of these points is called a system call.

How system calls work on x86_64 Linux by taking a look at the kernel source, specifically arch/x86_64/kernel/entry.S where we see the following comment...

/*

 * System call entry. Upto 6 arguments in registers are supported.

 *

 * SYSCALL does not save anything on the stack and does not change the

 * stack pointer.

 */

                              

/*

 * Register setup: 

 * rax  system call number

 * rdi  arg0

 * rcx  return address for syscall/sysret, C arg3

 * rsi  arg1

 * rdx  arg2        

 * r10  arg3        (--> moved to rcx for C)

 * r8   arg4

 * r9   arg5

 * r11  eflags for syscall/sysret, temporary for C

 * r12-r15,rbp,rbx saved by C code, not touched.                          

 *

 * Interrupts are off on entry.

 * Only called from user space.

 *

 * XXX   if we had a free scratch register we could save the RSP into the stack frame

 *      and report it properly in ps. Unfortunately we haven't.

 */                                                                     

So to make a system call, you first store the syscall number in RAX, any parameters in RDI, RSI, 
RDX, etc, and then execute the "syscall" instruction.

 

图4 64位模式下通用寄存器的大小和名称

 

图5 在传统和兼容模式下的通用寄存器大小和名称

通用寄存器在编程时通常用于不同的用途,说明如表1所示。

表1 通用寄存器的用途

寄存器名

用途

EAX

累加器

EBX

基址寄存器

ECX

计数器

EDX

数据寄存器

ESI

源地址指针寄存器

EDI

目的地址指针寄存器

EBP

基址指针寄存器

ESP

堆栈指针寄存器

 
待续

参考文献:
Buffer Overflows and You (上)
GDB munual
X86-64构架概述
X86-64处理器构架的应用程序二进制接口

转载于:https://www.cnblogs.com/zhenjing/archive/2011/03/22/advance_debug.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows7系统安装更新补丁提示0x80240037错误如何解决,文件的后缀名怎么换?

作者&#xff1a;WYF 我们以 IE11-Windows6.1-KB3008923-x64.msu 补丁为例 1、首先我们把IE11-Windows6.1-KB3008923-x64.msu的后缀名msu改为cab&#xff0c;然后解压&#xff0c;注意解压到一个新的文件夹中&#xff0c;不要在本文件夹中解压&#xff08;例如&#xff1a;可以…

多核电脑的配件(CPU)

cpu CPU&#xff0c;全称中央处理器&#xff0c;既是电脑的指令中枢&#xff0c;也是系统的最高执行单位。 CPU主要负责指令的执行&#xff0c;作为电脑系统的核心组件&#xff0c;在电脑系统中占有举足轻重的地位&#xff0c;是影响电脑系统运算速度的重要部件。 cpu的基本信…

centos7利用nexus离线搭建局域网pypi源

centos7利用nexus离线搭建局域网pypi源 1、官网下载nexus oss版本 https://sonatype-download.global.ssl.fastly.net/repository/downloads-prod-group/3/nexus-3.29.2-02-unix.tar.gz [rootlocalhost bin]# wget https://sonatype-download.global.ssl.fastly.net/reposit…

从零搭建nginx服务器

本文开始从零搭建一个nginx网页服务器。 1.最小化安装linux&#xff08;web服务器需要纯净的环境&#xff09; 2.局域网环境&#xff08;环境限制&#xff0c;需要搭建本地包配置环境&#xff09; 3.配置安装nginx环境 1.搭建系统 物理系统:两台浪潮服务器&#xff0c;两台联…

.NET中栈和堆的比较【转自:c#开发园地】

本文转自&#xff1a;C#开发园地 原文翻译的地址&#xff1a;http://www.cnblogs.com/c2303191/articles/1065675.html压栈(入栈)执行方法中的指令.NET中栈和堆的比较1 原文出处&#xff1a; http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM…

修改远程桌面的端口+防火墙设置

作者&#xff1a;WYF 修改远程桌面的端口防火墙设置&#xff08;最详细&#xff09; Windows系统中的远程终端服务是一项功能非常强大的服务&#xff0c;其默认的端口号3389很容易成为入侵者长驻主机的通道&#xff0c;使用户电脑成为通常称为的“肉鸡”&#xff0c;受入侵者远…

keepalived高可用+nginx负载均衡

keepalived高可用nginx负载均衡 1、IP地址规划 hostnameip说明KN0110.4.7.30keepalived MASTER节点 nginx负载均衡器KN0210.4.7.31keepalived BACKUP节点 nginx负载均衡器WEB0110.4.7.24web01节点WEB0210.4.7.25web02节点 2、关闭防火墙&#xff0c;selinux&#xff0c;并安装…

centos利用nexus搭建局域网docker私有仓库

centos利用nexus搭建局域网docker私有仓库 1、官网下载nexus oss版本 https://sonatype-download.global.ssl.fastly.net/repository/downloads-prod-group/3/nexus-3.29.2-02-unix.tar.gz [rootlocalhost bin]# wget https://sonatype-download.global.ssl.fastly.net/repo…

centos离线部署gitlab

centos离线部署gitlab 有的时候因为工作环境需要&#xff0c;不能够连接互联网。而我们工作时又需要使用git进行合作开发&#xff0c;这时就需要在内网部署一个git服务端。 1、下载依赖软件包 yum install --downloadonly --downloaddir/opt/repo curl policycoreutils-pyth…

centos离线安装jenkins

centos离线安装jenkins 1、安装java环境&#xff0c;这里我们选择openjdk&#xff0c;当然也可以是JDK [rootlocalhost repo]# yum install -y java2、下载jenkins的yum源的配置文件jenkins.repo [rootlocalhost repo]# wget -O /etc/yum.repos.d/jenkins.repo http://pkg.j…

django开发环境搭建

django开发环境搭建 1、下载所需要的安装包 pycharm python3.7.9 2、安装pycharm python环境 3、Windows 安装mkvirtualenv虚拟python环境 pip install virtualenvwrapper-win4、下载必要的安装包&#xff08;只下载不安装&#xff09; pip download -d \home\packs virtu…

Java递归例子——求x的y幂次方

假设n的值大于0。 一&#xff1a;源程序&#xff1a; View Code packageone;publicclassRecursionTest {/*** paramargs*/publicstaticvoidmain(String[] args) {//TODO Auto-generated method stubRecursionTest rt newRecursionTest();intx 6;inty 2;longresult rt.getPower…

Android应用开发控件——Gallery和ImageSwitcher

Gallery组件主要用于横向显示图像列表&#xff0c;不过按常规做法。Gallery组件只能有限地显示指定的图像。也就是说&#xff0c;如果为Gallery组件指定了10张图像&#xff0c;那么当Gallery组件显示到第10张时&#xff0c;就不会再继续显示了。这虽然在大多数时候没有什么关系…

Windows7搭建FTP文件

Windows7搭建FTP文件 第一步&#xff1a;在任意一盘创建一个共享文件夹&#xff0c;这里我们把它命名为“ftp文件共享”&#xff0c;把需要共享的文件放里面&#xff0c;如图所示 第二步&#xff1a;安装IS组件 开始菜单→控制面板→程序→程序和功能→打开或关闭Windows功能…

Win7搭建http文件共享

Win7搭建http文件共享 作者&#xff1a;莫咸海 第一步&#xff1a;在除C盘以外的盘符中新建一个共享文件夹&#xff0c;命名为“http文件共享”&#xff1b; 将需要共享的文件放在“http文件共享”文件夹中。 第二步&#xff1a;安装IIS组件。开始菜单->控制面板->程序…

以命令方式从ftp服务器上下载和上传文件

** 以命令方式从ftp服务器上下载和上传文件 wang ** 1、“开始”→“运行”&#xff0c;输入“cmd“&#xff0c;打开命令提示符&#xff1b; 2、在命令提示符内输入”ftp“并回车&#xff0c;进入ftp提示符ftp> 3、在ftp>输入 open 192.168.2.5 回车&#xff1b; 如…

在windows环境下ftp服务器的文件上传和下载

在windows环境下ftp服务器的文件上传和下载 mo 一、上传本地文件 第一步&#xff1a;登录FTP服务器。在开始菜单中输入cmd&#xff0c;回车进入。输入ftp进入服务器&#xff0c;输入命令格式&#xff1a;open FTP服务器地址 端口&#xff0c;例如open 192.168.2.5 21 如果FTP端…

运维的未来之路:在技术革命中保持关键地位

在快速发展的IT界&#xff0c;运维工程师向来扮演着无可或缺的角色。他们不仅确保系统的平稳运行&#xff0c;还需要及时应对突发事件&#xff0c;优化各项技术实施。然而&#xff0c;伴随着技术的迭代和新工具的出现&#xff0c;一些人开始担忧35岁成为运维人员的职业半衰期。…

Ogre读取中文路径名的文件失败的解决办法

Ogre的文件读取是使用的标准库的io库读取的&#xff0c;众所周知的是&#xff0c;在vs2005是存在着bug的。因此想要一劳永逸的解决这个办法唯有去修改Ogre的源代码&#xff0c;以下为修改方法&#xff1a;打开OgreFileSystem.cpp文件&#xff0c;找到FileSystemArchive::open方…