Skipping the instruction after IRET

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Suzuran
Posts: 2
Joined: Mon Jan 02, 2017 4:55 am

Skipping the instruction after IRET

Post by Suzuran »

In x86 long mode, is there a better way to skip the instruction after IRET than parsing the bytes at the stored IP and working out how much to add to it?

Modifying the bytes at IP isn't an option because I don't want the change to be "permanent".
Octocontrabass
Member
Member
Posts: 5578
Joined: Mon Mar 25, 2013 7:01 pm

Re: Skipping the instruction after IRET

Post by Octocontrabass »

No.

Why do you want to skip the instruction?
Suzuran
Posts: 2
Joined: Mon Jan 02, 2017 4:55 am

Re: Skipping the instruction after IRET

Post by Suzuran »

Because it's a non-fatal condition and I don't want the failing instruction to be retried.

To vastly simplify, what's going on is GC trickery; If a page contains candidates for garbage collection, I tag it oldspace and make it read-only. If something later tries to write to the page, it will page fault, allowing me to trap the write. The kernel will do the right thing for the object that was touched, but not the entire page. Since the kernel has completed the write, having the program try it again will loop.

Later I can GC the objects in the page that didn't get written to and keep just what's being actively used.
MollenOS
Member
Member
Posts: 202
Joined: Wed Oct 26, 2011 12:00 pm

Re: Skipping the instruction after IRET

Post by MollenOS »

No, you would need to parse the assembly pointed to by the IP and figure out the length of that instruction and add it to the IP. There is no easy way to solve that.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Skipping the instruction after IRET

Post by bzt »

Hi Suzuran,

If you're using long mode (64 bit), you could try my disassembler: https://gitlab.com/bztsrc/osz/blob/mast ... 4/disasm.h. It has one function only:

Code: Select all

virt_t disasm(virt_t addr, char *str)
Where "virt_t" is a virtual address, uint64_t. This function receives an address, and returns the address of the next instruction. You obviously won't need the disassembled string, so just pass NULL as the second argument.

Code: Select all

nextinst = disasm(exceptioninst, NULL);
For protected mode (32 bit), you might want to take a look at OpenBSD's version: https://github.com/openbsd/src/blob/mas ... b_disasm.c. It has a very similar interface:

Code: Select all

vaddr_t db_disasm(vaddr_t loc, int altfmt);
but it is not that trivial to reuse this code as it is a bit tied up with other parts of the BSD kernel (but not particularly hard either, just provide you own db_access implementation), and you'll have to manually remove the disassembled string writes from the code (all those db_print* calls). But at the end, it will do the job.

Cheers,
bzt
Post Reply