This example introduces the tools required to use Etch from the
command line; we provide a more detailed description of those commands
and their options in Section 3.
Before you can use Etch from the command line, you must
initialize your environment. First, update your path to
include the directory where the Etch executable and runtime DLLs are
kept. Assuming that you have installed Etch in c:\etch, you
would add the bin directory to your path as follows:
X:\> set path=%path%;c:\etch\bin
Next you need to update your path to include the directory where the
Etch tool DLLs are kept:
X:\> set path=%path%;c:\etch\apps\bin
With your path initialized as above, you are now ready to use Etch
from the command line.
X:\> etch -app <basename> -t <toolname> <executable>
where:
X:\> etch -app winword -t countiref winword.exe
Executing this command will produce a new executable,
winword-countiref.exe, in the current directory. This executable is a
version of winword.exe instrumented to count instructions using the
countiref tool. Etch found this tool by looking for
countiref-inst.dll in your path (which you updated to include
the Etch tool directory, as described above).
When run, winword-countiref.exe will produce an output file named
countiref.output in the current directory. This file is the output of
the tool, and will show the number of instructions executed by the
Word application. Try running winword-countiref.exe, and then exit
after Word finishes loading. Then invoke "type countiref.output" to
show the number of instructions Word just executed.
X:\> dllwatch winword.exe
This will run winword in the context of DLLwatch. Exercise Word
in the way that you intend to use it for measurement. When
you exit Word, the DLLwatch tool will generate a file,
dllwatch.output, that shows all of the DLLs loaded by Word.
X:\> etch -app winword -t countiref -wrap Etch etchwrap.dll kernel32.dll -outbase 0x300000 -o winword-etch.exe winword.exe
X:\> etch -app winword -t countiref -wrap Etch etchwrap.dll kernel32.dll -outbase 0x300000 -o gdi32-etch.dll %windir%\system32\gdi32.dll
X:\> etch -app winword -t countiref -wrap Etch etchwrap.dll kernel32.dll -outbase 0x300000 -o pscrptui-etch.dll %windir%\system32\pscrptui.dll
These commands will create three new modules in the current directory,
winword-etch.exe, gdi32-etch.exe, and pscrptui-etch.dll,
respectively.
The command line for etching these modules is rather complex, so we'll
go over the arguments individually and discuss what each of them
do.
X:\> etch -wrap Etch etchwrap.dll kernel32.dll -outbase 0x300000 -o advapi32-patch.dll %windir%\system32\advapi32.dll
X:\> etch -wrap Etch etchwrap.dll kernel32.dll -outbase 0x300000 -o comctl32-patch.dll %windir%\system32\comctl32.dll
X:\> etch -wrap Etch etchwrap.dll kernel32.dll -outbase 0x300000 -o mpr-patch.dll %windir%\system32\mpr32.dll
X:\> etch -wrap Etch etchwrap.dll kernel32.dll -o user32-patch.dll %windir%\system32\user32.dll
X:\> ...
We repeat this step for each of the DLLs that Word uses, both
statically and dynamically, except for kernel32.dll and
ntdll.dll. These two DLLs are special, and should not need to be
patched.
Note: We do not relocate user32.dll using the "-outbase"
argument (see the last command above); the kernel assumes that
user32.dll will be loaded at its predefined load address, so the
application will fail to run if user32.dll is relocated.
X:\> dllwalk -map winword.dmf winword-etch.exe
We repeat the use of dllwalk on every module used by Word. Note,
however, that, as with the patching step, we do not map the imports of
kernel32.dll and ntdll.dll.
X:\> winword-etch.exe
When you exit from Word, the countiref tool will create a file
"countiref.output" that shows the total number of instructions
executed, as well as a breakdown among the etched modules.
Note that it is possible to use invoke Etch on a binary without
applying a tool. For example, it is possible to create a new binary
with a different image base (-outbase), or with some DLL calls
replaced (-wrap), without applying any instrumentation. (In the
current implementation of Etch, any invocation will produce a new
import table and new export table, even if there were no changes
to the import or export information.)
The -t, or -i and -r, flags specify the instrumentation and runtime
DLLs to use in rewriting the binary. When the '-t tool' flag is used,
the instrumentation and runtime DLL names are assumed to be
"tool-inst.dll" and "tool-rt.dll". Etch expects to find the instrumentation
and tool DLLs in the directory specified in the TOOL_ENV environment
variable.
The -app flag specifies a tag to identify the application being
rewritten. The same tag should be specified for the executable
and all the DLLs etched as part of a single application.
(The -app flag can be omitted if instrumentDll does not export
InstrumentProgram.)
will produce hello-cache.exe.
Alternatively, you can use
This is identical to the previous invocation, except that instead
of specifying a toolname, the user explicitly specifies the names
of the two DLLs that make up the tool. If a full path is not
specified Etch will check the current directory as well as the
%ETCHTOOLS% directory.
For example, these two invocations of Etch are equivalent:
The layout is an ASCII file describing the order in which
the output binary should be written. Each line in the file
is a whitespace separated pair of hex numbers representing a
base and limit of PCs in the uninstrumented program to be written.
In addition, the special tokens BEGIN and END can be used
in place of numbers to represent the beginning and end of
the section. (At present code layout is only supported
for programs containing a single esection.)
Note that the range 'x y' represents pcs from [x .. y-1], NOT [x..y].
For example, to interchange two procedures of length 0x100 at
addresses 0x1000 and 0x2000, the following layout file would suffice:
Typically code layout files are generated automatically as part
of the code layout optimization tool.
If the cvdump utility has been used to generate debugging information,
then this flag can be used to specify the name of the file containing
the resulting information.
The cvdump tool is used to extract CodeView debugging information from
a win32 executable or DLL. The user must run cvdump on each component:
once on the .exe file, and once on each DLL that the user plans to
instrument. As with Etch, normally there is no reason to run cvdump from the
command line: Visual Etch has all the machinery to invoke cvdump
correctly.
Each executable or DLL must have been compiled to include the CodeView
debugging information, and the only revision of CodeView debug info
that cvdump understands is NB09. Cvdump will not attempt to extract
debugging information if the revision number is not NB09 or NB11. NB09 can be
generated by Microsoft Visual C++ versions 2.0 and 4.0. The user must
give the /pdb:none option to the Visual C++ linker in order to get
debug information included in the .exe or .dll file, otherwise Visual
C++ puts the debug info into a .pdb file, and cvdump cannot read .pdb
files.
The cvdump tool is invoked by:
After cvdump is run on each component, the outputs from all components
must be combined. The combined outputs must then be
postprocessed by the cvfilter perl script, before the output is given
to Etch, using the -d option. For example, assuming that we had two
components on which we had run cvdump, we would execute the statements:
Note: Some compilers split up procedures into multiple non-contiguous segments.
In this case, cvdump will label the segment containing the procedure entry
point with the procedure name and label other segments with the procedure
name followed by a semicolon ";".
would change all references to SHELL32.DLL
in y.dll to SHELL32-etch.DLL.
dllwalk -map will apply the changes only to the executable or DLL
listed on the command line, not to any any of the DLLs that it
imports.
The DLLwatch utility is used to identify the set of all DLLs
loaded by an application. This set includes implicitly-loaded DLLs
listed in the import tables of the application modules, as well as the
explicitly-loaded DLLs loaded by the application during runtime.
Usage is 1. Introduction
Etch can be used to transform executables in two ways. Normally, the
user starts Visual Etch, specifies various parameters through the
menus provided, and then clicks the Visual Etch "Execute Action"
button to run the experiment. Selecting "Execute Action" causes
Visual Etch and its helper scripts to invoke Etch on the modules selected,
and then to execute the instrumented executable.
As an alternative, you can run
Etch directly at the Windows command line. Invoking Etch
directly in this way requires
that you understand more about the Etch process and the steps
required to instrument an executable and its associated DLLs.
This section describes that Etch command line interface, the steps
required to etch an executable, and the individual tools required to
use the command line interface.2. An Example of Using the Etch Command Line Interface
As a step-by-step example of running Etch directly, we will show you how to etch an
application, MS Word for Windows, using the command line interface.
In this example, we use Etch to instrument the application with
the instruction counting tool, "countiref." We first show how to etch
the winword.exe executable itself, and then show how to etch some of
the DLLs it uses in addition to the executable. 2.1 The Environment
2.2 Instrumenting The Executable
Instrumenting only the executable with Etch is straightforward. You
simply need to tell Etch the base name of the executable, the tool
that you want to use, and the location of the executable. The general
format of the command is:
In our example, the basename is "winword" and the toolname is
"countiref." We will assume that the executable is in the current
directory as "winword.exe"; in this case we would specify the
command:2.3 The Executable and DLLs
Due to the dependencies and interactions among the etched
executable, etched DLLs, and unetched DLLs, etching executables and
their DLLs requires seven steps: (1) determining the complete set of
DLLs used, (2) deciding which DLLs to etch, (3) etching the executable
and chosen DLLs, (4) patching calls to LoadLibrary, (5) patching
import tables, (6) creating an etch.config file, and (7) running the
etched application. We will use Word again as our example application
to illustrate this process; a perl script that performs the steps
below can be found in util\etchscripts\etchword.pl in the Etch source
tree.
winword.exe:winword-etch.exe
gdi32.dll:gdi32-etch.dll
pscrptui.dll:pscrptui-etch.dll
Now that we have this file, we can use dllwalk:
X:\> dllwalk -map winword.dmf gdi32-etch.dll
X:\> dllwalk -map winword.dmf pscrptui-etch.dll
X:\> dllwalk -map winword.dmf advapi32-patch.dll
X:\> dllwalk -map winword.dmf comctl32-patch.dll
X:\> dllwalk -map winword.dmf mpr-etch.dll
X:\> ...
# etched modules
C:\MSOFFICE\WINWORD\WINWORD.EXE->WINWORD-ETCH.EXE
C:\WINNT\SYSTEM32\GDI32.DLL->GDI32-ETCH.DLL
C:\WINNT\SYSTEM32\PSCRPTUI.DLL->PSCRPTUI-ETCH.DLL
# patched modules
C:\WINNT\SYSTEM32\ADVAPI32.DLL->ADVAPI32-PATCH.DLL
C:\WINNT\SYSTEM32\COMCTL32.DLL->COMCTL32-PATCH.DLL
.
.
.
# untouched modules
KERNEL32.DLL
NTDLL.DLL
3. Etch Command Line Tools
Etch is composed of a number of separate programs that can be invoked
from the command line with a variety of command line flags, as demonstrated
in the example above. This section describes those programs, which have
the following functions:
3.1 The Etch Binary-Rewriting Engine (etch)
Etch is the core engine for reading and rewriting a binary. As noted
above, it is easier to let Visual Etch figure it all out for you.
However, for the advanced user, or for the curious, here are the basic
options supported from the Etch command line.
Instrumentation
There are two ways of invoking Etch to apply a specific instrumentation
tool to a module.
An Example
For example,
etch [FLAGS] -i instrumentDll -r runtimeDll target
Miscellaneous Options
Optimization (code layout)
BEGIN 0x1000
0x2000 0x2100
0x1100 0x2000
0x1000 0x1100
0x2100 END
Using debugging information
Files compiled with debugging information (Codeview format) can be
inspected with the -d option.
Generating additional information
Some Etch options let you generate some additional information about the
structure of a program.
Context save protocol
These two flags control how careful Etch is about preserving
state between instructions when inserting calls to the tool runtime.
The default is to not save floating point state, and to assume
that data above the top of the stack is dead.
Code discovery
The flags control the heuristics used during code discovery.
By default, code discovery is aggressive; in practice, this
rarely results in data being misidentified as code. These
options indicate that less aggressive heuristics should be used.
Replacing DLL Calls
This is used internally by Etch to replace calls to
the KERNEL32.DLL functions LoadLibrary
and GetModuleHandle with calls to the Etch runtime library.
Help and version information:
3.2 Extracting Debugging Information (cvdump)
cvdump -p hw.exe > cv.out
type cv1.out cv2.out | perl cvfilter.pl > cv.new
etch -t mytool -d cv.new hw.exe
3.3 Determining Implicitly-Loaded DLLs (dllwalk)
The dllwalk utility is used to identify the set of implicitly loaded
DLLs used by an application or a DLL, and also to modify the import
table of a single DLL to import etched or patched DLLs instead of the
originals.
3.4 Determining All Loaded DLLs (dllwatch)
3.5 Monitoring DLL usage and references to DLLs (monitor)
The monitor utility runs executable-name and reports the DLLs it loads,
as well as any instructions executed in the original (unetched) text
segment of etched modules. In addition to writing some information
to standard output and standard error, it summarizes the resulting
information in the file monitor.log.
monitor executable-name