PIN me if you can

Or how to escape PIN in 5 instructions, using the self-modification technique seen in the previous post. Ready ? Go:

#include <stdio.h>
main() {
  asm("call foo\n\t"
      "foo: pop %rax\n\t"
      "movl $0x4004e7, 10(%eax)\n\t"  // put @nottraced() in the next mov
      "movl $0x4004fb, %eax\n\t"      // @traced(), will be overwritten
                                      // by @nottraced() if not instrumented
      "call *%rax\n\t");
// we don't want PIN to analyse this
nottraced() {
  printf("trace me if you can!\n");
// we want PIN to analyse this, a dummy function
traced() {
  printf("you're not supposed to get here\n");

As usual: compile, make the .text section and the program header writable, and run.

reynaudd@lhs-2:~/test/packed$ ./escape2
trace me if you can!
reynaudd@lhs-2:~/test/packed$ pin -t ../pin-2.5-24110-gcc.4.0.0-ia32_intel64-linux/source/tools/ManualExamples/obj-intel64/ -- ./escape2
you're not supposed to get here

‘Nuff said.

UPDATE: as the authors of PIN pointed out, this situation in handled correctly by PIN with the option -smc_strict. That’s because for performance reasons (and standards compliance), PIN makes the assumption that there is at least a taken branch between a modification of the code and its execution (i.e. no basic block modifies itself). My example violates this assumption.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s