Alternate Data Streams
Start the command prompt of the
Windows™ SDK
in an arbitrary, preferable empty directory, then create an (empty)
file or subdirectory, for example streams, there:
IF DEFINED STREAMS (MKDIR streams) ELSE (COPY NUL: streams)
1 file(s) copied.
Write the hexadecimal dump of a 16-bit DOS program that
prints its copyright message on standard output to an
alternate data stream,
for example .txt, of the file or subdirectory created
in step 1.:
IF EXIST streams @( ECHO 4d 5a 90 00 01 00 00 00 04 00 00 00 ff ff 00 00 e0 00 00 00 43 00 00 00 ECHO 40 00 00 00 00 00 00 00 00 00 00 00 19 57 04 27 00 00 00 00 00 00 00 00 ECHO 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 28 43 29 6f 70 79 72 69 ECHO 67 68 74 20 32 30 30 34 2d 32 30 32 36 2c 20 53 74 65 66 61 6e 20 4b 61 ECHO 6e 74 68 61 6b 20 3c 73 74 65 66 61 6e 2e 6b 61 6e 74 68 61 6b 40 6e 65 ECHO 78 67 6f 2e 64 65 3e 0d 0a 07 24 0e 1f 33 d2 b4 09 cd 21 b8 01 4c cd 21) 1>streams:.txtNote: the MSKB article 65122 documents the
IMAGE_DOS_HEADER structure contained in
the first 64 bytes; it is followed by the 67
ASCII
characters
(C)opyright 2004-2026, Stefan Kanthak <stefan.kanthak@nexgo.de>\r\n\a$
and the real modemachine code.
Note: the command lines can be copied and pasted as block into a Command Processor window.
; Copyright © 2004-2026, Stefan Kanthak <stefan.kanthak@nexgo.de>
.model tiny
e_header struct ; DOS .EXE header
e_magic word 5A4Dh ; magic number "MZ"
e_cblp word stop - header ; bytes on last page of file
e_cp word 1 ; pages in file
e_crlc word 0 ; number of relocation table entries
e_cparhdr word sizeof header / 16 ; size of header in paragraphs
e_minalloc word 0 ; minimum extra paragraphs needed
e_maxalloc word 65535 ; maximum extra paragraphs needed
e_ss word 0 ; initial (PSP relative) SS value
e_sp word stack - header ; initial (SS relative) SP value
e_csum word 0 ; checksum
e_ip word sizeof message ; initial (CS relative) IP value
e_cs word 0 ; initial (PSP relative) CS value
e_lfarlc word sizeof header ; file offset of relocation table
e_ovno word 0 ; overlay number
e_res word 4 dup (0) ; reserved words
e_oemid word 5719h ; OEM identifier
e_oeminfo word 2704h ; OEM information
e_res2 word 10 dup (0) ; reserved words
e_lfanew dword 0 ; file offset of new exe header
e_header ends
.code
header e_header <>
message byte "(C)opyright 2004-2026, Stefan Kanthak <stefan.kanthak@nexgo.de>", 0Dh, 0Ah, 07h, 24h
start:
push cs
pop ds
xor dx, dx
mov ah, 09h
int 21h
mov ax, 4C01h
int 21h
stop:
dword 20 dup (?)
stack:
end start
Decode the 16-bit DOS program to another
alternate data stream,
for example .dos, of the file or subdirectory created
in step 1.:
CERTUTIL.EXE /DecodeHex streams:.txt streams:.dos
Input Length = 438 Output Length = 144 CertUtil: -decodehex command completed successfully.
Execute the 16-bit DOS program created in step 3.:
.\streams:.dos
The syntax of the command is incorrect.
Oops¹: except for input and output
redirection,
and except for its internal
Dir
and
Mklink
commands, the Command Processor
Cmd.exe
fails to support
alternate data streams!
Write a
JScript
that prints its pathname on standard output to the
alternate data stream
.js of the file or subdirectory created in
step 1. and execute it with the
Windows Script Host
console application:
1>streams:.js ECHO WScript.Echo(WScript.ScriptFullName) CSCRIPT.EXE streams:.js
Microsoft (R) Windows Script Host, Version 5.8 Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. C:\Users\Stefan\Desktop\streams:.js
Write a
VBScript
that executes the 16-bit DOS program decoded in
step 3. and prints its standard output to the
alternate data stream
.vbs of the file or subdirectory created in
step 1. and execute it with the
Windows Script Host
console application:
1>streams:.vbs ECHO WScript.Echo WScript.CreateObject("WScript.Shell").Exec("%CD%\streams:.dos").StdOut.ReadAll()
CSCRIPT.EXE streams:.vbs
32-bit editions of Windows execute the 16-bit
DOS program:
Microsoft (R) Windows Script Host, Version 5.8 Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. (C)opyright 2004-2026, Stefan Kanthak <stefan.kanthak@nexgo.de>
64-bit editions of Windows don’t support 16-bit
DOS programs and display the message box shown to the
right:
C:\Users\Stefan\Desktop\streams:.vbs(1, 1) WshShell.Exec: This version of C:\Users\Stefan\Desktop\streams:.dos is not compatible with the version of Windows you're running. Check your computer's system information to see whether you need an x86 (32-bit) or x64 (64-bit) version of the program, and then contact the software publisher.
Write an
ANSI C
source code to the
alternate data stream
.c of the file or subdirectory created in step 1.:
1>streams:.c ECHO unsigned _DllMainCRTStartup(void *module, unsigned reason, void *context) { return 0; }
Compile and link the source code from the
alternate data stream
.c written in step 7.:
SET CL=/Fa /Gz /LD /W4 /Zl SET LINK=/MANIFEST /MAP /NODEFAULTLIB /STUB:streams:.dos CL.EXE streams:.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. streams:.c Microsoft (R) Incremental Linker Version 10.00.40219.386 Copyright (C) Microsoft Corporation. All rights reserved. /MANIFEST /MAP /NODEFAULTLIB /STUB:streams:.dos /out:streams:.dll /dll /implib:streams:.lib streams:.objNote: the Visual C compiler writes its output to one or more alternate data streams of the file or subdirectory from which it reads the alternate data stream with the (first) source, then the linker reads object file and DOS stub from and writes its output to one or more alternate data streams of the same file or subdirectory.
List the alternate data streams of the (still empty) file or subdirectory created in step 1.:
DIR /R streams
Volume in drive C has no label.
Volume Serial Number is 1957-0427
Directory of C:\Users\Stefan\Desktop
04/27/2012 08:15 PM 0 streams
619 streams:.asm:$DATA
89 streams:.c:$DATA
1.024 streams:.dll:$DATA
381 streams:.dll.manifest:$DATA
144 streams:.dos:$DATA
38 streams:.js:$DATA
577 streams:.map:$DATA
469 streams:.obj:$DATA
438 streams:.txt:$DATA
114 streams:.vbs:$DATA
1 File(s) 0 bytes
0 Dir(s) 9,876,543,210 bytes free
Execute the DLL built in step 8. via the Microsoft(C) Register Server application:
REGSVR32.EXE "%CD%\streams:.dll"
Note: the error message box is expected – the
_DllMainCRTStartup()
function intentionally returns 0 alias FALSE to let the
Win32 functions
LoadLibrary()
and
LoadLibraryEx()
fail with Win32 error code 1114 alias
ERROR_DLL_INIT_FAILED.
The MSKB article 249873 provides details.
Execute the DLL built in step 8. via the Windows host process (Rundll32) application:
RUNDLL32.EXE "%CD%\streams:.dll",#0Rundll32
Note: the error message box is expected – the
_DllMainCRTStartup()
function intentionally returns 0 alias FALSE to let the
Win32 functions
LoadLibrary()
and
LoadLibraryEx()
fail with Win32 error code 1114 alias
ERROR_DLL_INIT_FAILED.
Write another
ANSI C
source code to the
alternate data stream
.c of the file or subdirectory created in step 1.:
1>streams:.c ECHO unsigned mainCRTStartup(void) { return 'NTFS'; }
Compile and link the source code from the
alternate data stream
.c overwritten in step 11.:
SET CL=/Gd /W4 /Zl SET LINK=/ENTRY:mainCRTStartup /NODEFAULTLIB /STUB:streams:.dos /SUBSYSTEM:CONSOLE CL.EXE streams:.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
streams:.c
Microsoft (R) Incremental Linker Version 10.00.40219.386
Copyright (C) Microsoft Corporation. All rights reserved.
/ENTRY:mainCRTStartup /NODEFAULTLIB /STUB:streams:.dos /SUBSYSTEM:CONSOLE
/out:streams:.exe
streams:.obj
Write a
VBScript
that executes the Win32 console application built in
step 12. and prints its exit code to the
alternate data stream
.vbs of the file or subdirectory created in
step 1. and execute it with the
Windows Script Host
console application:
IF EXIST streams @(
ECHO With WScript.CreateObject("WScript.Shell"^).Exec("%CD%\streams:.exe"^)
ECHO Do
ECHO WScript.Sleep(99^)
ECHO Loop Until .Status = 1
ECHO WScript.Echo Hex(.ExitCode^)
ECHO End With) 1>streams:.vbs
CSCRIPT.EXE streams:.vbs
Microsoft (R) Windows Script Host, Version 5.8 Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. 4E544653
Write an intentionally invalid external
manifest
for the Win32 console application built in
step 12. to the
alternate data stream
.exe.manifest of the file or subdirectory created in
step 1.:
1>streams:.exe.manifest ECHO ^<?xml version='1.0' encoding='US-ASCII' standalone='yes' ?^>
Execute the Win32 console application built in step 12. via the VBScript overwritten in step 13. again:
CSCRIPT.EXE streams:.vbs
Microsoft (R) Windows Script Host, Version 5.8
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
C:\Users\Stefan\Desktop\streams:.vbs(1, 1) WshShell.Exec: The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
Oops²: Windows’ module loader
honors external
manifests
for executable image files stored in
alternate data streams!
Write another external
manifest
for the Win32 console application built in
step 12. to the
alternate data stream
.exe.manifest of the file or subdirectory created in
step 1.:
IF EXIST streams @( ECHO ^<?xml version='1.0' encoding='UTF-8' standalone='yes' ?^> ECHO ^<assembly manifestVersion='1.0' xmlns='urn:schemas-microsoft-com:asm.v1'^> ECHO ^<file loadFrom='%CD%\streams:.dll' name='kernel32.dll' /^> ECHO ^</assembly^>) 1>streams:.exe.manifest
Execute the Win32 console application built in step 12. via the VBScript overwritten in step 13. once more:
CSCRIPT.EXE streams:.vbs
Microsoft (R) Windows Script Host, Version 5.8 Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. C0000139OUCH: Windows’ module loader displays the error message box for
NTSTATUS
0xC000007A
alias STATUS_PROCEDURE_NOT_FOUND shown to the right
– it loads multiple unreferenced
DLLs
with the Win32 console application built
without dependencies in step 12. and fails
with
NTSTATUS
0xC0000139
alias STATUS_ENTRYPOINT_NOT_FOUND since the (external)
manifest
overwritten in step 16. redirects
kernel32.dll
kernelbase.dll
advapi32.dll
msvcrt.dll
sechost.dll
rpcrt4.dll
sspicli.dll
cryptbase.dll
to the
alternate data stream
that contains the
DLL
built in step 8. without
exports
and imports!
Write yet another
ANSI C
source code to the
alternate data stream
.c of the file or subdirectory created in step 1.:
1>streams:.c ECHO void wWinMainCRTStartup(void) { ExitProcess(MessageBox(HWND_DESKTOP, GetCommandLine(), __LPREFIX(__FUNCTION__), MB_OK) ? ERROR_SUCCESS : GetLastError()); }
Compile and link the source code from the
alternate data stream
.c overwritten in step 18.:
SET CL=/DSTRICT /DUNICODE /DWIN32_LEAN_AND_MEAN /FIwindows.h /Gd /W4 /we4013 /Zl SET LINK=/ENTRY:wWinMainCRTStartup /FIXED /MANIFEST /NODEFAULTLIB /STUB:streams:.dos /SUBSYSTEM:WINDOWS CL.EXE streams:.c kernel32.lib user32.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. streams:.c Microsoft (R) Incremental Linker Version 10.00.40219.386 Copyright (C) Microsoft Corporation. All rights reserved. /ENTRY:wWinMainCRTStartup /FIXED /MANIFEST /NODEFAULTLIB /STUB:streams:.dos /SUBSYSTEM:WINDOWS /out:streams:.exe kernel32.lib user32.lib streams:.obj
Execute the Windows application built in step 19. via the WMI Commandline Utility console application:
WMIC.EXE PROCESS CALL CREATE "%CD%\streams:.exe"
Executing (Win32_Process)->Create()
Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
ProcessId = 9876;
ReturnValue = 0;
};
Execute the Windows application built in step 19. via the BITS administration utility console application:
BITSAdmin.exe /Create streams BITSAdmin.exe /AddFile "%CD%\streams" "%CD%\streams.tmp" BITSAdmin.exe /SetNotifyCmdLine streams "%CD%\streams:.exe" NULL BITSAdmin.exe /Resume streams BITSAdmin.exe /Complete streams
BITSADMIN version 3.0 [ 7.5.7601 ]
BITS administration utility.
(C) Copyright 2000-2006 Microsoft Corp.
BITSAdmin is deprecated and is not guaranteed to be available in future versions of Windows.
Administrative tools for the BITS service are now provided by BITS PowerShell cmdlets.
Created job {539A68AF-34AE-446F-B503-3C2158CE9B49}.
BITSADMIN version 3.0 [ 7.5.7601 ]
BITS administration utility.
(C) Copyright 2000-2006 Microsoft Corp.
BITSAdmin is deprecated and is not guaranteed to be available in future versions of Windows.
Administrative tools for the BITS service are now provided by BITS PowerShell cmdlets.
Added C:\Users\Stefan\Desktop\streams -> C:\Users\Stefan\Desktop\streams.tmp to job.
BITSADMIN version 3.0 [ 7.5.7601 ]
BITS administration utility.
(C) Copyright 2000-2006 Microsoft Corp.
BITSAdmin is deprecated and is not guaranteed to be available in future versions of Windows.
Administrative tools for the BITS service are now provided by BITS PowerShell cmdlets.
notification command line set to 'C:\Users\Stefan\Desktop\streams:.exe' 'NULL'.
BITSADMIN version 3.0 [ 7.5.7601 ]
BITS administration utility.
(C) Copyright 2000-2006 Microsoft Corp.
BITSAdmin is deprecated and is not guaranteed to be available in future versions of Windows.
Administrative tools for the BITS service are now provided by BITS PowerShell cmdlets.
Job resumed.
BITSADMIN version 3.0 [ 7.5.7601 ]
BITS administration utility.
(C) Copyright 2000-2006 Microsoft Corp.
BITSAdmin is deprecated and is not guaranteed to be available in future versions of Windows.
Administrative tools for the BITS service are now provided by BITS PowerShell cmdlets.
Job completed.
Use the X.509 certificate to send S/MIME encrypted mail.
Note: email in weird format and without a proper sender name is likely to be discarded!
I dislike
HTML (and even
weirder formats too) in email, I prefer to receive plain text.
I also expect to see your full (real) name as sender, not your
nickname.
I abhor top posts and expect inline quotes in replies.
as iswithout any warranty, neither express nor implied.
cookiesin the web browser.
The web service is operated and provided by
Telekom Deutschland GmbH The web service provider stores a session cookie
in the web
browser and records every visit of this web site with the following
data in an access log on their server(s):