对命令行输入的简单C程序进行缓冲区溢出操作遇问题
Hey there, let's walk through fixing your buffer overflow issue to redirect execution from func()'s normal return to chgflow()—I've debugged plenty of these, so let's break it down step by step.
chgflow() 1. Grab Critical Memory Addresses
First, you need two key details to make this work:
chgflow()'s start address: You can get this either viagdbor your existingobjdumpoutput.- In
gdb, runprint &chgflowand jot down the hex value (e.g.,0x401156). - From
objdump -d ./main, look for the line starting with0xXXXXXX <chgflow>:—that's your target jump address.
- In
- Buffer-to-return-address offset: This tells you how much garbage data you need to fill before overwriting the return address on the stack.
- Generate a unique pattern (e.g., using
pattern_create 100ingdb-peda), feed it into the program until it crashes. - Check the value in the
eip(32-bit) orrip(64-bit) register, then usepattern_offset <eip-value>to get the exact offset.
- Generate a unique pattern (e.g., using
2. Compile With Protections Disabled
Your compile command must turn off stack security features that block overflow attempts—use this:
gcc -fno-stack-protector -z execstack -o main main.c
-fno-stack-protector: Disables stack canary checks that detect overflowed buffers.-z execstack: Makes the stack executable (not strictly necessary for just jumping to an existing function, but avoids unexpected issues).
Also, disable system-wide address randomization so addresses don't shift between runs:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
3. Build Your Payload
Your payload needs two simple parts:
- Garbage data to fill the buffer and reach the return address (use the offset you calculated earlier).
- The little-endian version of
chgflow()'s address (since x86/x86_64 systems use little-endian byte ordering).
For example, if your offset is 20 bytes and chgflow() is at 0x401156 (32-bit):
python3 -c "print('A'*20 + '\x56\x11\x40\x00')" > payload.txt
- 64-bit note: Use 8 bytes for the address, reversed. For
0x40115600, that would be\x00\x56\x11\x40\x00\x00\x00\x00.
4. Debug & Verify the Redirect
Use gdb to confirm your payload works as expected:
gdb ./main # Set a breakpoint at func()'s return instruction (find the address from your objdump output) break *0x40113a # Replace with the actual ret address from your assembly dump run < payload.txt
When the breakpoint hits, check the stack to confirm the overwrite:
- 32-bit: Run
x/24x $espto see if the value right after your garbageAs is set tochgflow()'s address. - 64-bit: Run
x/24x $rspinstead.
If everything looks correct, type continue—the program should jump to chgflow() instead of executing the normal return path.
Common Pitfalls to Troubleshoot
- Wrong offset: Double-check the pattern offset calculation—even one byte off will break the redirect.
- Endianness mistake: Always reverse the address bytes (little-endian). If you use the raw hex address, the CPU will read it backwards.
- Input truncation: If your address has a
\x00byte, functions likescanfwill stop reading early. Use a different input method (likeread()in your C program) or adjust your payload.
内容的提问来源于stack exchange,提问作者Marco_81

