All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] Question regarding self-modifying code.
@ 2016-01-13 16:45 farmdve
  2016-01-13 17:18 ` Peter Maydell
  0 siblings, 1 reply; 7+ messages in thread
From: farmdve @ 2016-01-13 16:45 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 88 bytes --]

On Windows, in software MMU mode, how does QEMU handle self-modifying code?

Thank you.

[-- Attachment #2: Type: text/html, Size: 133 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] Question regarding self-modifying code.
  2016-01-13 16:45 [Qemu-devel] Question regarding self-modifying code farmdve
@ 2016-01-13 17:18 ` Peter Maydell
       [not found]   ` <CAHGme8sE+hOQwS+neP5A_-S-pyLg_YhdE1jT7W+nL7mi0BHi2A@mail.gmail.com>
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Maydell @ 2016-01-13 17:18 UTC (permalink / raw)
  To: farmdve; +Cc: QEMU Developers

On 13 January 2016 at 16:45, farmdve <farmdve@gmail.com> wrote:
> On Windows, in software MMU mode, how does QEMU handle
> self-modifying code?

When we translate the guest code in a page of guest
memory, we mark that page as "not dirty for code" by
calling tlb_protect_code(), which clears a DIRTY_MEMORY_CODE
bit and also ensures that subsequent guest writes to
this page will take a slow code path. On that slow code
path (in notdirty_mem_write()) we check to see if the
DIRTY_MEMORY_CODE flag is clear for this page, and if
it is then we throw away the translated code by
calling tb_invalidate_phys_page_fast(). If the guest
later tries to execute from the page again, we will
translate the guest code again (and so will use the
freshly modified code).

There is some slight extra complication for CPUs which
can validly modify the code they're executing (ie
which don't need any kind of "flush cache/pipeline"
or a branch between the store which modifies the
code and the execution of the modified code). You
can find those by looking at the changes controlled
by the TARGET_HAS_PRECISE_SMC #define, which we only
need for x86 guests at the moment. (For CPUs which don't
set that, attempting to self-modify code in the same
TB won't work, which is OK because architecturally
that doesn't work on hardware either.)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] Question regarding self-modifying code.
       [not found]     ` <CAFEAcA_EiFu0Okn5AEkeauO=ndfti-+CcCbr850iogQojJ5QAg@mail.gmail.com>
@ 2016-01-14 10:15       ` farmdve
  2016-01-14 10:27         ` Peter Maydell
  0 siblings, 1 reply; 7+ messages in thread
From: farmdve @ 2016-01-14 10:15 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2128 bytes --]

Sorry about that. Somehow Google decided it should reply to you, rather
than the mailing list. It was an honest mistake.

Original question is below


I am unable to get this part here if (!(tb_end <= start || tb_start >=
end)) in tb_invalidate_phys_page_range

What would happen if code forward modifies itself, but that condition
evaluates to true?

Then this piece here won't get executed

> #ifdef TARGET_HAS_PRECISE_SMC
>             if (current_tb_not_found) {
>                 current_tb_not_found = 0;
>                 current_tb = NULL;
>                 if (cpu->mem_io_pc) {
>                     /* now we have a real cpu fault */
>                     current_tb = tb_find_pc(uc, cpu->mem_io_pc);
>                 }
>             }
>            if (current_tb == tb &&
>                 (current_tb->cflags & CF_COUNT_MASK) != 1) {
>                 /* If we are modifying the current TB, we must stop
>                 its execution. We could be more precise by checking
>                 that the modification is after the current PC, but it
>                 would require a specialized function to partially
>                 restore the CPU state */
>
>                current_tb_modified = 1;
>                 // self-modifying code will restore state from TB
>                 cpu_restore_state_from_tb(cpu, current_tb,
cpu->mem_io_pc);
>                 cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
>                                      &current_flags);
>            }
> #endif /* TARGET_HAS_PRECISE_SMC */

> It just so happens I am experiencing such a case.

On 14 January 2016 at 11:58, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 14 January 2016 at 00:37, farmdve <farmdve@gmail.com> wrote:
> > I am unable to get this part here if (!(tb_end <= start || tb_start >=
> end))
> > in tb_invalidate_phys_page_range
> >
> > What would happen if code forward modifies itself, but that condition
> > evaluates to true?
>
> Please can you send questions to the mailing list, not to
> me personally. That way anybody who knows and has time to
> answer can do so.
>
> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 4582 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] Question regarding self-modifying code.
  2016-01-14 10:15       ` farmdve
@ 2016-01-14 10:27         ` Peter Maydell
       [not found]           ` <CAHGme8sPAEea6rTKYiypTE+_2Sp5RiNDTo22gNOBy2fppsduBw@mail.gmail.com>
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Maydell @ 2016-01-14 10:27 UTC (permalink / raw)
  To: farmdve; +Cc: QEMU Developers

On 14 January 2016 at 10:15, farmdve <farmdve@gmail.com> wrote:
> Sorry about that. Somehow Google decided it should reply to you, rather than
> the mailing list. It was an honest mistake.
>
> Original question is below
>
>
> I am unable to get this part here if (!(tb_end <= start || tb_start >= end))
> in tb_invalidate_phys_page_range
>
> What would happen if code forward modifies itself, but that condition
> evaluates to true?

If that condition is true, then the TB we're looking at (as we
iterate through every TB we know about) is not in fact overlapping
with the page that the guest just modified, and so is not affected
by the write...

> Then this piece here won't get executed

...and so it is correct that we don't need to do anything for this TB.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] Question regarding self-modifying code.
       [not found]           ` <CAHGme8sPAEea6rTKYiypTE+_2Sp5RiNDTo22gNOBy2fppsduBw@mail.gmail.com>
