problem: singlestep cmp [esp+1c],0

70 views
Skip to first unread message

mengxp(孟学政)

unread,
Jul 27, 2011, 7:28:11 AM7/27/11
to hyperdbg
i press F12 call the hyperdbg
and singlestep the i8042prt.sys

when goes here:
cmp [esp+1C],0

hyperdbg goes die

i print debug info found that

when singlestep executing the instruction "cmp [esp+1C],0"

VMMEntryPoint receive a EXIT CODE 33

it means VM-entry failure due to invalid guest state.

but the CR0 CR3 CR4 registers look good.

the same to ESP register

how does this happen???????

Aristide Fattori

unread,
Jul 27, 2011, 7:37:47 AM7/27/11
to hype...@googlegroups.com
Hi,

I need more context here:

1) which version of hyperdbg are you using: precompiled, compiled from
the tarball, compiled from the SVN repo?
2) version of the guest OS.
3) base address of the i8042prt.sys and relative offset of the "cmp
[esp+1c], 0" instruction.

TIA,
Aristide

2011/7/27 mengxp(孟学政) <m...@live.cn>:

--
GnuPG Key on  ID 0x25578128
http://security.dico.unimi.it/~joystick/

mengxp(孟学政)

unread,
Jul 27, 2011, 9:13:42 AM7/27/11
to hyperdbg
1.hyperdbg version is hyperdbg_20100325
2.winxp sp3 (CPU P8600 nopae singlecore)
3.the fault eip is in ntoskrnl.exe

