Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

151 lines
4.3 KiB

# Verify the disasembly to make sure
# there are no calls to W API's outside
# wrapper functions. If there are, it's an
# error that breaks the client on win9x
# NadimA
$curfn = "NotAFunction";
$curfnIsWrapper = 0;
$calleeName = "NoCalleeName";
$seenErrors = 0;
#stats
$linesProcessed = 0;
$callsProcessed = 0;
$wideCallsProcessed = 0;
$callExceptions = 0;
$callerExceptions = 0;
#
#
# W fn exception list
# Add W functions here that don't need to be wrapped
# e.g they are available on win95
#
#
%exceptFnList = (
"lstrlenW" => "1",
"GetCommandLineW" => "1"
);
#
# Caller exception list
# there are some fn's in the CRT that make W calls
# based on a platform branch
#
%exceptCallerList = (
"___crtGetEnvironmentStringsA" => "1",
"___crtLCMapStringA" => "1",
"___crtLCMapStringW" => "1",
"___crtGetStringTypeA" => "1",
"___crtGetStringTypeW" => "1",
"SHUnicodeToAnsiNativeCP" => "1",
"SHUnicodeToAnsiCP" => "1"
);
if (@ARGV != 1)
{
print "Usage: perl vrfywrap.pl BINARY.EXE|DLL\n";
print "This verifies binary.exe to make sure there are no unwrapped UNICODE calls\n";
print "You may want to redirect the output to a log file with > LOG\n";
print "Also note that you need to have an x86 link.exe in the path for the disassembly to work";
return 900;
}
$inputBin = shift;
print "Disassembling: " . $inputBin . " ...\n";
$asmFile = $inputBin . ".vfy.asm";
$rc = 0xFFFF & system "link /dump /disasm " . $inputBin . ">" . $asmFile . "\n";
print "Disassemble status: " . $rc ."\n";
if($rc != 0)
{
print "Error disassembling " . $inputBin . ". Is link.exe in the path?\n";
}
print "Verifying disassembly (". $asmFile .") for unwrapped wide calls...\n";
open (ASMFILE, $asmFile) or die "Error can't open disassembly file.\n";
while(<ASMFILE>)
{
$linesProcessed++;
#Parse current function name for context
if(m/(\S*):$/) # old condition:(m/(\S*)@(\S*):$/)
{
$curfn = $1;
if(m/(.*)WrapW@(.*)/)
{
$curfnIsWrapper = 1;
}
else
{
$curfnIsWrapper = 0;
}
next;
}
#Parse disassembly to determine if there is a call
#to a W function
if(m/(.*)(\s*)call(\s*)(.*)dword ptr/)
{
$callsProcessed++;
#This is a call
#figure out if it's a call to W function that is not
#a wrapper call
if(m/(.*)__imp__(\w*)W(@(\w*)|])/)
{
$wideCallsProcessed++;
$calleeName = $2 . "W@" . $3;
#print "call to " . $calleeName . " from " . $curfn . "\n";
if(m/(.*)WrapW@(.*)/)
{
#It's a wrapper call
#print "it's a wrapper call\n";
next;
}
if(0 == $curfnIsWrapper)
{
#
#Check for exceptions to the rules
#
$cleanCalleeFnName = $calleeName;
#Clean out the functionname
$cleanCalleeFnName =~ s/(\W*)(\w*)(.*)/$2/;
if($exceptFnList{$cleanCalleeFnName})
{
#print "Exception fn found: " . $cleanCalleeFnName . " \n";
$callExceptions++;
next;
}
$cleanCallerFnName = $curfn;
#Clean out the functionname
$cleanCallerFnName =~ s/(\W*)(\w*)(.*)/$2/;
if($exceptCallerList{$cleanCallerFnName})
{
#print "Exception fn found: " . $cleanCallerFnName . " \n";
$callerExceptions++;
next;
}
print "Error: call to unwrapped W fn: " . $calleeName . " in fn " . $curfn . "\n";
$seenErrors++;
}
}
}
}
print "Result summary:\n";
print "Lines processed: " . $linesProcessed . "\n";
print "Calls processed: " . $callsProcessed . "\n";
print "Wide calls processed: " . $wideCallsProcessed . "\n";
print "Call exceptions (valid unwrapped wide calls):" . $callExceptions . "\n";
print "Caller exceptions (exempt callers):" . $callerExceptions . "\n";
if ($seenErrors != 0)
{
print $seenErrors . " errors were detected. Please fix them\n";
}
else
{
print "Everything looks OK, no errors detected\n";
}
exit $seenErrors;