From 21e8db012f8c46f75e43a40da3f3e2676363c291 Mon Sep 17 00:00:00 2001 From: johannst Date: Sat, 14 Mar 2020 18:01:23 +0000 Subject: deploy: 951ccb67565f34a0aa1b23ad6eef647aed5e0b4b --- index.html | 236 ++++++++++++++++++++++++++++--------------------------------- 1 file changed, 107 insertions(+), 129 deletions(-) (limited to 'index.html') diff --git a/index.html b/index.html index b8fc51b..425ada7 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - gdb - Notes + ld.so - Notes @@ -81,7 +81,7 @@ @@ -148,135 +148,105 @@
-

gdb(1)

-

CLI

-
  gdb [opts] [prg [-c coredump | -p pid]]
-  gdb [opts] --args prg <prg-args>
-    opts:
-      -p <pid>        attach to pid
-      -c <coredump>   use <coredump>
-      -x <file>       execute script <file> before prompt
-      -ex <cmd>       execute command <cmd> before prompt
-      --tty <tty>     set I/O tty for debugee
+                        

ld.so(8)

+

Environment variables

+
  LD_PRELOAD=<l_so>       colon separated list of libso's to be pre loaded
+  LD_DEBUG=<opts>         comman separated list of debug options
+          =help           list available options
+          =libs           show library search path
+          =files          processing of input files
+          =symbols        show search path for symbol lookup
+          =bindings       show against which definition a symbol is bound
 
-

Interactive usage

-
  tty <tty>
-          Set <tty> as tty for debugee.
-          Make sure nobody reads from target tty, easiest is to spawn a shell
-          and run following in target tty:
-          > while true; do sleep 1024; done
-
-  set follow-fork-mode <child | parent>
-          Specify which process to follow when debuggee makes a fork(2)
-          syscall.
-
-  sharedlibrary [<regex>]
-          Load symbols of shared libs loaded by debugee. Optionally use <regex>
-          to filter libs for symbol loading.
-
-  break [-qualified] <sym> thread <tnum>
-          Set a breakpoint only for a specific thread.
-          -qualified: Tred <sym> as fully qualified symbol (quiet handy to set
-          breakpoints on C symbols in C++ contexts)
-
-  rbreak <regex>
-          Set breakpoints matching <regex>, where matching internally is done
-          on: .*<regex>.*
-
-  command [<bp_list>]
-          Define commands to run after breakpoint hit. If <bp_list> is not
-          specified attach command to last created breakpoint. Command block
-          terminated with 'end' token.
-
-          <bp_list>: Space separates list, eg 'command 2 5-8' to run command
-          for breakpoints: 2,5,6,7,8.
-
-  info functions [<regex>]
-          List functions matching <regex>. List all functions if no <regex>
-          provided.
-
-  info variables [<regex>]
-          List variables matching <regex>. List all variables if no <regex>
-          provided.
-
-  info handle [<signal>]
-          Print how to handle <signal>. If no <signal> specified print for all
-          signals.
-
-  handle <signal> <action>
-          Configure how gdb handles <signal> sent to debugee.
-          <action>:
-            stop/nostop       Catch signal in gdb and break.
-            print/noprint     Print message when gdb catches signal.
-            pass/nopass       Pass signal down to debugee.
-
-  catch signal <signal>
-          Create a catchpoint for <signal>.
+

LD_PRELOAD load & init order

+
  > ldd ./main