.text:00405BCF ; __fastcall KiIdleLoop()
.text:00405BCF @KiIdleLoop@0 proc near ; CODE XREF:
KiSystemStartup(x)+2F3 j
.text:00405BCF lea ebp, [ebx+980h]
.text:00405BD5 jmp short loc_405BDF
.text:00405BD7 ;
---------------------------------------------------------------------------
.text:00405BD7
.text:00405BD7 loc_405BD7: ; CODE XREF:
KiIdleLoop()+2F j
.text:00405BD7 lea ecx, [ebx+0C50h]
.text:00405BDD call dword ptr [ecx]
.text:00405BDF
.text:00405BDF loc_405BDF: ; CODE XREF:
KiIdleLoop()+6 j
.text:00405BDF ; KiIdleLoop()
+B3 j
.text:00405BDF pause
.text:00405BE1 sti
.text:00405BE2 nop
.text:00405BE3 nop
.text:00405BE4 cli
.text:00405BE5 cmp ebp, [ebp+0]
.text:00405BE8 jz short loc_405BF7
.text:00405BEA mov cl, 2
.text:00405BEC call
ds:__imp_@HalClearSoftwareInterrupt@4 ; HalClearSoftwareInterrupt(x)
.text:00405BF2 call KiRetireDpcList
.text:00405BF7
.text:00405BF7 loc_405BF7: ; CODE XREF:
KiIdleLoop()+19 j
.text:00405BF7 cmp dword ptr [ebx+128h], 0
.text:00405BFE jz short loc_405BD7
.text:00405C00 mov ecx, 1Ch
.text:00405C05 call ds:__imp_@KfRaiseIrql@4 ;
KfRaiseIrql(x)
.text:00405C0B sti
.text:00405C0C lea ecx, [ebx+540h]
.text:00405C12 call
@KeAcquireQueuedSpinLockAtDpcLevel@4 ;
KeAcquireQueuedSpinLockAtDpcLevel(x)
.text:00405C17 mov esi, [ebx+128h]
.text:00405C1D mov edi, [ebx+124h]
.text:00405C23 cmp byte ptr [esi+50h], 0
.text:00405C27 jnz short loc_405C66
.text:00405C29 cmp esi, edi
.text:00405C2B jz short loc_405C87
.text:00405C2D or ecx, 1
.text:00405C30 mov [ebx+124h], esi
.text:00405C36 mov byte ptr es:[esi+2Dh], 2
.text:00405C3B mov dword ptr [ebx+128h], 0
.text:00405C45 push offset unk_405C50
.text:00405C4A pushf
.text:00405C4B jmp loc_405950
.text:00405C4B ;
---------------------------------------------------------------------------
.text:00405C50 unk_405C50 db 0B9h ; ? ; DATA XREF:
KiIdleLoop()+76 o
.text:00405C51 db 2
.text:00405C52 db 0
.text:00405C53 db 0
.text:00405C54 db 0
.text:00405C55 db 0FFh
.text:00405C56 db 15h
.text:00405C57 db 30h ; 0 OFF32 SEGDEF [_text,401030]
.text:00405C58 db 10h
.text:00405C59 db 40h ; @
.text:00405C5A db 0
.text:00405C5B db 8Dh ; ?
.text:00405C5C db 0ABh ; ?
.text:00405C5D db 80h ; €
.text:00405C5E db 9
.text:00405C5F db 0
.text:00405C60 db 0
.text:00405C61 db 0E9h ; ?
.text:00405C62 db 79h ; y
.text:00405C63 db 0FFh
.text:00405C64 db 0FFh
.text:00405C65 db 0FFh
.text:00405C66 ;
---------------------------------------------------------------------------
.text:00405C66
.text:00405C66 loc_405C66: ; CODE XREF:
KiIdleLoop()+58 j
.text:00405C66 lea ecx, [ebx+540h]
.text:00405C6C
.text:00405C6C loc_405C6C: ; CODE XREF:
KiIdleLoop()+D4 j
.text:00405C6C ; KiIdleLoop()
+E0 j
.text:00405C6C call
@KeReleaseQueuedSpinLockFromDpcLevel@4 ;
KeReleaseQueuedSpinLockFromDpcLevel(x)
.text:00405C71 mov ecx, 2
.text:00405C76 call ds:__imp_@KfLowerIrql@4 ;
KfLowerIrql(x)
.text:00405C7C lea ebp, [ebx+980h]
.text:00405C82 jmp loc_405BDF
.text:00405C87 ;
---------------------------------------------------------------------------
.text:00405C87
.text:00405C87 loc_405C87: ; CODE XREF:
KiIdleLoop()+5C j
.text:00405C87 lea ecx, [ebx+540h]
.text:00405C8D call
@KeReleaseQueuedSpinLockFromDpcLevel@4 ;
KeReleaseQueuedSpinLockFromDpcLevel(x)
.text:00405C92 lea ecx, [ebx+538h]
.text:00405C98 call
@KeAcquireQueuedSpinLockAtDpcLevel@4 ;
KeAcquireQueuedSpinLockAtDpcLevel(x)
.text:00405C9D cmp esi, [ebx+128h]
.text:00405CA3 jnz short loc_405C6C
.text:00405CA5 mov dword ptr [ebx+128h], 0
.text:00405CAF jmp short loc_405C6C
.text:00405CAF @KiIdleLoop@0 endp ; sp-analysis failed
.text:00405CAF
.text:00405CB1
.text:00405CB1 ; =============== S U B R O U T I N E
=======================================
.text:00405CB1
.text:00405CB1
.text:00405CB1 KiRetireDpcList proc near ; CODE XREF:
KiDispatchInterrupt()+26 p
.text:00405CB1 ; KiIdleLoop()
+23 p
.text:00405CB1
.text:00405CB1 var_24 = dword ptr -24h
.text:00405CB1 var_14 = dword ptr -14h
.text:00405CB1 var_10 = dword ptr -10h
.text:00405CB1 var_C = dword ptr -0Ch
.text:00405CB1 var_8 = dword ptr -8
.text:00405CB1
.text:00405CB1 push esi
.text:00405CB2 lea esi, [ebx+9C0h]
.text:00405CB8 push 0
.text:00405CBA sub esp, 0Ch
.text:00405CBD cmp ds:_PPerfGlobalGroupMask, 0
.text:00405CC4 jnz loc_405D4F
.text:00405CCA
.text:00405CCA loc_405CCA: ; CODE XREF:
KiRetireDpcList+85 j
.text:00405CCA ;
KiRetireDpcList+A6 j ...
.text:00405CCA mov large fs:994h, esp
.text:00405CD1
.text:00405CD1 loc_405CD1: ; CODE XREF:
KiRetireDpcList+6C j
.text:00405CD1 lock bts dword ptr [esi], 0
.text:00405CD6 jb short loc_405D42
.text:00405CD8 cmp ebp, [ebp+0]
.text:00405CDB jz short loc_405D3D
.text:00405CDD mov edx, [ebp+0]
.text:00405CE0 mov ecx, [edx]
.text:00405CE2 mov [ebp+0], ecx
.text:00405CE5 mov [ecx+4], ebp
.text:00405CE8 sub edx, 4
.text:00405CEB mov ecx, [edx+0Ch]
.text:00405CEE push dword ptr [edx+18h]
.text:00405CF1 push dword ptr [edx+14h]
.text:00405CF4 push dword ptr [edx+10h]
.text:00405CF7 push edx
.text:00405CF8 mov dword ptr [edx+1Ch], 0
.text:00405CFF dec dword ptr [ebx+990h]
.text:00405D05 mov byte ptr [esi], 0
.text:00405D08 sti
.text:00405D09 cmp [esp+24h+var_8], 0 ;here we
singlestep will die


