[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-discuss] How to check cpu running mode?
From: |
krishnaLee |
Subject: |
Re: [Qemu-discuss] How to check cpu running mode? |
Date: |
Sat, 18 Aug 2018 09:17:46 +0800 (CST) |
it looks excellent code,although I'm not very familiar with ASM code,I will dig
into it,
thank you,Jakob!
by krishna.
At 2018-08-17 22:00:40, "Jakob Bohm" <address@hidden> wrote:
>On 17/08/2018 15:32, Jakob Bohm wrote:
>> On 17/08/2018 12:27, krishnaLee wrote:
>>> Hi,
>>> as to my known,intel x64 cpu can work at 64-bit mode or
>>> Compatibility mode,
>>> so thery are two kind of x64-mode,
>>> I find QEMU can run at each of them,
>>> I want to write som C code to check it if it is running at 64-bit
>>> mode or Compatibility mode, what's the key?
>>>
>> This mode is a bit in the segment descriptor referenced by the
>> current CS register, the following or similar code should be
>> able to check this(note that this code has to use only
>> instructions that have the same encoding in all CPU modes!):
>>
>> ; UNTESTED HYPOTHETICAL CODE!!!
>>
>> ; First, check that we are not running in real or VM8086
>> ; mode, because then the following will not work
>> ; (LAR will trigger an undefined opcode exception).
>> ; Doing this is left as an exercise for the reader
>>
>> ; The following is valid in 16, 32 and 64 bit protected mode
>> ; the instructions should have the same opcodes, they are
>> ; shown here using the 32 bit mode Intel syntax
>> .386
>> MOV EAX,CS
>> LAR EAX,EAX
>> JNZ SHORT modeerror
>> SHR EAX,21
>> JCSHORT mode64
>> SHR EAX,1
>> JC SHORT mode32
>> mode16j:
>> .286
>> ; Code here is 16 bit code and can use all 16 bit instructions
>> JMP mode16 ; This can be a longer jmp now that we know the
>> ; instruction encoding
>> mode32j:
>> .386
>> ; Code here is 32 bit code and can use all 32 bit instructions
>> JMP mode32 ; This can be a longer jmp now that we know the
>> ; instruction encoding
>> mode64j:
>> .amd64 ; Note, not sure what directive tells MASM to generate
>> 64bit opcodes
>> ; Code here is 64 bit code and can use all 64 bit instructions
>> JMP mode64 ; This can be a longer jmp now that we know the
>> ; instruction encoding
>> modeerror:
>> ; This really shouldn't happen!
>> ; One possible way would be if something changed the CS descriptor
>> ; in the descriptor table without reloading CS
>> ; Code here is still restricted to mode independent instructions!
>>
>> ; Alternatively, a code sequence could be constructed that has different
>> ; effects depending on CPU mode but doesn't directly query the CS
>> ; descriptor table entry, avoiding the modeerror case above.
>>
>> ; UNTESTED HYPOTHETICAL CODE!!!
>>
>> ; Perhaps
>> .386
>> XOR EAX,EAX ; XOR AX,AX if 16 bit mode
>> NOT EAX ; 16 bit: AX is now 0FFFFh
>> ; 32 bit: EAX is now 0FFFFFFFFh
>> ; 64 bit: RAX is now 0FFFFFFFFFFFFFFFFh (UNTESTED)
>> SHR EAX,16
>> JNC SHORT mode16j
>> SHR EAX,16
>> JNC SHORT mode32j
>> mode64j:
>> ; as above
>> mode32j:
>> ; as above
>> mode16j:
>> .286
>> SMSW AX
>> SHR AX,1
>> JNC SHORT mode16real
>> ; Add code here to test if this is VM8086 mode or 16 bit
>> ; protected mode
>> ; First set up a stack, 4 byte aligned
>> ; CODE MISSING
>> ; Next do the classic tricks to detect if this is at least
>> ; a 386, this involves using 16 bit PUSHF and POPF
>> ; CODE MISSING
>> ; The missing code should jump to mode16rj if < 386
>> ; Next use code to determine if in VM8086 mode, note that
>> ; PUSHFD hides the desired EFLAGS bit from us, so another
>> ; trick is needed
>> ; CODE MISSING
>> ; The missing code should jump to mode16rj if real mode
>> mode16vj:
>> .286
>> ; Code here is 16 bit code and can use all 16 bit instructions
>> ; VM8086 mode
>> JMP mode16v ; This can be a longer jmp now that we know the
>> ; instruction encoding
>> mode16rj:
>> .286
>> ; Code here is 16 bit code and can use all 16 bit instructions
>> ; Real mode, full CPU access!
>> JMP mode16v ; This can be a longer jmp now that we know the
>> ; instruction encoding
>Corrections:
>
>In the first example, the first shift should be
> SHR EAX,22
>
>In the second example, the first shift should be
> SHR EAX,17
>
>And the entire 16 bit case needs to be regrouped:
>
>mode16rj:
> .286
> ; Code here is 16 bit code and can use all 16 bit instructions
> ; Real mode, full CPU access!
> ; May or may not be the unofficial large-segment real mode
> JMP mode16r ; This can be a longer jmp now that we know the
> ; instruction encoding
>mode16j:
> .286
> ; 16 bit code, maybe protected, real, VM8086 or even
> ; the unofficial large-segment real mode
>
> ; First set up a stack, 4 byte aligned
> ; CODE MISSING OR ASSUME STACK ALREADY VALID
> ; Next do the classic tricks to detect if this is at least
> ; a 286, this involves using 16 bit PUSHF and POPF
> ; CODE MISSING
> ; The missing code should jump to mode16rj if < 286
> SMSW AX
> SHR AX,1
> JNC SHORT mode16rj
> ; So now it is protected mode or VM8086 mode
> ; First check if at least a 386 (we know it's at least 286)
> ; CODE MISSING
> ; The missing code should jump to mode16pj if a 286
> ; Add code here to test if this is VM8086 mode or 16 bit
> ; protected mode
> ; Next use code to determine if in VM8086 mode, note that
> ; PUSHFD hides the desired EFLAGS bit from us, so another
> ; trick is needed
> ; CODE MISSING
> ; The missing code should jump to mode16vj if VM8086 mode
>mode16pj:
> .286
> ; Code here is 16 bit code and can use all 16 bit instructions
> ; protected mode 16 bit
> JMP mode16p ; This can be a longer jmp now that we know the
> ; instruction encoding
>mode16vj:
> .286
> ; Code here is 16 bit code and can use all 16 bit instructions
> ; VM8086 mode
> JMP mode16v ; This can be a longer jmp now that we know the
> ; instruction encoding
>
>Enjoy
>
>Jakob
>--
>Jakob Bohm, CIO, Partner, WiseMo A/S. https://www.wisemo.com
>Transformervej 29, 2860 Søborg, Denmark. Direct +45 31 13 16 10
>This public discussion message is non-binding and may contain errors.
>WiseMo - Remote Service Management for PCs, Phones and Embedded
>