Geoff Chappell - Software Analyst
The STUB statement is supported only when building an export file for a VxD. It is otherwise ignored after a warning (LNK4017).
STUB is a single-line statement. It is a fatal error (LNK1118) if the statement is empty. The STUB tag must be followed by at least one space or tab. There may then be any amount of white space, including none, before the definition. The ordinary syntax is:
such that filename is all the text on the remainder of the line (including trailing white space). A variation is:
Here, the first character of the argument is a single-quote, and pathname begins with the next character and continues up to but not including the last single-quote on the remainder of the line. It is a fatal error (LNK1118) if there is not another single-quote on the line. Characters beyond the last single-quote are irrelevant and are ignored without complaint.
The STUB statement translates to a /stub option for the export-file command line. The form is:
where pathname is from the definition, as described above.
The code for generating the /stub switch uses a 128-byte buffer on the stack but does not check the lengths of the strings it copies there. A sufficiently long pathname can therefore induce an overrun and corrupt the stack, including to overwrite the relevant procedure’s return address. In the version studied for these notes, namely 7.00.9466, the procedure has been compiled with the Buffer Security Check enabled and the placement of the buffer is such that even a one-byte overrun is caught.
For a demonstration, prepare a module definition file, here named TEST.DEF, containing just the following as one (long) line:
where the ellipsis stands for as many repetitions of 123456789\ as needed for the text argument to count to 120. With 8 bytes for the characters of the /stub switch, its colon and two double-quotes, the null byte at the end of the string will be one byte too many. Running
lib /def:test.def /machine:x86 /vxd
triggers the buffer overrun. Repeat with pathname reduced by one byte, and there is no buffer overrun.
Note that a pathname with white space need not be enclosed in quotes of either sort when given in the STUB statement. All the white space gets enclosed in double-quotes when carried to the /stub option. This is true even of trailing white space, such as occurs if the pathname without single-quotes is followed by white space and then by a comment. (Remember that by this stage of parsing, LIB treats a comment as having ended the line.)
Enclosure between single-quotes in the STUB statement is supported explicitly and has the merit of marking clearly which characters are intended as the pathname for the /stub option.
Double-quotes in the pathname are problematic. They carry into the pathname for the /stub option in the export file, but the enclosure in double-quotes for the option inverts the pairing of the double-quotes in the definition.