* [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 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
* 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
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.