views:

248

answers:

2

I am looking for a neat way to trap and fiddle with the CPUID instruction of Linux processes. Played around with ptrace() and patching all cpuid opcodes in all executable mmap'ed regions that are created by a process, replacing them by int3's. Didn't work that well since the CPUID opcode bytes appears quite often as parts of other longer opcodes.

So basically I am looking for some way that allows me to set a breakpoint not on a specific memory address but instead on every invocation of an opcode. Anyone has a good idea how to do that?

A: 

No easy nice way to do that I'm aware of.

A nasty way might be to use GDB's python scripting API to automatically single-step through the program, examining each instruction before it is executed.

Another nasty way might be to grab the source for something like Bochs, an open-source x86 emulator, and alter it so it does what you want when the instructions you are interested in are executed.

moonshadow
+1  A: 

In general the only way to do this on arbitrary x86 code and catch all corner-cases is to either:

  • single-step and examine each instruction before it's executed (PTRACE_SINGLESTEP, see below); or
  • fully emulate the x86 instruction set.

The first way is probably better.

(Trying to decompile the opcodes other than just-in-time with single-stepping doesn't work because it won't catch cases like self-modifying code or jumping into the middle of another instruction).

To implement the single-stepping method, each time the traced process stops, you would use PTRACE_GETREGS to get the child's registers, then use the child's %eip register value as an address to pass to PTRACE_PEEKTEXT, getting the next word to be executed. Examine that word to see if it's a CPUID instruction - if it is, emulate the instruction by adjusting the child's register set (including advancing %eip past the CPUID instruction). Then call PTRACE_SINGLESTEP to let the process continue.

caf