+    >> libc.so.6 => /usr/lib/libc.so.6
+
+  > LD_PRELOAD=liba.so:libb.so ./main
+             -->
+      preloaded in this order
+             <--
+      initialized in this order
+
+  - preload order determines the order libs are inserted into the link map
+
+  - resulting link map:
+      +------+    +------+    +------+    +------+
+      | main | -> | liba | -> | libb | -> | libc |
+      +------+    +------+    +------+    +------+
+
+  - see preload and init order in action
+    > LD_DEBUG=files LD_PRELOAD=liba.so:libb.so ./main
+      # load order (-> determines link map)
+      >> file=liba.so [0];  generating link map
+      >> file=libb.so [0];  generating link map
+      >> file=libc.so.6 [0];  generating link map
+
+      # init order
+      >> calling init: /usr/lib/libc.so.6
+      >> calling init: <path>/libb.so
+      >> calling init: <path>/liba.so
+      >> initialize program: ./main
+
+  - see the symbol lookup in action and therefore the link map order
+    > LD_DEBUG=symbols,bindings LD_PRELOAD=liba.so:libb.so ./main
+      >> symbol=memcpy;  lookup in file=./main [0]
+      >> symbol=memcpy;  lookup in file=<path>/liba.so [0]
+      >> symbol=memcpy;  lookup in file=<path>/libb.so [0]
+      >> symbol=memcpy;  lookup in file=/usr/lib/libc.so.6 [0]
+      >> binding file ./main [0] to /usr/lib/libc.so.6 [0]: normal symbol
+         `memcpy' [GLIBC_2.14]
 
-

User commands (macros)

-
  define <cmd>
-    # cmds
-  end
-
-  document <cmd>
-    # docu
-  end
-
-  help user-defined             List user defined commands.
-  help <cmd>                    List documentation for command <cmd>.
-
-

Hooks

-

Gdb allows to create two types of command hooks which will be either executed -before or after a certain command.

-
  define hook-<cmd>             Run commands defined in hook before
-    # cmds                      executing <cmd>.
-  end
-
-  define hookpost-<cmd>         Run commands defined in hookpost after
-    # cmds                      executing <cmd>.
-  end
-
-

Flows

-

Catch SIGSEGV and execute commands on occurrence

-
  catch signal SIGSEGV
-  command
-    bt
-    c
-  end
-
-

Run backtrace on thread 1 (batch mode)

-
  gdb --batch -ex 'thread 1' -ex 'bt' -p <pid>
-
-

Script gdb for automating debugging sessions

-
# run.gdb
-  set pagination off
-
-  break mmap
-  command
-    info reg rdi rsi rdx
-    bt
-    c
-  end
-
-  #initial drop
-  c
-
-

This script can be used as:

-
  gdb -p <pid> -x ./run.gdb  --batch &> run.log
-
-

Workaround command + finish bug

-

When using finish action inside a command block, actions after finish are -not executed anymore. To workaround that bug one can create a wrapper function -which calls finish.

-
  define handler
-  bt
-  finish
-  info reg rax
-  end
-
-  command
-  handler
-  end
+

dynamic linking (x86_64)

+
  - dynamic linking basically works via one indirect jump. It uses a
+    combination of function trampolines (.plt) and a function pointer table
+    (.got.plt). On the first call the trampoline sets up some metadata and
+    then jumps to the ld.so runtime resolve function, which in turn patches
+    the table with the correct function pointer.
+      .plt ....... contains function trampolines, usually located in code
+                   segment (rx permission)
+      .got.plt ... hold the function pointer table
+
+  - following r2 dump shows this
+      - [0x00401030] indirect jump for 'puts' using function pointer in
+        _GLOBAL_OFFSET_TABLE_[3]
+      - initially points to instruction behind 'puts' trampoline [0x00401036]
+      - this pushes relocation index and then jumps to the first trampoline
+        [0x00401020]
+      - the first trampoline jumps to _GLOBAL_OFFSET_TABLE_[2] which will be
+        filled at program startup by the ld.so with its resolve function
+      - the resolve function fixes the relocation referenced by the
+        relocation index pushed by the 'puts' trampoline
+      - the relocation entry tells the resolve function which symbol to
+        search for and where to put the function pointer
+          > readelf -r <main>
+            >> Relocation section '.rela.plt' at offset 0x4b8 contains 1 entry:
+            >>   Offset          Info           Type           Sym. Value    Sym. Name + Addend
+            >> 000000404018  000200000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0
+          - offset points to _GLOBAL_OFFSET_TABLE_[3]
+
+      [0x00401040]> pd 4 @ section..got.plt
+                  ;-- section..got.plt:
+                  ;-- .got.plt:    ; [22] -rw- section size 32 named .got.plt
+                  ;-- _GLOBAL_OFFSET_TABLE_:
+                  0x00404000      .qword 0x0000000000403e10 ; section..dynamic ; obj._DYNAMIC
+                  0x00404008      .qword 0x0000000000000000
+                  ; CODE XREF from section..plt @ +0x6
+                  0x00404010      .qword 0x0000000000000000
+                  ;-- reloc.puts:
+                  ; CODE XREF from sym.imp.puts @ 0x401030
+                  0x00404018      .qword 0x0000000000401036                  ; RELOC 64 puts
+
+      [0x00401040]> pd 6 @ section..plt
+                  ;-- section..plt:
+                  ;-- .plt:       ; [12] -r-x section size 32 named .plt
+              ┌─> 0x00401020      ff35e22f0000   push qword [0x00404008]
+              ╎   0x00401026      ff25e42f0000   jmp qword [0x00404010]
+              ╎   0x0040102c      0f1f4000       nop dword [rax]
+      ┌ 6: int sym.imp.puts (const char *s);
+      └       ╎   0x00401030      ff25e22f0000   jmp qword [reloc.puts]
+              ╎   0x00401036      6800000000     push 0
+              └─< 0x0040103b      e9e0ffffff     jmp sym..plt
 
@@ -286,6 +256,10 @@ which calls finish.

+ +
@@ -296,6 +270,10 @@ which calls finish.

+ +
-- cgit v1.2.3