Vuln Dev
Re: GetPC code (was: Shellcode from ASCII) Jun 27 2003 08:22PM
noir (noir gsu linux org tr) (2 replies)
Re: GetPC code (was: Shellcode from ASCII) Nov 18 2003 10:57PM
Aaron Adams (aadams securityfocus com) (1 replies)
Hey Noir,

I've been looking into FPU stuff a bit lately and decided to look into
what you described a little deeper. I decided I'd give you and the list
the details of what the deal is with this.

Basically, you can do a GetPC procedure without simulating any exception.
In fact, the data stored by fnstenv isn't influenced by the exception nor
is it actually an exception record. fstenv/fnstenv is commonly used by FPU
exception handler code though, to analyze the state of the FPU environment
that an exception occured within.

Although you are triggering an exception, all of the exception bits in the
control word are masked by default when the environment is initialized. As
such, if an exception occurs the only result will be the appropriate
exception flag being set within the status word.

So, keeping this in mind we'll see what actually allows the GetPC to be
possible. Basically, the state of the FPU environment, following the first
floating point instruction, is always maintained. The fnstenv/fstenv
instructions can be used to save the state of the environment to the
location pointed to by it's operand. So the only requirement to actually
using fstenv/fnstenv is to have previously executed an FP instruction.

The structure stored by fnstenv is defined as user_fpregs_struct in
sys/user.h and is saved as so:

0 | Control Word
4 | Status Word
8 | Tag Word
12 | FPU Instruction Pointer Offset

As you explained, the FPU Instruction Pointer will be the address of the
previously executed FP instruction. And as seen above it's located at
offset 12 within the structure.

Because we can specify the location that fnstenv stores the structure
I came up with something that can kind of simplify obtaining the PC. It
can be seen in the following code, which is the smallest way I could come
up with to do a GetPC procedure.

fnstenv -12(%esp)
popl %ecx
addb 10, %cl

So, when this is executed you'll have the current pc in ecx when you hit
nop. It's pretty similar to what you did, but hopefully it clarifies some


Aaron Adams

On Fri, 27 Jun 2003, noir wrote:

> """
> > First thoughts on the second challenge: You can't use any of the call
> > opcodes, but you might be able to setup a quick exception handler in
> > the known mapped space. Cause a fault, and then find the address of
> > your fault causing instruction in the structure that's passed. (Again
> > I'm talking NT).
> I'm not sure this could be done (same problem) but, keep this in mind
> anyway :-
> ) [hint]
> gera
> """
> i have spend good 20 minutes on this, i don't have the solution yet due to
> lack of time but i thought this might be interesting for the list.
> basicly, i'm simulating a floating point exception (division by zero) and
> then grabbing the EIP(pc) from the exception record. PC is the location of
> the fdivs instruction since that instruction created the exception
> condition so we add 11 on top to make %eax point to the nop instruction.
> (ATT syntax)
> xor %eax, %eax
> push %eax
> fdivs (%esp)
> fnstenv (%esp)
> mov 0xc(%esp), %eax
> add $0xd, %eax
> nop
> - noir
> sup mate ? ;)

[ reply ]
Re: GetPC code (was: Shellcode from ASCII) Nov 19 2003 10:12PM
noir (noir gsu linux org tr)
Re: GetPC code (was: Shellcode from ASCII) Jun 30 2003 02:30PM
Gerardo Richarte (gera corest com) (1 replies)
Re: GetPC code (was: Shellcode from ASCII) Jul 01 2003 04:56PM
Costin Ionescu (costin ionescu fokus fraunhofer de)


Privacy Statement
Copyright 2010, SecurityFocus