Category : Files from Magazines
Archive   : JAN94.ZIP
Filename : UNDOC.ASC

 
Output of file : UNDOC.ASC contained in archive : JAN94.ZIP
_UNDOCUMENTED CORNER_
by Kelly Zytaruk
edited by Andrew Schulman



Figure 1: Accessing a VMCB from a Windows program.

// for Windows 3.1 only!
#define VM_FROM_HWND(hWndDosBox) \
*((LPDWORD) MK_FP(GetWindowWord(hWndDosBox, GWW_HINSTANCE), 0x0FC))
// undocumented Windows API function; see UndocWin, pp. 303-304
extern BOOL FAR PASCAL IsWinOldApTask(HANDLE hTask);
#define ISDOSBOX(hWnd) IsWinOldApTask(GetWindowTask(hWnd))
if (ISDOSBOX(hwnd)) {
DWORD vm_handle = VM_FROM_HWND(hwnd);
VMCB far *vm_cb = (VMCB far *) map_linear(VM_FROM_HWND(hwnd),
sizeof(VMCB));
WORD ldt = vm_cb->CB_LDT;
// or *((WORD far *) ((BYTE far *) vm_cb) + 0x114)
FreeSelector(FP_SEG(vm_cb));
// now do something with LDT in other VM
}


Figure 2: Displaying a Selector List.

(a)

C:\DDJ\VM>protdump -vm
#1 VMCB=804C1000 high lin=81C00000h
#2 VMCB=8065A000 high lin=82000000h


(b)

C:\DDJ\VM>protdump -ptr -list -dword 804c1048 8
804007E0 | 000E0000 0000104F
804007D4 | 000D0000 00001047
804007C8 | 000C0000 0000103F
804007BC | 000B8000 00001037
804007B0 | 000B0000 0000102F
804007A4 | 000A0000 00001027
80400798 | 000F0000 0000101F
8040078C | 00000400 00001017
80400770 | 00000000 0000100F
804002D4 | 000009A0 00001007
804002C8 | 0001E490 000000C7


(c)

