Los archivos VxD supestamente siempre son archivos con la marca "LE" en vez de "LX".
De la cabecera LE EXE:
MemPagesCtr es la cuenta de bloques de tamaño MemPageSZ en disco, que hasta ahora puedo dejar a 512 bytes de tamaño.
LastPageBytes dice cuántos bytes tiene el último bloque en el archivo, que puede ser menor o tal vez igual que MemPageSZ.
En el código, los servicios VxD se llaman con INT 20H, seguido de 4 bytes que tienen códigos de los servicios a llamar. Windows mismo se encarga de saltarse esos 4 bytes después de la instrucción INT para evitar errores de ejecución con esos bytes de opcode inválidos.
Esqueleto simple en NASM que muestra un MessageBox al abrir o cerrar una ventana de consola de MS-DOS:
Código:
;http://master.dl.sourceforge.net/project/api-simple-completa/api.7z?viasf=1
%include "../../../PC/BIOS/WinAPI/EXE/PE/snippets/DOS_Stubs/NASM/DOS_Stub_classic0xB0.asm"
PE_header:
LE_header:
LE_header_start:
LE_header_0x00_Signature db 'LE'
LE_header_0x02_ByteOrder db 0 ;0 Little or Big Endian
LE_header_0x03_WordOrder db 0 ;0 Little or Big Endian
LE_header_0x04_FormatLevel dd 0
LE_header_0x08_CPUType dw 2 ;1 286+, 2 386+, 3 486+, 4 586+, 20h i860 N10+, 21h N11+, 40h MIPS Mark I+ (R2000, R3000), 41h MIPS Mark II+ (R6000), 42h MIPS Mark III+ (R4000)
LE_header_0x0A_TargetOS dw 4 ;1 OS/2, 2 Win16, 3 DOS 4x, 4 Win386
LE_header_0x0C_ModuleVersion dd 0
LE_header_0x10_Flags dd 101000000000000000b ;
LE_header_0x14_MemPagesCtr dd 3
LE_header_0x18_InitialCS dd 0
LE_header_0x1C_InitialEIP dd 0 ;Explicar cómo encuentra y carga las secciones y direcciones de código y datos el VxD
LE_header_0x20_InitialSS dd 0
LE_header_0x24_InitialESP dd 0
LE_header_0x28_MemPageSZ dd 512 ;Tamaño de datos
LE_header_0x2C_LastPageBytes dd 0x31
LE_header_0x30_FixUpSectionSZ dd 0x85
LE_header_0x34_FixUpSectionCheck dd 0
LE_header_0x38_LdrSectionSZ dd 0x69
LE_header_0x3C_LdrSectionCheck dd 0
LE_header_0x40_ObjectTableOffset dd 0xC4 ;from where?
LE_header_0x44_ObjectTableEntries dd 3
LE_header_0x48_ObjectPageMapOffset dd 0x10C
LE_header_0x4C_ObjectIterDataMapOff dd 0 ;always 0 for VxD?
LE_header_0x50_RsrcTableOffset dd 0
LE_header_0x54_RsrcTableEntries dd 0
LE_header_0x58_ResidentTableOffset dd 0x118
LE_header_0x5C_EntryTableOffset dd 0x123
LE_header_0x60_ModulDirectivesTable dd 0 ;always 0 for VxD?
LE_header_0x64_ModulDirectivesEnts dd 0
LE_header_0x68_FixupPageTblOffset dd 0x12D
LE_header_0x6C_FixupRecordTable dd 0x13D
LE_header_0x70_ImportModulesTable dd 0x1B2
LE_header_0x74_ImportModulesCount dd 0
LE_header_0x78_ImportProcTable dd 0x1B2
LE_header_0x7C_PerPageChecksums dd 0
LE_header_0x80_DataPagesOffset dd 0x400 ;0x1000; 0x400;0x2E0;0x1000 ;inicio de código y datos después de la cabecera
LE_header_0x84_PreloadPageCount dd 1
LE_header_0x88_NonResidentNames dd 0x1434
LE_header_0x8c_NonResidentNamesLen8 dd 15 ;in bytes
LE_header_0x90_NonResidentNamesChk dd 0
LE_header_0x94_AutomaticDataObject dd 0
LE_header_0x98_DebugInformationOff dd 0
LE_header_0x9C_DebugInformationLen dd 0
LE_header_0xA0_PreloadInstPagesNum dd 0
LE_header_0xA4_DemandInstancePgsNum dd 0
LE_header_0xA8_ExtraHeapAllocation dd 0
LE_header_0xAC dd 0
;File Offset 0x160, LE header offset 0xB0
;INIT:
;INIT:
;INIT:
;INIT:
times 16 db 0
dd 0x4000000
dd 0xE8
dd 0
dd 0x2045
dd 1
dd 1
db "LCOD'",0,0,0
dd 0
dd 0x2005
dd 2
dd 1
db "PCOD1",0,0,0
dd 0
dd 0x2023
dd 3
dd 1
db "PDAT"
dd 0x10000
db 0,0,2,0
db 0,0,3,0
db 7
db "MESSAGE"
db 0,0,0,1,3,1,0,3,0,0,0,0,0,0,0,0
db 0,0x60,0,0,0,0x75,0,0,0,0x75,0,0,0,7,0,0xE1
db 0,2,0x20,0,0x27,0,0x1F,1,0x5F,0,0x65,0,0x69,0,0x6D,0
db 0x71,0,0x75,0,0x79,0,0x7D,0,0x81,0,0x85,0,0x89,0,0x8D,0
db 0x91,0,0x95,0,0x99,0,0x9D,0,0xA1,0,0xA5,0,0xA9,0,0xAD,0
db 0xB1,0,0xB5,0,0xB9,0,0xBD,0,0xC1,0,0xC5,0,0xC9,0,0xCD,0
db 0xD1,0,0xD5,0,0xD9,0,0xDD,0,7,0,0x61,0,2,0,0,7
db 0,0x5B,0,1,0x61,0,7,0,0x18,0,1,0x50,0,7,0,0x21
db 0,3,0x1F,0,7,0,0x11,0,3,0,0,7,0,1,0,3
db 15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32
db "MESSAGE_DDB",0,32,0X40,0X31,0
db 32,32,32,"CLASS",0,"'RCODE",0
db 0,0,32,32,32,"PRELOAD DISCARDABLE",0,0
db "CONFORMING",0,0,0,0,0,0,0,0,0,0,0,0
;times 0xD20 db 0
;align 0x1000
align 0x400
;END:
;END:
;END:
;END:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;0x1000 en el archivo tiene .00000000
;de base en HIEW, por qué?
;;
;INIT: Page 0
;INIT: Page 0
;INIT: Page 0
;INIT: Page 0
db 0,0,0,0,0,4,0,0,1,0,0,0,"MESSAGE"
db 32,0,0,0,0x80,0,0,0,0,0,0,0,0
times 16 db 0
dd 0,0,0
db "verPP",0,0,0
db "1vsR2vsR3vsR",0x83,0xE8,7,0x83,0xF8,0x21,0x73,7,-1,0x24,0x85,0,0,0,0,0xF8
db 0xC3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
times 16*7 db 0
db 0,0,0,0,0,0xCC,0xCC,0xCC,0,0,0,0,0,0,0,0
;times 16*17 db 0
%define round(n, r) (((n+(r-1))/r)*r)
align 512
;END: Page 0
;END: Page 0
;END: Page 0
;END: Page 0
;align 512
;_s:
;times (512-_s) db 0
;dd round(_s,512)
;times (512-$$) db 0
;INIT: Page 1
;INIT: Page 1
;INIT: Page 1
;INIT: Page 1
bits 32
mov ecx,0 ;xor ecx,ecx
;xor ecx,ecx
db 0xCD,0x20,3,0,1,0 ;VMMcall Get_Sys_VM_Handle
mov eax,0x30
mov edi,0
xor esi,esi
xor edx,edx
;db 0xCD,0x20,4,0,17,0 ;VxDcall VMCPD.Set_CR0_State ;17 en vez de 0x17, probar valores WORD o DWORD
db 0xCD,0x20,4,0,0x17,0 ;VxDcall SHELL.Message
ret
mov ecx,0
db 0xEB,0xDE ;jmps .5
;times 9 db 0
;times 16*29 db 0
align 512
;END: Page 1
;END: Page 1
;END: Page 1
;END: Page 1
;INIT: Page 2
;INIT: Page 2
;INIT: Page 2
;INIT: Page 2
db "VxD MessageBox",0
db "A VM is created",0
db "A VM is destroyed",0
;db "SEC",0x0B
;db "MESSAGE_DDB",0,0,0
;END: Page 2
;END: Page 2
;END: Page 2
;END: Page 2