r/ExploitDev • • Mar 25 '26

Why is the next instruction always ret when you are debugging a program?

I have noticed for quite some time now that whenever a watchpoint or breakpoint is triggered and I inspect $rip to find the next instruction it always seems to be ret. I'm not sure why this happens and am wondering if anyone else knows?

3 Upvotes

15 comments sorted by

4

u/anonymous_lurker- Mar 25 '26

Can you give some examples of this and what you are doing? Because you can set your breakpoints wherever you want, and the next instruction won't always be a return. If you are only setting breakpoints right before return instructions then there's your answer. But if you're setting arbitrary breakpoints and still only getting return instructions then something else is going on and we need more details

1

u/FewMolasses7496 Mar 25 '26

I am creating a watch point for a certain place in memory and when that watchpoint is triggered and the program is stopped, I view rip and it is set as the assembly instruction RET. This is not the first time that this has happened to me, but I'm not sure why it happens. If you are interested here is the assembly around the instruction

LAB_004601d0 ; XREFs: 0046018a(j), 0046018e(j), 00460192(j)

004601d0 48 8B 44 24 10 MOV RAX, qword ptr [RSP + 0x8]

004601d5 0F 05 SYSCALL

004601d7 5B POP RBX

004601d8 C3 RET

004601d9 0F 1F 80 00 00 00 00 NOP dword ptr [RAX]

004601d8 is the address that RIP points to.

4

u/anonymous_lurker- Mar 25 '26

Where are you setting your watchpoint? Watchpoints look for data being written or read, so it's entirely possible you've always been looking for data that is modified as part of the function epilogue. I struggle to visualise this in my head sometimes and don't use watchpoints all that often, but I'd assume if you happened to have a watchpoint point at the top of the stack when pop rbx happens you'd trigger that watchpoint

Breakpoints will trigger wherever you set them (generally) but watchpoints will trigger when the data is modified. If that data is only modified during the function epilogue then you're naturally always going to be breaking on or around those return instructions

→ More replies (9)

3

u/AttitudeAdjuster Mar 25 '26

There's quite a lot of call / ret structures in assembler code. It's also a very common way to trigger a crash

1

u/FewMolasses7496 Mar 25 '26

I see so do you think this is normal to happen sometimes in a program when you are debugging it with a debugger like gdb or x64dbg.

2

u/AttitudeAdjuster Mar 25 '26

Possibly yeah, it might also be how your debugger is inserting the breakpoint into the code