C:\DDJ\VM>protdump -prot #1 101f:fff0
81CFFFF0 | EA 5B E0 00 F0 30 36 2F 30 36 2F 39 31 00 FC 00 | .[...06/06/91...
81D00000 | 00 00 00 56 44 49 53 4B 33 2E 33 80 00 01 01 00 | ...VDISK3.3.....


(d)

C:\DDJ\VM>protdump -prot #1 0617:00f0
81C4FEF0 | 00 00 50 52 4F 47 4D 41 4E 00 54 44 00 00 00 00 | ..PROGMAN.TD....

(e)

C:\DDJ\VM>protdump -all DOS:330 -word 2
#1 81C00CD0 | 29DC
#2 82000CD0 | 710B



Figure 3: Layout of a sample VM Control Block

VxD Owner Size Offset into VMCB
--------- ---- ----------------
VMM 210h 0h
VPICD BCh 210h
VTD 17h 2CCh
VDDVGA 840h 2EAh
VKD E3h B24h
VFD 2h C08h - Note that sizes are rounded
DOSMGR 4Dh C0Ch up to a multiple of 4 bytes
. . .
. . .
. . .
VSERVER 4h 1A9Ch
VMPOLL 14h 1AA0h
VPFD 8Ch 1AB4h



Figure 4: The Windows 3.1 Virtual Machine Control Block (offsets are
for the retail version)

typedef struct {
DWORD CB_VM_Status; // 00h
DWORD CB_High_Linear; // 04h
DWORD CB_Client_Pointer; // 08h
DWORD CB_VMID; // 0Ch
DWORD CB_PM_Int_Table; // 10h
DWORD CB_VM_ExecTime; // 14h
DWORD CB_V86_PageTable; // 18h
DWORD CB_Local_Port_Trapping_BitMap[8]; // 1Ch
DWORD CB_Begin_Nested_Exec_List; // 3Ch
DWORD CB_OS_Stack; // 40h
DWORD CB_Scheduler_Flags; // 44h
DWORD CB_Selector_List; // 48h
WORD CB_unused0; // 4Ch
WORD CB_Locked_PM_Stack_LDT; // 4Eh
WORD CB_Locked_PM_Stack_GDT; // 50h
WORD CB_Locked_PM_Stack_Prev_SS; // 52h
DWORD CB_Locked_PM_Stack_Prev_ESP; // 54h
DWORD CB_Locked_PM_Stack_hMem; // 58h
DWORD CB_Locked_PM_Stack_Count; // 5Ch
DWORD CB_Locked_PM_Stack_EIP; // 60h
DWORD CB_PM_App_CB; // 64h
DWORD CB_VM_List_Link; // 68h
DWORD CB_ListNext; // 6Ch
DWORD CB_ListHead; // 70h
DWORD CB_BlockedSemaphore; // 74h
DWORD CB_SuspendedList_Head; // 78h
DWORD CB_Suspended_BlockedSemaphore; // 7Ch
DWORD CB_Exec_Priority_Bits; // 80h
DWORD CB_SchedulerStatus // 84h
DWORD CB_Suspended_Stack; // 88h
DWORD CB_TSS_ESP0; // 8Ch
DWORD CB_hMem_Stack; // 90h
DWORD CB_SuspendedVM_Count; // 94h
DWORD CB_SuspendedVM_EventHandle; // 98h
WORD CB_ForeGround_TS_Priority; // 9Ch
WORD CB_BackGround_TS_Priority; // 9Eh
DWORD CB_Weighted_Priority; // A0h
DWORD CB_Weighted_Time; // A4h
DWORD CB_Next_Scheduled_VM; // A8h
DWORD CB_Last_Weighted_VMTime; // ACh
DWORD CB_ExtendedErrorCode; // B0h
DWORD CB_ExtendedErrorRefData; // B4h
DWORD CB_V86_PgTbl_PhysAddr; // B8h
DWORD CB_Int_Table_Instance; // BCh
DWORD CB_hMem_VMDataArea; // C0h
DWORD CB_Int_Table_hMem; // C4h
DWORD CB_DeviceV86Pages[9]; // C8h
DWORD CB_V86PageableArray[8]; // ECh
DWORD CB_MMGR_Flags; // 10Ch
DWORD CB_MMGR_Pages; // 110h
WORD CB_LDT; // 114h
WORD CB_unused2; // 116h
DWORD CB_hMem_LDT; // 118h
DWORD CB_VM_Event_Count; // 11Ch
DWORD CB_VM_Event_List; // 120h
DWORD CB_Priority_VM_Event_List; // 124h
DWORD CB_CallWhenVMIntsEnabled_Count; // 128h
DWORD CB_CallWhenVMIntsEnabled_List; // 12Ch
DWORD CB_Next_Timeout_Handle; // 130h
DWORD CB_Prev_Timeout_Handle; // 134h
DWORD CB_First_Timeout; // 138h
DWORD CB_Expiration_Time; // 13Ch
DWORD CB_IDT_Base_hMem; // 140h
WORD CB_unused3; // 144h
WORD CB_IDT_Limit; // 146h
DWORD CB_IDT_Base; // 148h
struct { // 14Ch
DWORD Ex_EIP;
WORD Ex_CS;
} CB_Exception_Handlers[32];
DWORD CB_V86_CallBack_List; // 20Ch
// end of VMM portion
// start of VxD CB areas
} VM_ControlBlock; // size: 210h bytes



Figure 5: Using the documented VMCB CB_High_Linear field to read
real-mode memory in other VMs. The somehow_get_VM_handle() function
could be implemented using VM_FROM_HWND() in Figure 1, or with
the generic VxD.

DWORD LinAddr = (0x40L << 4) + 8;
DWORD VMHandle = somehow_get_VM_handle();
VMCB far *VMCB = map_linear(VMHandle, sizeof(VMCB));
LinAddr += VMCB->CB_High_Linear;
FreeSelector(FP_SEG(VMCB));
WORD far *WPtr = map_linear(LinAddr, sizeof(WORD));
WORD W = *WPtr;
FreeSelector(FP_SEG(WPtr));
// W is WORD at 40:08 in other VM



  3 Responses to “Category : Files from Magazines
Archive   : JAN94.ZIP
Filename : UNDOC.ASC

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/