Skip to content

Functions¤

pwndbg provides a set of functions which can be used during expression evaluation to quickly perform common calculations. These can even be passed to other commands as arguments. Currently, they only work in gdb.

To see a list of all functions, including those built into gdb, use help function. To see the help of any given function use help function function_name. Function invokation must include a preceding $ sign and must include brackets. For instance, invoke the environ function like so:

pwndbg> p $environ("LANG")
$2 = (signed char *) 0x7fffffffe6da "LANG=en_US.UTF-8"
If the result of the function is being passed to a pwndbg command, make sure to either escape the function argument's quotes, or put the whole function call in quotes.
pwndbg> tele $environ("LANG")
usage: telescope [-h] [-r] [-f] [-i] [address] [count]
telescope: error: argument address: debugger couldn't resolve argument '$environ(LANG)':
    No symbol "LANG" in current context.
pwndbg> tele $environ(\"LANG\")
00:0000│  0x7fffffffe6cf ◂— 'LANG=en_US.UTF-8'
01:0008│  0x7fffffffe6d7 ◂— 'US.UTF-8'
02:0010│  0x7fffffffe6df ◂— 0x4e49475542454400
[...]
pwndbg> tele '$environ("LANG")'
00:0000│  0x7fffffffe6cf ◂— 'LANG=en_US.UTF-8'
01:0008│  0x7fffffffe6d7 ◂— 'US.UTF-8'
02:0010│  0x7fffffffe6df ◂— 0x4e49475542454400
[...]

pwndbg functions¤

rebase¤

rebase(addr: gdb.Value | int) -> int

Description¤

Return address rebased onto the executable's mappings.

Example¤

pwndbg> p/x $rebase(0xd9020)
$1 = 0x55555562d020
pwndbg> vmmap
0x555555554000     0x55555556f000 r--p    1b000      0 /usr/bin/bash
0x55555556f000     0x55555562d000 r-xp    be000  1b000 /usr/bin/bash
0x55555562d000     0x55555565e000 r--p    31000  d9000 /usr/bin/bash
[...]
pwndbg> p $rebase(0xd9020) == 0x555555554000 + 0xd9020
$2 = 1
pwndbg> tele $rebase(0xd9020)
00:0000│  0x55555562d020 ◂— 0x204900636f6c6c61 /* 'alloc' */
01:0008│  0x55555562d028 ◂— 'have no name!'
02:0010│  0x55555562d030 ◂— 0x65720021656d616e /* 'name!' */
03:0018│  0x55555562d038 ◂— 'adline stdin'
[...]

base¤

base(name_pattern: gdb.Value | str) -> int

Description¤

Return the base address of the first memory mapping containing the given name.

Example¤

pwndbg> p/x $base("libc")
$4 = 0x7ffff7d4b000
pwndbg> vmmap libc
    0x7ffff7d4a000     0x7ffff7d4b000 rw-p     1000  6e000 /usr/lib/libncursesw.so.6.5
►   0x7ffff7d4b000     0x7ffff7d6f000 r--p    24000      0 /usr/lib/libc.so.6
►   0x7ffff7d6f000     0x7ffff7ed6000 r-xp   167000  24000 /usr/lib/libc.so.6
►   0x7ffff7ed6000     0x7ffff7f2b000 r--p    55000 18b000 /usr/lib/libc.so.6
►   0x7ffff7f2b000     0x7ffff7f2f000 r--p     4000 1e0000 /usr/lib/libc.so.6
►   0x7ffff7f2f000     0x7ffff7f31000 rw-p     2000 1e4000 /usr/lib/libc.so.6
    0x7ffff7f31000     0x7ffff7f39000 rw-p     8000      0 [anon_7ffff7f31]
pwndbg> tele $base(\"libc\")+0x1337
00:0000│  0x7ffff7d4c337 ◂— 0x80480a04214000f0
01:0008│  0x7ffff7d4c33f ◂— 0x8040c02204452040
02:0010│  0x7ffff7d4c347 ◂— 0x20042400000200
03:0018│  0x7ffff7d4c34f ◂— 0x20 /* ' ' */
[...]

Beware of accidentally matching the wrong mapping. For instance, if the loaded executable contained the string "libc" anywhere in it's path, it would've been returned.


hex2ptr¤

hex2ptr(hex_string: gdb.Value | str) -> int

Description¤

Converts a hex string to a little-endian address and returns the address.

Example¤

pwndbg> p/x $hex2ptr("20 74 ed f7 ff 7f")
$1 = 0x7ffff7ed7420
pwndbg> p/x $hex2ptr("2074edf7ff7f")
$2 = 0x7ffff7ed7420
pwndbg> distance '$base("libc")' '$hex2ptr("20 74 ed f7 ff 7f")'
0x7ffff7d4b000->0x7ffff7ed7420 is 0x18c420 bytes (0x31884 words)

Especially useful for quickly converting pwntools output.


argc¤

argc() -> int

Description¤

Get the number of program arguments. Evaluates to argc.

Example¤

pwndbg> p $argc()
$1 = 2
pwndbg> argv
00:0000│  0x7fffffffe288 —▸ 0x7fffffffe659 ◂— '/usr/bin/cat'
01:0008│  0x7fffffffe290 —▸ 0x7fffffffe666 ◂— 'gdbinit.py'
02:0010│  0x7fffffffe298 ◂— 0

argv¤

argv(index: gdb.Value) -> gdb.Value

Description¤

Get the n-th program argument. Evaluate argv on the supplied value.

Example¤

pwndbg> p $argv(0)
$11 = (signed char *) 0x7fffffffe666 "/usr/bin/sh"
pwndbg> argv
00:0000│  0x7fffffffe2a8 —▸ 0x7fffffffe666 ◂— '/usr/bin/sh'
01:0008│  0x7fffffffe2b0 ◂— 0

environ¤

environ(env_name: gdb.Value) -> gdb.Value

Description¤

Get an environment variable by name. Evaluate getenv() on the supplied value.

Example¤

pwndbg> p $environ("LANG")
$2 = (signed char *) 0x7fffffffebfb "LANG=en_US.UTF-8"

envp¤

envp(index: gdb.Value) -> gdb.Value

Description¤

Get the n-th environment variable. Evaluate envp on the supplied value.

Example¤

pwndbg> p $envp(0x3F)
$13 = (signed char *) 0x7fffffffef7d "LANG=en_US.UTF-8"
pwndbg> p $envp(0x3F) == $environ("LANG")
$14 = 1

fsbase¤

fsbase(offset: gdb.Value = gdb.Value(0)) -> int

Description¤

Get the value of the FS segment register. Only valid on x86(-64).

Example¤

pwndbg> p/x $fsbase()
$3 = 0x7ffff7cdab80
pwndbg> p $fs_base == $fsbase()
$4 = 1
pwndbg> x/gx $fsbase(0x28)
0x7ffff7cdaba8:     0x4da926e1668e5a00
pwndbg> x/gx $fsbase(0x30)
0x7ffff7cdabb0:     0x190a86d93bccf0ad
pwndbg> tls
Thread Local Storage (TLS) base: 0x7ffff7cdab80
TLS is located at:
    0x7ffff7cda000     0x7ffff7cdc000 rw-p     2000      0 [anon_7ffff7cda]
Dumping the address:
tcbhead_t @ 0x7ffff7cdab80
    0x00007ffff7cdab80 +0x0000 tcb                  : 0x7ffff7cdab80
    0x00007ffff7cdab88 +0x0008 dtv                  : 0x7ffff7cdb4f0
    0x00007ffff7cdab90 +0x0010 self                 : 0x7ffff7cdab80
    0x00007ffff7cdab98 +0x0018 multiple_threads     : 0x0
    0x00007ffff7cdab9c +0x001c gscope_flag          : 0x0
    0x00007ffff7cdaba0 +0x0020 sysinfo              : 0x0
    0x00007ffff7cdaba8 +0x0028 stack_guard          : 0x4da926e1668e5a00
    0x00007ffff7cdabb0 +0x0030 pointer_guard        : 0x190a86d93bccf0ad
    [...]
pwndbg> canary
[...]
Canary    = 0x4da926e1668e5a00 (may be incorrect on != glibc)
[...]
FS will usually point to the start of the TLS. If you're not providing an offset, it is usually easier to use gdb's builtin $fs_base variable.


gsbase¤

gsbase(offset: gdb.Value = gdb.Value(0)) -> int

Description¤

Get the value of the GS segment register. Only valid on x86(-64).

Example¤

pwndbg> p/x $gsbase()
$1 = 0x0
The value of the GS register is more interesting when doing kernel debugging:
pwndbg> p/x $gsbase()
$1 = 0xffff999287a00000
pwndbg> tele $gsbase()
00:0000│  0xffff999287a00000 ◂— 0
... ↓     4 skipped
05:0028│  0xffff999287a00028 ◂— 0xd6aa9b336d52a400
06:0030│  0xffff999287a00030 ◂— 0
07:0038│  0xffff999287a00038 ◂— 0
pwndbg> p $gsbase() == $gs_base
$2 = 1
If you're not providing an offset, it is usually easier to use gdb's builtin $gs_base variable.


bn_sym¤

bn_sym(name_val: gdb.Value) -> int | None

Description¤

Lookup a symbol's address by name from Binary Ninja.

This function sees symbols like functions and global variables, but not stack local variables, use bn_var for that.

Example¤

pwndbg> set integration-provider binja
Pwndbg successfully connected to Binary Ninja (4.2.6455 Personal) xmlrpc: http://127.0.0.1:31337
Set which provider to use for integration features to 'binja'.
pwndbg> p main
No symbol "main" in current context.
pwndbg> p/x $bn_sym("main")
$2 = 0x555555555645
pwndbg> b *($bn_sym("main"))
Breakpoint 1 at 0x555555555645

bn_var¤

bn_var(name_val: gdb.Value) -> int | None

Description¤

Lookup a stack variable's address by name from Binary Ninja.

This function doesn't see functions or global variables, use bn_sym for that.

Example¤

pwndbg> set integration-provider binja
Pwndbg successfully connected to Binary Ninja (4.2.6455 Personal) xmlrpc: http://127.0.0.1:31337
Set which provider to use for integration features to 'binja'.
pwndbg> p user_choice
No symbol "user_choice" in current context.
pwndbg> p/x $bn_var("user_choice")
$4 = 0x7fffffffe118
pwndbg> vmmap $4
    0x7ffff7ffe000     0x7ffff7fff000 rw-p     1000      0 [anon_7ffff7ffe]
►   0x7ffffffde000     0x7ffffffff000 rw-p    21000      0 [stack] +0x20118
pwndbg> p/x $bn_var("main")
TypeError: Could not convert Python object: None.
Error while executing Python code.

bn_eval¤

bn_eval(expr: gdb.Value) -> int | None

Description¤

Parse and evaluate a Binary Ninja expression.

Read more about binary ninja expressions here: https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.BinaryView.parse_expression

All registers in the current register set are available as magic variables (e.g. $rip). The $piebase magic variable is also included, with the computed executable base.

This function cannot see stack local variables.

Example¤

pwndbg> set integration-provider binja
Pwndbg successfully connected to Binary Ninja (4.2.6455 Personal) xmlrpc: http://127.0.0.1:31337
Set which provider to use for integration features to 'binja'.
pwndbg> p/x $bn_eval("10+20")
$6 = 0x30
pwndbg> p/x $bn_eval("main")
$7 = 0x1645
pwndbg> p/x $rebase($bn_eval("main"))
$8 = 0x555555555645
pwndbg> p some_global_var
No symbol "some_global_var" in current context.
pwndbg> p/x $rebase($bn_eval("some_global_var+$rax"))
$9 = 0x5555555586b8
pwndbg> p $rebase($bn_eval("some_global_var+$rax")) == $bn_sym("some_global_var") + $rax
$10 = 1
pwndbg> p $bn_eval("$piebase+some_global_var+$rax") == $bn_sym("some_global_var") + $rax
$11 = 1

ida¤

ida(name: gdb.Value) -> int

Description¤

Lookup a symbol's address by name from IDA. Evaluate ida.LocByName() on the supplied value.

This functions doesn't see stack local variables.

Example¤

pwndbg> set integration-provider ida
Pwndbg successfully connected to Ida Pro xmlrpc: http://127.0.0.1:31337
Set which provider to use for integration features to 'ida'.
pwndbg> p main
No symbol "main" in current context.
pwndbg> p/x $ida("main")
$1 = 0x555555555645
pwndbg> b *$ida("main")
Breakpoint 2 at 0x555555555645