Aristide Fattori

unread,
Jul 27, 2011, 9:52:28 AM7/27/11
to hype...@googlegroups.com
Hi,

I am unable to reproduce the bug using the SVN version so this bug has
probably been fixed already. Please try to recompile hyperdbg from the
SVN version and consider that version as stable. We will try to update
the precompiled packages ASAP.

Greetings,
Aristide

2011/7/27 mengxp(孟学政) <m...@live.cn>:

--

mengxp(孟学政)

unread,
Jul 27, 2011, 10:02:05 AM7/27/11
to hyperdbg
ok i will try the SVN version~~

thx a lot!

:D

mengxp(孟学政)

unread,
Jul 27, 2011, 12:03:28 PM7/27/11
to hyperdbg
Hi,

I tried the SVN version, it seems that this bug is still exist.

I put some code in vmx.c to print the exit reason here:

default:

VideoResetOutMatrix();

vmm_snprintf(out_matrix[0], OUT_SIZE_X, "WHAT THE FUCK! Exit Reason
is %d",vmxcontext.ExitReason & 0xFF);
VideoRefreshOutArea(0xffff0000);


/* Unknown exit condition */
break;
}

// This instruction is reached when we are not able to handle the
reason that
// triggered this VM exit. In this case, we simply switch off VMX
mode.
HypercallSwitchOff(NULL);


i press f12 then singlestep here. the vm die.....

look these two photos (my poor cellphone)

http://www.deadc0de.com/1.JPG
http://www.deadc0de.com/2.JPG