@ 2016-01-14 14:29             ` farmdve
  2016-01-14 14:36               ` Peter Maydell
  0 siblings, 1 reply; 7+ messages in thread
From: farmdve @ 2016-01-14 14:29 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1373 bytes --]

Again, sorry for the personal message, Peter, Google really is failing
here, more so than me.

>> But in my case, an instruction did forward modify some code, but this if
statement did not execute and QEMU executed the old code.

On 14 January 2016 at 16:28, farmdve <farmdve@gmail.com> wrote:

> But in my case, an instruction did forward modify some code, but this if
> statement did not execute and QEMU executed the old code.
>
> On 14 January 2016 at 12:27, Peter Maydell <peter.maydell@linaro.org>
> wrote:
>
>> On 14 January 2016 at 10:15, farmdve <farmdve@gmail.com> wrote:
>> > Sorry about that. Somehow Google decided it should reply to you, rather
>> than
>> > the mailing list. It was an honest mistake.
>> >
>> > Original question is below
>> >
>> >
>> > I am unable to get this part here if (!(tb_end <= start || tb_start >=
>> end))
>> > in tb_invalidate_phys_page_range
>> >
>> > What would happen if code forward modifies itself, but that condition
>> > evaluates to true?
>>
>> If that condition is true, then the TB we're looking at (as we
>> iterate through every TB we know about) is not in fact overlapping
>> with the page that the guest just modified, and so is not affected
>> by the write...
>>
>> > Then this piece here won't get executed
>>
>> ...and so it is correct that we don't need to do anything for this TB.
>>
>> thanks
>> -- PMM
>>
>
>

[-- Attachment #2: Type: text/html, Size: 2251 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] Question regarding self-modifying code.
  2016-01-14 14:29             ` farmdve
@ 2016-01-14 14:36               ` Peter Maydell
  2016-01-14 15:12                 ` farmdve
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Maydell @ 2016-01-14 14:36 UTC (permalink / raw)
  To: farmdve; +Cc: QEMU Developers

On 14 January 2016 at 14:29, farmdve <farmdve@gmail.com> wrote:
> Again, sorry for the personal message, Peter, Google really is failing here,
> more so than me.

There's a "Default reply behaviour" setting in Settings->General
in gmail that you can use to make it default to reply-to-all
rather than just reply if you prefer that.

> But in my case, an instruction did forward modify some code, but
> this if statement did not execute and QEMU executed the old code.

Can't really diagnose this without a test case. But the
if condition is pretty trivial and very unlikely to be wrong.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] Question regarding self-modifying code.
  2016-01-14 14:36               ` Peter Maydell
@ 2016-01-14 15:12                 ` farmdve
  0 siblings, 0 replies; 7+ messages in thread
From: farmdve @ 2016-01-14 15:12 UTC (permalink / raw)
  Cc: QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 1780 bytes --]

I can only provide this shellcode right here.

\x89\xe1\xd9\xcd\xd9\x71\xf4\x5d\x55\x59\x49\x49\x49\x49\x49\x49" \
"\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51\x5a\x6a\x41\x58" \
"\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30" \
"\x42\x42\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x51\x51\x51\x52" \
"\x47\x33\x47\x34\x51\x55\x51\x56\x50\x47\x47\x38\x47\x39\x50\x4a" \
"\x50\x4b\x50\x4c\x50\x4d\x50\x4e\x50\x4f\x50\x50\x50\x31\x47\x42" \
"\x47\x42\x50\x34\x50\x5a\x50\x45\x51\x52\x46\x32\x47\x31\x50\x4d" \
"\x51\x51\x50\x4e\x41\x41

This code runs normally in a debugger when executed on a real CPU.

Here is the disassembly of the relevant parts.

mov ecx,esp
fxch st5
fnstenv dword ptr ds:[ecx-C]
pop ebp
push ebp
pop ecx
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
inc ebx
inc ebx
inc ebx
inc ebx
inc ebx
inc ebx
aaa
push ecx
pop edx
push 41
pop eax
push eax
xor byte ptr ds:[ecx+30],al
inc ecx
imul eax,dword ptr ds:[ecx+41],51 <-- should multiply with 0x10, not 0x51.

The code is position independent.

On 14 January 2016 at 16:36, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 14 January 2016 at 14:29, farmdve <farmdve@gmail.com> wrote:
> > Again, sorry for the personal message, Peter, Google really is failing
> here,
> > more so than me.
>
> There's a "Default reply behaviour" setting in Settings->General
> in gmail that you can use to make it default to reply-to-all
> rather than just reply if you prefer that.
>
> > But in my case, an instruction did forward modify some code, but
> > this if statement did not execute and QEMU executed the old code.
>
> Can't really diagnose this without a test case. But the
> if condition is pretty trivial and very unlikely to be wrong.
>
> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 2834 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-01-14 15:12 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-13 16:45 [Qemu-devel] Question regarding self-modifying code farmdve
2016-01-13 17:18 ` Peter Maydell
     [not found]   ` <CAHGme8sE+hOQwS+neP5A_-S-pyLg_YhdE1jT7W+nL7mi0BHi2A@mail.gmail.com>
     [not found]     ` <CAFEAcA_EiFu0Okn5AEkeauO=ndfti-+CcCbr850iogQojJ5QAg@mail.gmail.com>
2016-01-14 10:15       ` farmdve
2016-01-14 10:27         ` Peter Maydell
     [not found]           ` <CAHGme8sPAEea6rTKYiypTE+_2Sp5RiNDTo22gNOBy2fppsduBw@mail.gmail.com>
2016-01-14 14:29             ` farmdve
2016-01-14 14:36               ` Peter Maydell
2016-01-14 15:12                 ` farmdve

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.