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

  1. # Verify the disasembly to make sure
  2. # there are no calls to W API's outside
  3. # wrapper functions. If there are, it's an
  4. # error that breaks the client on win9x
  5. # NadimA
  6. $curfn = "NotAFunction";
  7. $curfnIsWrapper = 0;
  8. $calleeName = "NoCalleeName";
  9. $seenErrors = 0;
  10. #stats
  11. $linesProcessed = 0;
  12. $callsProcessed = 0;
  13. $wideCallsProcessed = 0;
  14. $callExceptions = 0;
  15. $callerExceptions = 0;
  16. #
  17. #
  18. # W fn exception list
  19. # Add W functions here that don't need to be wrapped
  20. # e.g they are available on win95
  21. #
  22. #
  23. %exceptFnList = (
  24. "lstrlenW" => "1",
  25. "GetCommandLineW" => "1"
  26. );
  27. #
  28. # Caller exception list
  29. # there are some fn's in the CRT that make W calls
  30. # based on a platform branch
  31. #
  32. %exceptCallerList = (
  33. "___crtGetEnvironmentStringsA" => "1",
  34. "___crtLCMapStringA" => "1",
  35. "___crtLCMapStringW" => "1",
  36. "___crtGetStringTypeA" => "1",
  37. "___crtGetStringTypeW" => "1",
  38. "SHUnicodeToAnsiNativeCP" => "1",
  39. "SHUnicodeToAnsiCP" => "1"
  40. );
  41. if (@ARGV != 1)
  42. {
  43. print "Usage: perl vrfywrap.pl BINARY.EXE|DLL\n";
  44. print "This verifies binary.exe to make sure there are no unwrapped UNICODE calls\n";
  45. print "You may want to redirect the output to a log file with > LOG\n";
  46. print "Also note that you need to have an x86 link.exe in the path for the disassembly to work";
  47. return 900;
  48. }
  49. $inputBin = shift;
  50. print "Disassembling: " . $inputBin . " ...\n";
  51. $asmFile = $inputBin . ".vfy.asm";
  52. $rc = 0xFFFF & system "link /dump /disasm " . $inputBin . ">" . $asmFile . "\n";
  53. print "Disassemble status: " . $rc ."\n";
  54. if($rc != 0)
  55. {
  56. print "Error disassembling " . $inputBin . ". Is link.exe in the path?\n";
  57. }
  58. print "Verifying disassembly (". $asmFile .") for unwrapped wide calls...\n";
  59. open (ASMFILE, $asmFile) or die "Error can't open disassembly file.\n";
  60. while(<ASMFILE>)
  61. {
  62. $linesProcessed++;
  63. #Parse current function name for context
  64. if(m/(\S*):$/) # old condition:(m/(\S*)@(\S*):$/)
  65. {
  66. $curfn = $1;
  67. if(m/(.*)WrapW@(.*)/)
  68. {
  69. $curfnIsWrapper = 1;
  70. }
  71. else
  72. {
  73. $curfnIsWrapper = 0;
  74. }
  75. next;
  76. }
  77. #Parse disassembly to determine if there is a call
  78. #to a W function
  79. if(m/(.*)(\s*)call(\s*)(.*)dword ptr/)
  80. {
  81. $callsProcessed++;
  82. #This is a call
  83. #figure out if it's a call to W function that is not
  84. #a wrapper call
  85. if(m/(.*)__imp__(\w*)W(@(\w*)|])/)
  86. {
  87. $wideCallsProcessed++;
  88. $calleeName = $2 . "W@" . $3;
  89. #print "call to " . $calleeName . " from " . $curfn . "\n";
  90. if(m/(.*)WrapW@(.*)/)
  91. {
  92. #It's a wrapper call
  93. #print "it's a wrapper call\n";
  94. next;
  95. }
  96. if(0 == $curfnIsWrapper)
  97. {
  98. #
  99. #Check for exceptions to the rules
  100. #
  101. $cleanCalleeFnName = $calleeName;
  102. #Clean out the functionname
  103. $cleanCalleeFnName =~ s/(\W*)(\w*)(.*)/$2/;
  104. if($exceptFnList{$cleanCalleeFnName})
  105. {
  106. #print "Exception fn found: " . $cleanCalleeFnName . " \n";
  107. $callExceptions++;
  108. next;
  109. }
  110. $cleanCallerFnName = $curfn;
  111. #Clean out the functionname
  112. $cleanCallerFnName =~ s/(\W*)(\w*)(.*)/$2/;
  113. if($exceptCallerList{$cleanCallerFnName})
  114. {
  115. #print "Exception fn found: " . $cleanCallerFnName . " \n";
  116. $callerExceptions++;
  117. next;
  118. }
  119. print "Error: call to unwrapped W fn: " . $calleeName . " in fn " . $curfn . "\n";
  120. $seenErrors++;
  121. }
  122. }
  123. }
  124. }
  125. print "Result summary:\n";
  126. print "Lines processed: " . $linesProcessed . "\n";
  127. print "Calls processed: " . $callsProcessed . "\n";
  128. print "Wide calls processed: " . $wideCallsProcessed . "\n";
  129. print "Call exceptions (valid unwrapped wide calls):" . $callExceptions . "\n";
  130. print "Caller exceptions (exempt callers):" . $callerExceptions . "\n";
  131. if ($seenErrors != 0)
  132. {
  133. print $seenErrors . " errors were detected. Please fix them\n";
  134. }
  135. else
  136. {
  137. print "Everything looks OK, no errors detected\n";
  138. }
  139. exit $seenErrors;