On 09/04/2014 11:50 AM, Mohamed Elsabagh wrote:
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?
Mo--
In the course of doing some optimization work (avoiding unnecessary
trap-based instrumentation) we introduced the possibility of bugs of
this type, though I thought we'd gotten them all before the release. If
you can send me either mutator/mutatee code, or a log of your mutator
running with DYNINST_DEBUG_SPRINGBOARD=1 in your environment, I should
be able to diagnose this and get you a patch (and get the patched 8.2
posted soon).
Sorry for the inconvenience.
Thank you,
Mo
_______________________________________________
Dyninst-api mailing list
Dyninst-api@xxxxxxxxxxx
https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api
--
--bw
Bill Williams
Paradyn Project
bill@xxxxxxxxxxx
|