[DynInst_API:] Incorrect offset calculation for jmp targets


Date: Thu, 04 Sep 2014 12:50:54 -0400
From: Mohamed Elsabagh <melsabag@xxxxxxx>
Subject: [DynInst_API:] Incorrect offset calculation for jmp targets
I am using Dyninst to insert a call at the entry point of each local function in a program. This used to work fine with versions prior to 8.2. However, with Dyninst 8.2, it seems that some jump targets were shifted yet their corresponding jump sites were not updated. Dyninst 8.2 also insert an additional jmp that consumes more bytes than available. Please see below.

Before instrumentation (works):Â
 99fa40: 48 8b 15 69 d6 87 00 Âmov  Â0x87d669(%rip),%rdx
 99fa47: 31 c0         xor  Â%eax,%eax
 99fa49: 48 85 d2       Âtest  %rdx,%rdx
 99fa4c: 74 1e         je   99fa6c <sinh@plt+0x59b85c>
 99fa4e: 48 83 ec 08      sub  Â$0x8,%rsp
 99fa52: be 01 00 00 00    Âmov  Â$0x1,%esi
 99fa57: bf a0 76 68 01    Âmov  Â$0x16876a0,%edi
 99fa5c: ff d2         callq Â*%rdx
 99fa5e: 85 c0         test  %eax,%eax
 99fa60: 0f 95 c0       Âsetne Â%al
 99fa63: 48 83 c4 08      add  Â$0x8,%rsp
 99fa67: 0f b6 c0       Âmovzbl %al,%eax
 99fa6a: f7 d8         neg  Â%eax
->99fa6c: f3 c3 Â Â Â Â Â Â Â Â repz retq
 99fa6e: 66 90         xchg  %ax,%ax
->99fa70: 48 8b 15 39 d6 87 00 Âmov  Â0x87d639(%rip),%rdx

And there are two jump sites at:
 58c89d: e9 ce 31 41 00    Âjmpq  99fa70
 ...
 58c8bd: e9 ae 31 41 00    Âjmpq  99fa70

-------------------------------------------------------------------------

After instrumentation using Dyninst 8.1 (works):Â

 99fa40: e9 7c 04 05 01    Âjmpq  19efec1 <targ99fa40_dyninst>
 99fa45: 87 00         xchg  %eax,(%rax)
 99fa47: 31 c0         xor  Â%eax,%eaxÂ
 99fa49: 48 85 d2       Âtest  %rdx,%rdxÂ
 99fa4c: 74 1e         je   99fa6c <targ99fa40+0x2c>
 99fa4e: e9 7d 05 05 01    Âjmpq  19effd0 <targ99fa40_dyninst+0x10f>
 99fa53: 01 00         add  Â%eax,(%rax)Â
 99fa55: 00 00         add  Â%al,(%rax)
 99fa57: bf a0 76 68 01    Âmov  Â$0x16876a0,%ediÂ
 99fa5c: ff d2         callq Â*%rdxÂ
 99fa5e: e9 7d 05 05 01    Âjmpq  19effe0 <targ99fa40_dyninst+0x11f>
 99fa63: 48 83 c4 08      add  Â$0x8,%rspÂ
 99fa67: 0f b6 c0       Âmovzbl %al,%eax
 99fa6a: f7 d8         neg  Â%eax
->99fa6c: f3 c3 Â Â Â Â Â Â Â Â repz retq
ÂÂ99fa6e: 66 90         xchg  %ax,%axÂ
->99fa70: 48 8b 15 39 d6 87 00 Âmov  Â0x87d639(%rip),%rdxÂ


And the two aforementioned jump sites are intact.

-------------------------------------------------------------------------

After instrumentation with Dyninst 8.2 (crashes at 99fa70):ÂÂ
 99fa40: e9 51 16 05 01    Âjmpq  19f1096 <targ99fa40_dyninst>
 99fa45: 87 00         xchg  %eax,(%rax)
 99fa47: 31 c0         xor  Â%eax,%eax
 99fa49: 48 85 d2       Âtest  %rdx,%rdx
 99fa4c: 74 1e         je   99fa6c <targ99fa40+0x2c>
 99fa4e: e9 2e 17 05 01    Âjmpq  19f1181 <targ99fa40_dyninst+0xeb>
 99fa53: 01 00         add  Â%eax,(%rax)
 99fa55: 00 00         add  Â%al,(%rax)
 99fa57: bf a0 76 68 01    Âmov  Â$0x16876a0,%edi
 99fa5c: ff d2         callq Â*%rdx
 99fa5e: e9 2e 17 05 01    Âjmpq  19f1191 <targ99fa40_dyninst+0xfb>
 99fa63: 48 83 c4 08      add  Â$0x8,%rsp
 99fa67: 0f b6 c0       Âmovzbl %al,%eax
 99fa6a: f7 d8         neg  Â%eax
->99fa6c: e9 2e 17 05 01    Âjmpq  19f119f <targ99fa40_dyninst+0x109>
->99fa71: 8b 15 39 d6 87 00   mov  Â0x87d639(%rip),%edx

But the two jump sites are still pointing at 99fa70:
 19c70f1: e9 7a 89 fd fe    Âjmpq  99fa70
 ...
 19c71b6: e9 b5 88 fd fe    Âjmpq  99fa70

The instrumented process instantly crashes at 99fa70 once any of the two jumps are taken. The program executes correctly if I manually patch the jump sites to point at the correct target 99fa71.

Also, as you can notice, Dyninst 8.2 has inserted an *additional* jmp at 99fa6c that consumed 5 bytes, while the original block had a space for only 4 bytes. Dyninst 8.1 did not insert that jmp and 99fa6c ... 99fa70 were left intact.

Is this a known issue? Is there a workaround?

Thank you,
Mo
[← Prev in Thread] Current Thread [Next in Thread→]