:(

mengxp

Aristide Fattori

unread,
Jul 27, 2011, 12:23:32 PM7/27/11
to hype...@googlegroups.com
Hi,

can you please give me the nearest symbol to the faulty instruction?
You can use hyperdbg to get that with the command:

n 804ddd09

TIA,
Aristide

2011/7/27 mengxp(孟学政) <m...@live.cn>:

--

mengxp(孟学政)

unread,
Jul 27, 2011, 12:33:36 PM7/27/11
to hyperdbg
Hi

n 804ddd09

nearest symbol smaller than 804ddd09 is
ZwAccessCheckByTypeResultListAndAuditAlertByHandle@68

with ntoskrnl.pdb

we can find the faulty instructioin in the function >>>>
KiRetireDpcList

the following code is disasm by IDA Pro 5.5
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< the faulty
instruction

mengxp(孟学政)

unread,
Jul 27, 2011, 12:42:39 PM7/27/11
to hyperdbg
Hi,

now i'm considering that my CPU has the bug :-(
i will try with another PC tomorrow.
see you tomorrow!

mengxp

Aristide Fattori

unread,
Jul 27, 2011, 12:44:24 PM7/27/11
to hype...@googlegroups.com
According to the screenshots you sent me, I found the same instruction
that causes the bug on your machine (see attachments) but in our
development environment nothing wrong happens.

Unfortunately I don't have a physical machine to try it right now, but
please let me know if it behaves differently on the machine you are
going to try.

TIA,
Aristide

Selection_004.png
Selection_005.png

mengxp(孟学政)

unread,
Jul 27, 2011, 11:43:24 PM7/27/11
to hyperdbg
Hi,

I tried hyperdbg on another computer (Intel G45 Chipest Xeno3330
winxp sp3)

when single step executing the CMP instruction
the bad thing also happened..
VMExitCode is 33

:(

mengxp

mengxp(孟学政)

unread,
Jul 28, 2011, 3:38:51 AM7/28/11
to hyperdbg
Hi,

Today I looked up the <<Intel 64 and IA-32Software Developer's Manual
Volume 3B>> and found the reason why the vm-entry failed.

the following is quoted from the Chapter 23.3.15 "Checks on Guest Non-
Register State"


--------------------------------------------------------------------------------------------------------------------------------
• Pending debug exceptions.

— Bits 11:4, bit 13, and bits 63:15 (bits 31:15 on processors
that do not
support Intel 64 architecture) must be 0.

— The following checks are performed if any of the following
holds: (1) the
interruptibility-state field indicates blocking by STI (bit 0
in that field is 1);
(2) the interruptibility-state field indicates blocking by
MOV SS (bit 1 in that
field is 1); or (3) the activity-state field indicates HLT:

• Bit 14 (BS) must be 1 if the TF flag (bit 8) in the
RFLAGS field is 1 and the
BTF flag (bit 1) in the IA32_DEBUGCTL field is 0.

• Bit 14 (BS) must be 0 if the TF flag (bit 8) in the
RFLAGS field is 0 or the
BTF flag (bit 1) in the IA32_DEBUGCTL field is 1.
--------------------------------------------------------------------------------------------------------------------------------

these are the faulty instructions
.text:00405D08 sti
.text:00405D09 cmp [esp+24h+var_8], 0

so when we single-step executed "STI", the interruptibility-state
field indicates blocking by STI (bit 0 in that field is 1); and
TF=1(because we are single-stepping),and when we continue to single-
step the next instruction "cmp [esp+24h+var_8], 0", CPU will check
the Bit14 of Pending debug exceptions. If the Bit14(BS) = 0, we will
got a VMExit Code = 33 (vm-entry failed due to invalid guest state).

but we set BS=1 when single-step the instruction "cmp [esp+24h
+var_8], 0", the cpu will not execute this instruction and nothing
happens. so I think we should do some special process when we single-
step the instruction "STI" ?


sorry for my poor english :D
mengxp

Aristide Fattori

unread,
Jul 28, 2011, 4:02:38 AM7/28/11
to hype...@googlegroups.com
Hi,

we think your idea is reasonable and we are investigating on how to
solve the bug. In the meantime, could you please test what happens if
you place a breakpoint on the "cmp     [esp+24h+var_8], 0" instruction
and then start to single step (thus avoiding to single step on the STI
instruction).

TIA,
Aristide


2011/7/28 mengxp(孟学政) <m...@live.cn>:

--

mengxp(孟学政)

unread,
Jul 28, 2011, 4:24:24 AM7/28/11
to hyperdbg
Hi

I set a breakpoint on the "cmp [esp+24h+var_8], 0" instruction

b 804ddd08

and press f12. soon i got the break but single-step the "cmp" still
die

:(
mengxp

mengxp(孟学政)

unread,
Jul 28, 2011, 4:37:06 AM7/28/11
to hyperdbg
b 804ddd09

breakpoint on the "cmp [esp+24h+var_8], 0"

i wrote wrong :D

Aristide Fattori

unread,
Jul 28, 2011, 6:38:25 AM7/28/11
to hype...@googlegroups.com
Hi,

this behavior was expected. Could you please try the patch in
attachment (patched agains the current svn version). It should now
meet the requirements of the manual and avoid triggering the VMEXIT
33, but I am unable to try it out myself as BOCHS seems to completely
ignore the interruptibility state.

TIA,
Aristide

2011/7/28 mengxp(孟学政) <m...@live.cn>:

--

hyperdbg_r122_singlestep.diff

mengxp(孟学政)

unread,
Jul 28, 2011, 7:35:41 AM7/28/11
to hyperdbg
Hi,

your code has some mistake.
set bit14 should be this : pending_debug |= 0x4000

and HLT state is in GUEST_ACTIVITY_STATE

so code is ...

void VmxHvmInternalHandleExit(void)
{
Bit32u interruptibility,activitystate, pending_debug;
------------------------------------------------------------------------------------
HypercallSwitchOff(NULL);

Resume:

/* We need to check if TF is set*/
if((context.GuestContext.rflags & FLAGS_TF_MASK) != 0) {
Log("[VmxHvmInternalHandleExit] RFLAGS.TF == 1");
/* Here we must check if interruptibility-state field indicates a
blocking cause of STI, MOV SS or HLT */
interruptibility = VmxVmcsRead(GUEST_INTERRUPTIBILITY_INFO);
activitystate = VmxVmcsRead(GUEST_ACTIVITY_STATE);
/* STI (bit 0) MOV SS (bit
1) HLT (x) */
if((interruptibility & 0x1) != 0 || (interruptibility & 0x2) != 0 ||
(activitystate == 1) {
/* We must also check bit 1 of IA32_DEBUGCTL */
if((VmxVmcsRead(GUEST_IA32_DEBUGCTL) & 0x2) == 0) {
Log("[VmxHvmInternalHandleExit] Setting
GUEST_PENDING_DEBUG_EXCEPTIONS.BS to 1");
/* Since we just set RFLAGS.TF = 1, we need to set BS (bit 14) in
pending debug exception field */
pending_debug = VmxVmcsRead(GUEST_PENDING_DBG_EXCEPTIONS);
pending_debug |= 0x4000; /* bit 14 */
VmxVmcsWrite(GUEST_PENDING_DBG_EXCEPTIONS, pending_debug);
}
else {
Log("[VmxHvmInternalHandleExit] Setting
GUEST_PENDING_DEBUG_EXCEPTIONS.BS to 0 because
GUEST_IA32_DEBUGCTL.BTF != 0");
/* We must set GUEST_PENDING_DBG_EXCEPTIONS.BS = 0 */
pending_debug = VmxVmcsRead(GUEST_PENDING_DBG_EXCEPTIONS);
pending_debug &= ~0x4000; /* bit 14 */
VmxVmcsWrite(GUEST_PENDING_DBG_EXCEPTIONS, pending_debug);
}
}
}
else {
/* We must set GUEST_PENDING_DBG_EXCEPTIONS.BS = 0 because RFLAGS.TF
== 0*/
pending_debug = VmxVmcsRead(GUEST_PENDING_DBG_EXCEPTIONS);
pending_debug &= ~0x4000; /* bit 14 */
VmxVmcsWrite(GUEST_PENDING_DBG_EXCEPTIONS, pending_debug);
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------
even though we don't get a exitcode33 but debugger never step over the
instruction "cmp [esp+24h+var_8], 0" :-(

it stop at "cmp [esp+24h+var_8], 0" forever unless we give up
single-step...

------------------------------------------------------------------------------------------------------------------------------------------------------------------------
I have a question that

Do you have a physical cpu support intel-vt?

It seems that the vmx simulated by bochs has big difference from
physical cpu



here is some code that support hyperdbg GUI

but it is wrote in masm language ( I like writing some small program
with masm at the past :D but now I write kernel driver with VS2010 +
DDK ..)

just run it and can get the real FrameBuffer

I modified your video.c so the hyperdbg GUI works well on my machine

-----------------------------------------------------------------------------------------------------------------------------------------------
hvm_status VideoInit(void)
{

video_address = (hvm_address)0xD0060000; //got from my
FrameBufferLocker
video_sizex = 1280;
video_stride = 2048;
video_sizey = 800;
framebuffer_size =
video_sizey*video_stride*FRAME_BUFFER_RESOLUTION_DEPTH;
-----------------------------------------------------------------------------------------------------------------------------------------------

with DirectDraw's help,now we can operate the Frame buffer directly

this is a really good way to help hyperdbg run on a physical machine

I think you should run hyperdbg in physical machine ,and i believe you
have the ability to solve that problem!


:D
mengxp

mengxp(孟学政)

unread,
Jul 28, 2011, 7:38:23 AM7/28/11
to hyperdbg
here is the small tool
http://www.deadc0de.com/fb.rar

Aristide Fattori

unread,
Jul 28, 2011, 8:04:20 AM7/28/11
to hype...@googlegroups.com
Hi,

2011/7/28 mengxp(孟学政) <m...@live.cn>:


> Hi,
>
> your code has some mistake.
> set bit14 should be this : pending_debug |= 0x4000
>
> and HLT state is in GUEST_ACTIVITY_STATE
>
> so code is ...

Ops, you're right, thanks.

> even though we don't get a exitcode33 but debugger never step over the
> instruction "cmp     [esp+24h+var_8], 0"   :-(
>
> it stop at "cmp     [esp+24h+var_8], 0" forever unless we give up
> single-step...

Ouch, it probably needs some more handling then. I'll try to check it out.

> I have a question that
>
> Do you have a physical cpu  support intel-vt?

If I had one right now I wouldn't be asking you to try a patch "as-is"
without testing it myself :-) Unfortunately I won't be able to try it
on a physical CPU for a couple of weeks at least.

> here is some code that support hyperdbg  GUI
>
> but it is wrote in masm language ( I like writing some small program
> with masm at the past :D but now I write kernel driver with VS2010 +
> DDK ..)
>
> just run it and can get the real  FrameBuffer
>
> I modified your video.c so the hyperdbg GUI works well on my machine
>
> -----------------------------------------------------------------------------------------------------------------------------------------------
> hvm_status VideoInit(void)
> {
>
>  video_address = (hvm_address)0xD0060000;  //got from my
> FrameBufferLocker
>  video_sizex = 1280;
>  video_stride = 2048;
>  video_sizey = 800;
>  framebuffer_size =
> video_sizey*video_stride*FRAME_BUFFER_RESOLUTION_DEPTH;
> -----------------------------------------------------------------------------------------------------------------------------------------------
>
> with DirectDraw's help,now we can operate the Frame buffer directly
>
> this is a really good way to help hyperdbg run on a physical machine

Thanks, it looks very cool! We will check it out ASAP :-)

> I think you should run hyperdbg in physical machine ,and i believe you
> have the ability to solve that problem!

I ran hyperdbg on a physical machine more than once, but never caught
this bug. As I said, I don't have the possibility to test it right now
as I don't have a machine with XP and VT-x that I can use.

Thanks for your help,
Aristide

Reply all
Reply to author
Forward
0 new messages