{"id":295,"date":"2025-12-22T14:49:32","date_gmt":"2025-12-22T14:49:32","guid":{"rendered":"https:\/\/haco.club\/?p=295"},"modified":"2025-12-22T14:49:32","modified_gmt":"2025-12-22T14:49:32","slug":"gdb-usage","status":"publish","type":"post","link":"https:\/\/haco.club\/?p=295","title":{"rendered":"GDB Usage"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Check memory layout<\/h2>\n\n\n\n<p>To check the memory layout of a binary in GDB, you can use different commands depending on whether the program is currently running or if you are just inspecting the static binary file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. If the Program is Running<\/h3>\n\n\n\n<p>The best command to see the virtual memory mappings (including the heap, stack, and loaded libraries) is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>info proc mappings<\/code><\/pre>\n\n\n\n<p><strong>What it shows:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Start\/End Addr:<\/strong> The virtual address range.<\/li>\n\n\n\n<li><strong>Size:<\/strong> The size of the mapped region.<\/li>\n\n\n\n<li><strong>Offset:<\/strong> Offset into the file (if file-backed).<\/li>\n\n\n\n<li><strong>Objfile:<\/strong> The specific file backing this memory (e.g., <code>\/bin\/bash<\/code>, <code>[heap]<\/code>, <code>[stack]<\/code>, or shared libraries like <code>libc.so<\/code>).<\/li>\n<\/ul>\n\n\n\n<p><strong>Example Output:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(gdb) info proc mappings\nprocess 12345\nMapped address spaces:\n\n          Start Addr           End Addr       Size     Offset objfile\n      0x555555554000     0x555555558000     0x4000        0x0 \/path\/to\/binary\n      0x555555757000     0x555555758000     0x1000     0x3000 \/path\/to\/binary\n      0x555555758000     0x555555759000     0x1000     0x4000 \/path\/to\/binary\n      0x7ffff7dc0000     0x7ffff7fc0000   0x200000        0x0 &#91;heap]\n      0x7ffffffde000     0x7ffffffff000    0x21000        0x0 &#91;stack]<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. If the Program is NOT Running (or for Section Headers)<\/h3>\n\n\n\n<p>If you want to see how the binary&#8217;s sections (like <code>.text<\/code>, <code>.data<\/code>, <code>.bss<\/code>) are laid out, use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>maintenance info sections<\/code><\/pre>\n\n\n\n<p><em>(Short form: <code>maint info sections<\/code>)<\/em><\/p>\n\n\n\n<p><strong>What it shows:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A list of all sections from the object file.<\/li>\n\n\n\n<li>The memory flags (READONLY, CODE, DATA).<\/li>\n\n\n\n<li>File offsets and virtual addresses.<\/li>\n<\/ul>\n\n\n\n<p><strong>Example Output:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(gdb) maint info sections\nExec file: `\/path\/to\/binary', file type elf64-x86-64.\n    0x00400238-&gt;0x00400254 at 0x00000238: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS\n    0x00400254-&gt;0x00400274 at 0x00000254: .note.ABI-tag ALLOC LOAD READONLY DATA HAS_CONTENTS\n    0x004003e0-&gt;0x00400404 at 0x000003e0: .plt ALLOC LOAD READONLY CODE HAS_CONTENTS\n    0x00400410-&gt;0x004005c2 at 0x00000410: .text ALLOC LOAD READONLY CODE HAS_CONTENTS<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3. Alternative: <code>info files<\/code><\/h3>\n\n\n\n<p>This command provides a summary of the current target file, including the entry point and the memory ranges for each section.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>info files<\/code><\/pre>\n\n\n\n<p><strong>Key Difference:<\/strong> It is less detailed than <code>maint info sections<\/code> regarding flags but is often cleaner if you just want to know where <code>.text<\/code> or <code>.data<\/code> starts and ends.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Summary of When to Use Which<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Command<\/th><th class=\"has-text-align-left\" data-align=\"left\">Usage Scenario<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong><code>info proc mappings<\/code><\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>Best for runtime analysis.<\/strong> Shows the real layout including Heap, Stack, and Shared Libs.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong><code>maint info sections<\/code><\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>Best for static analysis.<\/strong> Shows binary sections (.text, .bss) exactly as defined in the ELF\/PE header.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong><code>info files<\/code><\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Good general overview of the loaded file and its entry point.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Set breakpoint at entrypoint<\/h2>\n\n\n\n<p>To set a breakpoint at the true entry point of a binary (which is before <code>main()<\/code>), you can use one of the following methods depending on your GDB version and whether the binary has symbols.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Method 1: The One-Liner (Best for GDB 8.1+)<\/h3>\n\n\n\n<p>If you just want to run the program and stop at the very first instruction immediately, use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>starti<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> It acts like <code>run<\/code> but automatically stops at the first instruction (the entry point).<\/li>\n\n\n\n<li><strong>Note:<\/strong> This is different from <code>start<\/code>, which stops at <code>main<\/code>.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Method 2: Breaking by Symbol (Standard)<\/h3>\n\n\n\n<p>For most Linux binaries, the entry point is labeled <code>_start<\/code>. You can simply break there:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>break _start<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Why <code>_start<\/code>?<\/strong> This is the actual assembly entry point that initializes the C runtime (setting up stack, environment) before calling your <code>main<\/code> function.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Method 3: Manual Address (If Symbols are Stripped)<\/h3>\n\n\n\n<p>If the binary is &#8220;stripped&#8221; (has no symbols) or you want to be precise, you can find the entry point address and break on it explicitly.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Find the entry point address:<\/strong><br>Use the <code>info files<\/code> command inside GDB. <code>(gdb) info files<\/code> Look for the line that says <strong>&#8220;Entry point: 0x\u2026&#8221;<\/strong> at the top of the output.<\/li>\n\n\n\n<li><strong>Set the breakpoint:<\/strong><br>Use the <code>*<\/code> syntax before the address to tell GDB it is a memory location.<br><code>gdb (gdb) break *0x401050<\/code><br><em>(Replace <code>0x401050<\/code> with the actual address you found).<\/em><\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Summary Table<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Command<\/th><th class=\"has-text-align-left\" data-align=\"left\">Description<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong><code>starti<\/code><\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>Easiest.<\/strong> Starts program and stops at entry point immediately.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong><code>break _start<\/code><\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Sets a breakpoint at the standard entry label.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong><code>break *0x...<\/code><\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Sets a breakpoint at a raw memory address (requires <code>info files<\/code>).<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Inspect 2\/4\/8 bytes data<\/h2>\n\n\n\n<p>To inspect memory in specific byte chunks in GDB, you use the <code>x<\/code> (examine) command. The syntax generally looks like this:<\/p>\n\n\n\n<p><code>x \/&lt;count&gt;&lt;format&gt;&lt;size&gt; &lt;address&gt;<\/code><\/p>\n\n\n\n<p>Here are the specific commands for 2, 4, and 8 bytes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. The Short Answer (Hex format)<\/h3>\n\n\n\n<p>Assuming you want to look at the address stored in the register <code>$sp<\/code> (stack pointer) or a raw address like <code>0x400500<\/code>:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Data Size<\/th><th class=\"has-text-align-left\" data-align=\"left\">GDB Suffix<\/th><th class=\"has-text-align-left\" data-align=\"left\">Command Example<\/th><th class=\"has-text-align-left\" data-align=\"left\">Explanation<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong>2 Bytes<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>h<\/code> (Halfword)<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>x\/xh $sp<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Examine <strong>1<\/strong> unit of <strong>Hex<\/strong>, size <strong>Halfword<\/strong><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong>4 Bytes<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>w<\/code> (Word)<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>x\/xw $sp<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Examine <strong>1<\/strong> unit of <strong>Hex<\/strong>, size <strong>Word<\/strong><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong>8 Bytes<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>g<\/code> (Giant)<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>x\/xg $sp<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Examine <strong>1<\/strong> unit of <strong>Hex<\/strong>, size <strong>Giant<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">2. Detailed Syntax Explanation<\/h3>\n\n\n\n<p>The command is broken down as <code>x \/NFS addr<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>N (Count):<\/strong> How many units to display (e.g., <code>1<\/code>, <code>4<\/code>, <code>10<\/code>).<\/li>\n\n\n\n<li><strong>F (Format):<\/strong> How to display the data.\n<ul class=\"wp-block-list\">\n<li><code>x<\/code> = Hexadecimal (most common)<\/li>\n\n\n\n<li><code>d<\/code> = Decimal<\/li>\n\n\n\n<li><code>u<\/code> = Unsigned Decimal<\/li>\n\n\n\n<li><code>i<\/code> = Instruction (Assembly)<\/li>\n\n\n\n<li><code>s<\/code> = String<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>S (Size):<\/strong> The size of each unit.\n<ul class=\"wp-block-list\">\n<li><code>b<\/code> = Byte (1 byte)<\/li>\n\n\n\n<li><code>h<\/code> = Halfword (2 bytes)<\/li>\n\n\n\n<li><code>w<\/code> = Word (4 bytes) <em>(Note: In GDB, a &#8220;word&#8221; is 4 bytes, unlike x86 assembly where it is often 2).<\/em><\/li>\n\n\n\n<li><code>g<\/code> = Giant (8 bytes)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3. Examples<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Inspecting 2 Bytes (Halfword)<\/h4>\n\n\n\n<p>To see the value <code>0x1234<\/code> located at <code>0x7fffffffe000<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(gdb) x\/1xh 0x7fffffffe000\n0x7fffffffe000:    0x1234<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Inspecting 4 Bytes (Word) in Decimal<\/h4>\n\n\n\n<p>To see a standard integer (4 bytes) at a variable&#8217;s address:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(gdb) x\/1wd &amp;my_integer\n0x7fffffffe000:    500<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Inspecting multiple 8 Byte (Giant) chunks<\/h4>\n\n\n\n<p>To see the top 4 values on the stack (64-bit machine):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(gdb) x\/4xg $sp\n0x7fffffffe100:    0x00000000004005d6    0x00007fffffffe238\n0x7fffffffe110:    0x0000000000000001    0x00007ffff7de59a0<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Alternative: Using <code>print<\/code> with Casting<\/h3>\n\n\n\n<p>If you prefer C-style casting over raw memory inspection, you can use the <code>print<\/code> (or <code>p<\/code>) command. This is often useful if you want GDB to handle the types for you.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>2 Bytes:<\/strong> <code>p *(short *) 0x400500<\/code><\/li>\n\n\n\n<li><strong>4 Bytes:<\/strong> <code>p *(int *) 0x400500<\/code><\/li>\n\n\n\n<li><strong>8 Bytes:<\/strong> <code>p *(long long *) 0x400500<\/code><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Print the assembly at the same time executing<\/h2>\n\n\n\n<p>You can achieve this in three ways. The first is a simple command, the second is a setting, and the third uses GDB&#8217;s visual mode.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Option 1: The <code>display<\/code> Command (Classic)<\/h3>\n\n\n\n<p>This tells GDB to automatically print an expression every time the program stops (e.g., after every <code>si<\/code>).<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Run this command once: <code>display\/i $pc<\/code>\n<ul class=\"wp-block-list\">\n<li><code>display<\/code>: Show every time execution stops.<\/li>\n\n\n\n<li><code>\/i<\/code>: Format as instruction (assembly).<\/li>\n\n\n\n<li><code>$pc<\/code>: The Program Counter register (current instruction pointer).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Now, when you type <code>si<\/code>, GDB will automatically print the next instruction.<br><code>text (gdb) si 1: x\/i $pc => 0x40052d &lt;main+4>: sub $0x10,%rsp<\/code><\/li>\n<\/ol>\n\n\n\n<p><em>To stop this behavior later, type <code>undisplay<\/code>.<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Option 2: The <code>disassemble-next-line<\/code> Setting (Cleaner)<\/h3>\n\n\n\n<p>Newer versions of GDB have a specific setting for this. It is often cleaner than <code>display<\/code> because it integrates the assembly into the standard stop message.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Run this command: <code>set disassemble-next-line on<\/code><\/li>\n\n\n\n<li>Now, when you <code>si<\/code> (or <code>ni<\/code>), it shows the instruction automatically:<br><code>text (gdb) si 0x0000000000401126 4 printf(\"Hello\\n\"); 0x0000000000401126 &lt;+4>: 48 83 ec 10 sub $0x10,%rsp<\/code><\/li>\n<\/ol>\n\n\n\n<p><em>This typically shows both the source line (if available) and the assembly instruction.<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Option 3: TUI Mode (Visual Split Screen)<\/h3>\n\n\n\n<p>This is usually the most helpful method. It splits your terminal window: the top half shows the scrolling assembly code with a highlighter on the current line, and the bottom half is your command prompt.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Enable it by typing: <code>layout asm<\/code> <em>(Or <code>layout split<\/code> to see both C source code and Assembly together).<\/em><\/li>\n\n\n\n<li>Now when you type <code>si<\/code>, the highlighter in the top window simply moves down one line.<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Tip:<\/strong> If the screen gets messed up (garbled text), press <code>Ctrl+L<\/code> to refresh it.<\/li>\n\n\n\n<li><strong>Tip:<\/strong> Press <code>Ctrl+X<\/code> then <code>A<\/code> to exit this mode.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Check memory layout To check the memory layout of a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[50,10],"class_list":["post-295","post","type-post","status-publish","format-standard","hentry","category-tutotial","tag-gdb","tag-toolchain"],"_links":{"self":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/295","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=295"}],"version-history":[{"count":1,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/295\/revisions"}],"predecessor-version":[{"id":296,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/295\/revisions\/296"}],"wp:attachment":[{"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=295"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=295"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}