Sysprogs forums › Forums › VisualDDK/VirtualKD discussion › VirtualBox running Win7 won’t start
- This topic has 39 replies, 3 voices, and was last updated 13 years, 2 months ago by jet_lee_spy.
-
AuthorPosts
-
May 21, 2011 at 14:47 #1508AnonymousParticipant
@bazis wrote:
Go to VM properties, add select Ports, set COM1 to point to a local pipe (\.pipecom_1), start WinDbg with parameters: “-k com:pipe,port=.\pipedebug”.
Thanks. What to select on the guest ? The Virtual KD boot entry or do I need to create a new one for COM ?
May 21, 2011 at 14:50 #1509supportKeymasterbcdedit /dbgsettings serial debugport:1
then, use VirtualKD entry
More details here: http://msdn.microsoft.com/en-us/windows/hardware/gg487520May 21, 2011 at 16:21 #1510AnonymousParticipantOk, after some hours of struggling I got the COM debugging running.
Because some of the steps where unclear or wrong typed, here the correct steps, just in case someone else will find this posting:
Host:
– open VirtualBox manager, edit the VM and go to serial ports, activate port 1, port number = 1, port mode =Host pipe, check “create pipe”, pipe name: \.pipecom_1Guest:
– create a new boot entry, for example using EasyBCD or bcdedit, make a copy of your default boot entry and enable debugging for this new entry (bcdedit /debug on)
– call “bcdedit /dbgsettings serial debugport:1” from a cmd with admin privilegesNow start the VM and select the new debug entry. The suggested VirtualKD entry did not work for me, it just waits forewer.
WinDbg:
windbg -k com:pipe,port=\.pipecom_1,resets=0,reconnectAfter WinDbg has loaded it should display:
Opened \.pipecom_1
Waiting to reconnect…Hit Ctrl+Break and you are connected.
I will now look at the dynamic patching suggestions and come back with the results.
May 21, 2011 at 16:26 #1511supportKeymasterok, thanks for the reference walkthrough.
May 21, 2011 at 16:45 #1512AnonymousParticipantok, copied kdpatch.sys and kdvm.dll to system32drivers and executed kdpatch.reg.
After reboot of the VM I get the following bugcheck:
Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.Opened \.pipecom_1
Waiting to reconnect…
Connected to Windows 7 7600 x86 compatible target at (Sat May 21 18:31:05.888 2011 (UTC + 2:00)), ptr64 FALSE
Kernel Debugger connection established.
Symbol search path is: srv*F:SDKssymbols
Executable search path is:
Windows 7 Kernel Version 7600 MP (1 procs) Free x86 compatible
Built by: 7600.16385.x86fre.win7_rtm.090713-1255
Machine Name:
Kernel base = 0x82849000 PsLoadedModuleList = 0x82991810
System Uptime: not available*** Fatal System Error: 0x0000007e
(0xC0000005,0x2041764D,0x80786898,0x80786470)Break instruction exception – code 80000003 (first chance)
A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.A fatal system error has occurred.
Connected to Windows 7 7600 x86 compatible target at (Sat May 21 18:31:32.341 2011 (UTC + 2:00)), ptr64 FALSE
Loading Kernel Symbols
………………………………………………………
……………
Loading User Symbols*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************Use !analyze -v to get detailed debugging information.
BugCheck 7E, {c0000005, 2041764d, 80786898, 80786470}
Probably caused by : hardware
Followup: MachineOwner
*** Possible invalid call from 8d7d6a2b ( kdpatch+0x2a2b )
*** Expected target 8d7d6db0 ( kdpatch+0x2db0 )nt!RtlpBreakWithStatusInstruction:
828b4394 cc int 3
0: kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (7e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: 2041764d, The address that the exception occurred at
Arg3: 80786898, Exception Record Address
Arg4: 80786470, Context Record AddressDebugging Details:
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 – Die Anweisung in “0x%08lx” verweist auf Speicher in “0x%08lx”. Der Vorgang “%s” konnte nicht auf dem Speicher durchgef hrt werden.
FAULTING_IP:
+1ad2faf00b2dfc0
2041764d ?? ???EXCEPTION_RECORD: 80786898 — (.exr 0xffffffff80786898)
ExceptionAddress: 2041764d
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 2041764d
Attempt to read from address 2041764dCONTEXT: 80786470 — (.cxr 0xffffffff80786470)
eax=ffffffff ebx=00000000 ecx=80786978 edx=0000000d esi=8d7da060 edi=84e7e000
eip=2041764d esp=80786960 ebp=80786b9c iopl=0 nv up ei ng nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010286
2041764d ?? ???
Resetting default scopeDEFAULT_BUCKET_ID: INTEL_CPU_MICROCODE_ZERO
PROCESS_NAME: System
CURRENT_IRQL: 2
ERROR_CODE: (NTSTATUS) 0xc0000005 – Die Anweisung in “0x%08lx” verweist auf Speicher in “0x%08lx”. Der Vorgang “%s” konnte nicht auf dem Speicher durchgef hrt werden.
EXCEPTION_PARAMETER1: 00000000
EXCEPTION_PARAMETER2: 2041764d
READ_ADDRESS: 2041764d
FOLLOWUP_IP:
+1ad2faf00b2dfc0
2041764d ?? ???FAILED_INSTRUCTION_ADDRESS:
+1ad2faf00b2dfc0
2041764d ?? ???BUGCHECK_STR: 0x7E
LAST_CONTROL_TRANSFER: from 8d7d6a30 to 2041764d
POSSIBLE_INVALID_CONTROL_TRANSFER: from 8d7d6a2b to 8d7d6db0
STACK_TEXT:
WARNING: Frame IP not in any known module. Following frames may be wrong.
8078695c 8d7d6a30 84e7e000 85116a70 57454e42 0x2041764d
80786b9c 82bfa853 00000001 00000000 80786bd4 kdpatch+0x2a30
80786be8 82bf687b 80807e98 8080a908 00000000 nt!IopInitializeSystemDrivers+0x163
80786c6c 82bfbe6f 0080a908 83e630b8 83e63d48 nt!IoInitSystem+0x6de
80786d48 829d447c 80786d90 82a5766d 8080a908 nt!Phase1InitializationDiscard+0xce4
80786d50 82a5766d 8080a908 73e79bf0 00000000 nt!Phase1Initialization+0xd
80786d90 829090d9 829d446f 8080a908 00000000 nt!PspSystemThreadStartup+0x9e
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x19FOLLOWUP_NAME: MachineOwner
MODULE_NAME: hardware
IMAGE_NAME: hardware
DEBUG_FLR_IMAGE_TIMESTAMP: 0
STACK_COMMAND: .cxr 0xffffffff80786470 ; kb
BUCKET_ID: CPU_CALL_ERROR
Followup: MachineOwner
*** Possible invalid call from 8d7d6a2b ( kdpatch+0x2a2b )
*** Expected target 8d7d6db0 ( kdpatch+0x2db0 )May 21, 2011 at 19:23 #1513AnonymousParticipantI quickly build and debugged the driver kdpatch.sys.
With the recompiled driver it longer bluescrens but VBox is not correctly detected. I don’t know if the sources from SourceForge are actual.
The following check fails, eax is 0xFFFFFFFF
Any idea ???
cmp eax, ‘XOBV’ //’VBOX’ signature is returned, if this call was made under VirtualBox
jz vmware_rpc_open_channel_vbox//! Opens a GuestRPC channel.
static unsigned __declspec(naked) __fastcall OpenChannel(VMWareRpcData *pChannel)
{
__asm
{
pushad
mov eax, 0x564D5868
mov ebx, 0xC9435052
xchg ecx,ebp
mov ecx, 0x0000001E
mov edx, 0x5658
out dx, eax
test ecx, 0x00010000
jz vmware_rpc_open_channel_error
mov [ebp].m_Cookie1, esi
mov [ebp].m_Cookie2, edi
mov [ebp].m_ChannelNumber, edx
popad
xor eax, eax
inc eax
ret
vmware_rpc_open_channel_error:
mov edx, 0x5658
in eax, dx
cmp eax, ‘XOBV’ //’VBOX’ signature is returned, if this call was made under VirtualBox
jz vmware_rpc_open_channel_vbox
popad
xor eax, eax
ret
vmware_rpc_open_channel_vbox:
popad
xor eax, eax
add eax, 2
ret
}
}May 22, 2011 at 10:06 #1514supportKeymasterThe sources are actual. The -1 in eax is even more strange.
I would suggest building a debug version of VBoxDD.DLL, copying it to VirtualBox dir, attaching to the VirtualBox process from Visual Studio and setting breakpoints on VirtualKDPortOutHandler() and VirtualKDPortInHandler(). These functions get called when the debug I/O port is read/written.
If VirtualKDPortInHandler() is not called, please try replacing 0x5658 (and 0x5659) with some other port number (note that 2 consequent ports are used). You will need to modify ConstructOverride() in VBoxDD.DLL and several .h/.asm files in kdvm directory.May 22, 2011 at 10:08 #1515AnonymousParticipantHi again, I continued to debug kdpatch.sys and found something interesting,
The question first so it gets not overseen between al the lines:
Is it possible that VirtualKD does not work correctly if you set ICH9 chipsets and not PIX chipsets in the VM ????
=============================
Regarding the bluescreens I come to the following clue:
1. the main problem seems that vboxdd.dll does not register callbacks correctly, when using ICH9 chipsets, callbacks are registered only for the PIX (pci) drivers but these callbacks are never called
2. because of this, OpenChannels fails and NegotiateProtocolVersions bluescreens with the release version of kdpatch.sys
I don’t know enough about Virtual machines to know all the details, but here is what I have debugged:
– OpenChannel fails to detect VBOX, because “in eax, dx” returns -1
– NegotiateProtocolVersions incorrectly assumes that VMWare is running and seems to send commands to VMWare
– this leads to an BlueScreen if kdpatch.sys is compiled as release version, but not with the debug version
– you can surely debug this yourself with the release build, if you do not use the patched VBoxDD.dll so “in eax, dx” failsI have the code commented below, look for “Ronald”:
static unsigned __declspec(naked) __fastcall OpenChannel(VMWareRpcData *pChannel)
{
__asm
{
……….
vmware_rpc_open_channel_error:
mov edx, 0x5658
in eax, dx
cmp eax, ‘XOBV’ //’VBOX’ signature is returned, if this call was made under VirtualBox// !!!! Ronald: fails here !!!!!
jz vmware_rpc_open_channel_vbox
popad
xor eax, eax
ret=========================================
static NTSTATUS NegotiateProtocolVersions()
{
DefaultRPCChannel channel;
if (channel.NeedRestartInVBoxMode())
{
s_bVBoxDetected = true;
return STATUS_RETRY;
}// !!! Ronald: because OpenChannel faild, continued here…. !!!!
channel.PrepareSend(5 + sizeof(g_szRPCCommandHeader) – 1);
char commandType = VersionReport;
int version = KDRPC_PROTOCOL_VERSION;
if (!channel.SendPartial(&g_szRPCCommandHeader, sizeof(g_szRPCCommandHeader) – 1))
return STATUS_CONNECTION_REFUSED;
if (!channel.SendPartial(&commandType, 1))
return STATUS_CONNECTION_REFUSED;
channel.SendPartial(&version, 4);// !!!! Ronald: the release build bluescreens in GetReplaySize() when executing the “ret” instruction
// prohably some stack override or problem with compiler optimization, I could not find out yet
// you should definitely put exception handling arround the code in this procif (channel.GetReplySize() != (4 + 2 + sizeof(g_szRPCReplySignature) – 1))
// !!! Ronald: the debug build just returns STATUS_CONNECTION_REFUSED
return STATUS_CONNECTION_REFUSED;=======================================
templateclass BufferedRPCChannel : private VMWareRPCChannel
{
……….
unsigned GetReplySize()
{
if (m_Phase == Receiving)
return m_TotalTransferSize;
if (!SendBufferedData())
return -1;
if (m_Phase != Sent)
return -1;
m_TotalTransferSize = __super::GetReplySize();// Ronald: !!!! the following equals to false
if (m_TotalTransferSize && (m_TotalTransferSize != -1) && (m_TotalTransferSize <= t_BufferSize))
{
if (!__super::Receive(t_pBuffer, t_BufferSize))
return -1;
m_Phase = Receiving;
m_BufferPos = 0;
return m_TotalTransferSize;
}
else
return -1;// bluescreens if the function returns (disassembly)
…
pop edit
ret <- BUMM - prohably stack override
}May 22, 2011 at 10:19 #1516AnonymousParticipantI already build and debugged VBoxDD.dll and found out that RegisterOverride registers something for the pci driver, but “ConstructOverride” gets never called. prohably because I use ICH9 chipsets.
If “ConstructOverride” gets not called, VirtualKDPortOutHandler, VirtualKDPortInHandler are also not assigned and this seems to be the reason why everything else fails.
I use the ICH9 chipset with IO-APIC activated, ICH6 IDE controller for the CD-Rom and AHCI SATA controler for the disk drive.
static int RTCALL RegisterOverride(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pDevReg)
{
if (pDevReg)
{
if (!strcmp(VIRTUALKD_HOOKED_VBOX_DEVICE_NAME, pDevReg->szName))
{
PPDMDEVREG pReg = new PDMDEVREG();
*pReg = *pDevReg;
s_pOriginalDevReg = pDevReg;
pReg->pfnConstruct = ConstructOverride; // Ronald: gets never called
pDevReg = pReg;
}
}
return ((DevRegisterCallbacksHook *)pCallbacks)->pOriginalCallbacks->pfnRegister(((DevRegisterCallbacksHook *)pCallbacks)->pOriginalCallbacks, pDevReg);
}May 22, 2011 at 10:28 #1517AnonymousParticipantJust in case someone else tries to debug vboxdd.dll anytime, you need to set virtualbox.exe as debugger target in visual studio and add the following commandline:
–comment “Win7 Professional 32Bit” –startvm 868457e4-b38e-4025-a2e1-9489d2f2393f –no-startvm-errormsgbox
Replace the VM name and guid with your values.
You can not just debug using virtualbox.exe, because vbox spawns another process with the above commandline.
Ronald
May 22, 2011 at 10:36 #1518supportKeymasterI assume, the problem is with the VIRTUALKD_HOOKED_VBOX_DEVICE_NAME set to “pci” (see VBoxDD.cpp).
In your case you might have to change it to some other device loaded by VirtualBox.May 22, 2011 at 10:41 #1519AnonymousParticipantI already did this one second before, and this solves the problem !!!!!
With:
#define VIRTUALKD_HOOKED_VBOX_DEVICE_NAME “ich9pci”
everything works as expected.
I assume that everyone with ICH9 chipsets will have this problem, I have read many post at the net where someone could not get virtualkd to work under w7, this could be a possible cause.
May 22, 2011 at 10:56 #1520AnonymousParticipantOk, here is a quickfix to support both devices. if i understand it correctly, ConstructOverride is just used to register the IOPortRegisters, so we assign ConstructOverride to both drivers and set a global flag if the proc was already called. For me this works just fine.
#define VIRTUALKD_HOOKED_VBOX_DEVICE_NAME1 “pci”
#define VIRTUALKD_HOOKED_VBOX_DEVICE_NAME2 “ich9pci”static PCPDMDEVREG s_pOriginalDevReg = NULL;
static bool g_IsOverriden = FALSE;static int RTCALL ConstructOverride(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
{
// Ronald: check if g_IsOverride is already TRUE, if so, just exit
if (!s_pOriginalDevReg || g_IsOverriden)
return VINF_OBJECT_DESTROYED;
pDevIns->pReg = s_pOriginalDevReg;
int rc = s_pOriginalDevReg->pfnConstruct(pDevIns, iInstance, pCfgHandle);
if (!RT_SUCCESS(rc))
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x5658, 2, NULL, VirtualKDPortOutHandler, VirtualKDPortInHandler, NULL, NULL, “VirtualKD interface”);
if (!RT_SUCCESS(rc))
return rc;
// Ronald: set g_isOverriden to TRUE so the proc is not executed again
g_IsOverriden = TRUE;
return VINF_SUCCESS;
}struct DevRegisterCallbacksHook : public PDMDEVREGCB
{
PPDMDEVREGCB pOriginalCallbacks;DevRegisterCallbacksHook(const PDMDEVREGCB &Callbacks) : PDMDEVREGCB(Callbacks)
{
pfnRegister = &RegisterOverride;
// pfnMMHeapAlloc = &AllocOverride;
}static int RTCALL RegisterOverride(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pDevReg)
{
if (pDevReg)
{
// Ronald: look for both device names here
if ((!strcmp(VIRTUALKD_HOOKED_VBOX_DEVICE_NAME1, pDevReg->szName)) ||
(!strcmp(VIRTUALKD_HOOKED_VBOX_DEVICE_NAME2, pDevReg->szName)))
{
PPDMDEVREG pReg = new PDMDEVREG();
*pReg = *pDevReg;
s_pOriginalDevReg = pDevReg;
pReg->pfnConstruct = ConstructOverride;
pDevReg = pReg;
}
}
return ((DevRegisterCallbacksHook *)pCallbacks)->pOriginalCallbacks->pfnRegister(((DevRegisterCallbacksHook *)pCallbacks)->pOriginalCallbacks, pDevReg);
}May 22, 2011 at 11:34 #1521supportKeymasterOK, thanks for the fix. I’ll include it in the next version.
May 22, 2011 at 11:53 #1522AnonymousParticipantI did not realize at the first moment, that ConstructOverride does some other work and requires the correct s_pOriginalDevReg for the device.
So here is the fix corrected, handling every device completely separately, but registers the IOPorts only once.
This was really an nice debugging session, where I learned many new things. Thank you for these awesome products.
However, you should definitely rework and extend the doscumentation a bit, it’s sometimes unclear and uncomplete, which makes it very difficult to use the excellent tools at the first step.
Keep up the good work.
==========================
#define VIRTUALKD_HOOKED_VBOX_DEVICE_NAME1 “pci”
#define VIRTUALKD_HOOKED_VBOX_DEVICE_NAME2 “ich9pci”static PCPDMDEVREG s_pOriginalDevReg1 = NULL;
static PCPDMDEVREG s_pOriginalDevReg2 = NULL;
static bool g_IOInstalled = FALSE;static int RTCALL ConstructOverride1(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
{
if (!s_pOriginalDevReg1)
return VINF_OBJECT_DESTROYED;
pDevIns->pReg = s_pOriginalDevReg1;
int rc = s_pOriginalDevReg1->pfnConstruct(pDevIns, iInstance, pCfgHandle);
if (!RT_SUCCESS(rc))
return rc;if (!g_IOInstalled)
{
rc = PDMDevHlpIOPortRegister(pDevIns, 0x5658, 2, NULL, VirtualKDPortOutHandler, VirtualKDPortInHandler, NULL, NULL, “VirtualKD interface”);
if (!RT_SUCCESS(rc))
return rc;
g_IOInstalled = TRUE;
}
return VINF_SUCCESS;
}static int RTCALL ConstructOverride2(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
{
if (!s_pOriginalDevReg2)
return VINF_OBJECT_DESTROYED;
pDevIns->pReg = s_pOriginalDevReg2;
int rc = s_pOriginalDevReg2->pfnConstruct(pDevIns, iInstance, pCfgHandle);
if (!RT_SUCCESS(rc))
return rc;if (!g_IOInstalled)
{
rc = PDMDevHlpIOPortRegister(pDevIns, 0x5658, 2, NULL, VirtualKDPortOutHandler, VirtualKDPortInHandler, NULL, NULL, “VirtualKD interface”);
if (!RT_SUCCESS(rc))
return rc;
g_IOInstalled = TRUE;
}
return VINF_SUCCESS;
}struct DevRegisterCallbacksHook : public PDMDEVREGCB
{
PPDMDEVREGCB pOriginalCallbacks;DevRegisterCallbacksHook(const PDMDEVREGCB &Callbacks) : PDMDEVREGCB(Callbacks)
{
pfnRegister = &RegisterOverride;
// pfnMMHeapAlloc = &AllocOverride;
}static int RTCALL RegisterOverride(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pDevReg)
{
if (pDevReg)
{
if (!strcmp(VIRTUALKD_HOOKED_VBOX_DEVICE_NAME1, pDevReg->szName))
{
PPDMDEVREG pReg = new PDMDEVREG();
*pReg = *pDevReg;
s_pOriginalDevReg1 = pDevReg;
pReg->pfnConstruct = ConstructOverride1;
pDevReg = pReg;
}
else if (!strcmp(VIRTUALKD_HOOKED_VBOX_DEVICE_NAME2, pDevReg->szName))
{
PPDMDEVREG pReg = new PDMDEVREG();
*pReg = *pDevReg;
s_pOriginalDevReg2 = pDevReg;
pReg->pfnConstruct = ConstructOverride2;
pDevReg = pReg;
}}
return ((DevRegisterCallbacksHook *)pCallbacks)->pOriginalCallbacks->pfnRegister(((DevRegisterCallbacksHook *)pCallbacks)->pOriginalCallbacks, pDevReg);
} -
AuthorPosts
- You must be logged in to reply to this topic.