* [Qemu-devel] Binary Translation hooking - reading registers
@ 2011-02-13 3:48 felix.matenaar@rwth-aachen
2011-02-13 5:38 ` Mulyadi Santosa
2011-02-13 8:55 ` Blue Swirl
0 siblings, 2 replies; 5+ messages in thread
From: felix.matenaar@rwth-aachen @ 2011-02-13 3:48 UTC (permalink / raw)
To: qemu-devel
Hello everyone,
i am working on a project adding instrumentation into qemu. My approach
is to use gen_helper stuff do hook specific opcodes like call or ret to
gain information about running processes in the virtual machine.
Today I noticed that the CPUState* env is not in all cases up-to-date
when my hooks are called on block execution. That makes totally sense
since blocks are natively executed in one step as far as I understood so
there is no code which would keep the cpu environment up-to-date.
To achieve my goal, it is necessary being able reading actual register
configuration like eax when a ret hook is called to get a function
return value. So my question is how I can do this. Are there already
some functions which generate code to update the cpu environment? If
not, is there anything you can point me towards for adding support?
Target is windows XP on i386.
Regards,
Felix
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [Qemu-devel] Binary Translation hooking - reading registers 2011-02-13 3:48 [Qemu-devel] Binary Translation hooking - reading registers felix.matenaar@rwth-aachen @ 2011-02-13 5:38 ` Mulyadi Santosa 2011-02-13 17:14 ` felix.matenaar@rwth-aachen 2011-02-13 8:55 ` Blue Swirl 1 sibling, 1 reply; 5+ messages in thread From: Mulyadi Santosa @ 2011-02-13 5:38 UTC (permalink / raw) To: felix.matenaar@rwth-aachen; +Cc: qemu-devel Hi.... On Sun, Feb 13, 2011 at 10:48, felix.matenaar@rwth-aachen <felix.matenaar@rwth-aachen.de> wrote: > To achieve my goal, it is necessary being able reading actual register > configuration like eax when a ret hook is called to get a function > return value. So my question is how I can do this. Are there already > some functions which generate code to update the cpu environment? If > not, is there anything you can point me towards for adding support? I think you should look into the tracing infrastructure that is gradually added to Qemu. I forgot the URL that provide the patch (since I am not sure whether it's fully merged with mainline). Please check this list archieve... NB: You're talking about qemu system emulation,right? not the user mode emulation, I assume? Because you said "executed in one step" (or something like that). AFAIK, although Qemu does lazy evalution, but for general registers it should be always updated. The one that gets lazy evalution for example is eflags. -- regards, Mulyadi Santosa Freelance Linux trainer and consultant blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] Binary Translation hooking - reading registers 2011-02-13 5:38 ` Mulyadi Santosa @ 2011-02-13 17:14 ` felix.matenaar@rwth-aachen 2011-02-13 17:34 ` Peter Maydell 0 siblings, 1 reply; 5+ messages in thread From: felix.matenaar@rwth-aachen @ 2011-02-13 17:14 UTC (permalink / raw) To: Mulyadi Santosa; +Cc: qemu-devel On 02/13/2011 06:38 AM, Mulyadi Santosa wrote: > Hi.... > > On Sun, Feb 13, 2011 at 10:48, felix.matenaar@rwth-aachen > <felix.matenaar@rwth-aachen.de> wrote: >> To achieve my goal, it is necessary being able reading actual register >> configuration like eax when a ret hook is called to get a function >> return value. So my question is how I can do this. Are there already >> some functions which generate code to update the cpu environment? If >> not, is there anything you can point me towards for adding support? > I think you should look into the tracing infrastructure that is > gradually added to Qemu. I forgot the URL that provide the patch > (since I am not sure whether it's fully merged with mainline). Please > check this list archieve... > > NB: You're talking about qemu system emulation,right? not the user > mode emulation, I assume? Because you said "executed in one step" (or > something like that). AFAIK, although Qemu does lazy evalution, but > for general registers it should be always updated. The one that gets > lazy evalution for example is eflags. > Yes I am talking about full system emulation (i386). Tracing infrastructure may be suitable for my needs in the future but I think that my instrumentation patches which are already added as far as I need it have a bit less overhead. To be more specific on my env update problem, here an example: push ebp mv esp,ebp /* do something */ call 0xfoo test eax,eax /* do something */ ret The first line is the start of a block. What I did was adding a gen_helper_instrument_call in the 'call' opcode cases in disas_insn() which will call my analysis code to examine from where the call is launched, where it will go and what is the address we will return to after (in this case regarding to call 0xfoo). Because in this case, usage of tcg_const_i32(pc_start) and providing CPU_T[0] as parameters to my generated helper, I can provide all three values. But what I would _assume_ is that after gen_helper_instrument_call is executed, env->eip would point towards 'call 0xfoo', but it points to 'push ebp'. Thats why I am confused if I can trust the values in env to gain more information about the current register values of the guest machine. This particular case is indeed not a problem since I can provide all parameters to gen_helper_instrument_call here but there are cases where I would like to read e.g. esp for keeping an analysis shadow stack up to date or reading return values by examining eax when my ret hook is called. This is my call immediate handler: void helper_call_im_protected(target_ulong src_eip, target_ulong new_eip, int next_eip){ if (!(new_eip & 0x80000000) ){ /* env->eip == src_eip will evaluate to 0 if 'call' opcode was not at the beginning of the translation block*/ analysis_examine_call(src_eip,new_eip,next_eip); } } Here my hook inserting in disas_insn: case 0xe8: /* call im */ { /* some code */ gen_movtl_T0_im(next_eip); gen_push_T0(s); /* will call helper_call_im_protected when call opcode is executed */ gen_helper_call_im_protected(tcg_const_i32(pc_start), tcg_const_i32(tval), cpu_T[0]); gen_jmp(s, tval); } Hope you understand. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] Binary Translation hooking - reading registers 2011-02-13 17:14 ` felix.matenaar@rwth-aachen @ 2011-02-13 17:34 ` Peter Maydell 0 siblings, 0 replies; 5+ messages in thread From: Peter Maydell @ 2011-02-13 17:34 UTC (permalink / raw) To: felix.matenaar@rwth-aachen; +Cc: Mulyadi Santosa, qemu-devel On 13 February 2011 17:14, felix.matenaar@rwth-aachen <felix.matenaar@rwth-aachen.de> wrote: > To be more specific on my env update problem, here an example: > > push ebp > mv esp,ebp > /* do something */ > call 0xfoo > test eax,eax > /* do something */ > ret > > The first line is the start of a block. What I did was adding a > gen_helper_instrument_call in the 'call' opcode cases in disas_insn() > which will call my analysis code to examine from where the call is > launched, where it will go and what is the address we will return to > after (in this case regarding to call 0xfoo). > Because in this case, usage of tcg_const_i32(pc_start) and providing > CPU_T[0] as parameters to my generated helper, I can provide all three > values. But what I would _assume_ is that after > gen_helper_instrument_call is executed, env->eip would point towards > 'call 0xfoo', but it points to 'push ebp'. Ah, you should have said you were talking about EIP; you've hit an optimisation case. If we updated env->eip after every instruction then this would slow things down. Instead, since we know what the value is statically at translate time, we can just use that calculated value mostly. We only update env->eip: * at the end of the TB * when we translate jump commands (usually ends the TB) * when we translate something that will raise an exception or some other thing we know will need an accurate env->eip Unexpected interrupts (typically faults on load/store) are handled by constructing a mapping from host PC to guest PC and then looking up the host fault address in it and resetting env->eip (in gen_pc_load()). Which registers are dealt with like this varies from target to target; on target-arm we do this for both r15 (pc) and the IT state bits in the CPSR, for instance. The other case to watch out for is where the value of some register is kept in env, but as a broken out set of components which are only reassembled into the actual register value when the target needs to read it; see for example the comment in target-i386/cpu.h about env->eflags. If the registers you care about aren't in either of these categories you should be able to trust them in a helper fn. This typically includes most of the general purpose registers. -- PMM ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] Binary Translation hooking - reading registers 2011-02-13 3:48 [Qemu-devel] Binary Translation hooking - reading registers felix.matenaar@rwth-aachen 2011-02-13 5:38 ` Mulyadi Santosa @ 2011-02-13 8:55 ` Blue Swirl 1 sibling, 0 replies; 5+ messages in thread From: Blue Swirl @ 2011-02-13 8:55 UTC (permalink / raw) To: felix.matenaar@rwth-aachen; +Cc: qemu-devel On Sun, Feb 13, 2011 at 5:48 AM, felix.matenaar@rwth-aachen <felix.matenaar@rwth-aachen.de> wrote: > Hello everyone, > > i am working on a project adding instrumentation into qemu. My approach > is to use gen_helper stuff do hook specific opcodes like call or ret to > gain information about running processes in the virtual machine. > > Today I noticed that the CPUState* env is not in all cases up-to-date > when my hooks are called on block execution. That makes totally sense > since blocks are natively executed in one step as far as I understood so > there is no code which would keep the cpu environment up-to-date. > > To achieve my goal, it is necessary being able reading actual register > configuration like eax when a ret hook is called to get a function > return value. So my question is how I can do this. Are there already > some functions which generate code to update the cpu environment? If > not, is there anything you can point me towards for adding support? Without seeing your code, you are probably confusing translation phase and executing the code generated by TCG. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-02-13 17:35 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-02-13 3:48 [Qemu-devel] Binary Translation hooking - reading registers felix.matenaar@rwth-aachen 2011-02-13 5:38 ` Mulyadi Santosa 2011-02-13 17:14 ` felix.matenaar@rwth-aachen 2011-02-13 17:34 ` Peter Maydell 2011-02-13 8:55 ` Blue Swirl
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.