日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

[Advance] How to debug a program (上)

發布時間:2023/11/27 生活经验 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [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處理器構架的應用程序二進制接口


作者:zhenjing.chen?
出處:http://www.cnblogs.com/zhenjing/?
未注明轉載的文章,版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。

轉載于:https://www.cnblogs.com/xumaojun/p/8533130.html

總結

以上是生活随笔為你收集整理的[Advance] How to debug a program (上)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。