1 1.1 elric ######################################################################## 2 1.1 elric # 3 1.1 elric # Copyright (c) 2010, Secure Endpoints Inc. 4 1.1 elric # All rights reserved. 5 1.1 elric # 6 1.1 elric # Redistribution and use in source and binary forms, with or without 7 1.1 elric # modification, are permitted provided that the following conditions 8 1.1 elric # are met: 9 1.1 elric # 10 1.1 elric # - Redistributions of source code must retain the above copyright 11 1.1 elric # notice, this list of conditions and the following disclaimer. 12 1.1 elric # 13 1.1 elric # - Redistributions in binary form must reproduce the above copyright 14 1.1 elric # notice, this list of conditions and the following disclaimer in 15 1.1 elric # the documentation and/or other materials provided with the 16 1.1 elric # distribution. 17 1.1 elric # 18 1.1 elric # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 1.1 elric # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 1.1 elric # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 1.1 elric # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 1.1 elric # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 1.1 elric # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 1.1 elric # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 1.1 elric # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 1.1 elric # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 elric # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 1.1 elric # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 elric # POSSIBILITY OF SUCH DAMAGE. 30 1.1 elric # 31 1.1 elric 32 1.1 elric my $show_module_name = 1; 33 1.1 elric my $use_indent = 1; 34 1.1 elric my $strip_leading_underscore = 0; 35 1.1 elric my $always_export = 0; 36 1.1 elric my $module_name = ""; 37 1.1 elric my $local_prefix = "SHIM_"; 38 1.1 elric my %forward_exports = (); 39 1.1 elric my %local_exports = (); 40 1.1 elric 41 1.1 elric sub build_forwarder_target_list($) 42 1.1 elric { 43 1.1 elric $fn = shift; 44 1.1 elric 45 1.1 elric print STDERR "Processing defs from file [$fn]\n"; 46 1.1 elric 47 1.1 elric open(SP, '-|', "dumpbin /exports \"".$fn."\"") or die "Can't open pipe for $fn"; 48 1.1 elric 49 1.1 elric LINE: 50 1.1 elric while (<SP>) { 51 1.1 elric # 112 6F 00071CDC krb5_encrypt_size 52 1.1 elric 53 1.1 elric /^ +([[:digit:]]+)\s+[[:xdigit:]]+\s[[:xdigit:]]{8,}\s+(\S+)(?:| = (\S*))$/ && do { 54 1.1 elric my ($ordinal, $symbol, $in) = ($1, $2, $3); 55 1.1 elric 56 1.1 elric if ($in eq "") { $in = $symbol }; 57 1.1 elric $forward_exports{$symbol} = $in; 58 1.1 elric }; 59 1.1 elric } 60 1.1 elric 61 1.1 elric close SP; 62 1.1 elric } 63 1.1 elric 64 1.1 elric # Dump all symbols for the given dll file that are defined and have 65 1.1 elric # external scope. 66 1.1 elric 67 1.1 elric sub build_def_file($) 68 1.1 elric { 69 1.1 elric $fn = shift; 70 1.1 elric 71 1.1 elric print STDERR "Opening dump of DLL [$fn]\n"; 72 1.1 elric 73 1.1 elric open(SP, '-|', "dumpbin /exports \"".$fn."\"") or die "Can't open pipe for $fn"; 74 1.1 elric 75 1.1 elric LINE: 76 1.1 elric while (<SP>) { 77 1.1 elric # 112 6F 00071CDC krb5_encrypt_size 78 1.1 elric 79 1.1 elric /^ +([[:digit:]]+)\s+[[:xdigit:]]+\s[[:xdigit:]]{8,}\s+(\S+)(?:| = (\S*))$/ && do { 80 1.1 elric my ($ordinal, $symbol, $in) = ($1, $2, $3); 81 1.1 elric 82 1.1 elric if ($strip_leading_underscore && $symbol =~ /_(.*)/) { 83 1.1 elric $symbol = $1; 84 1.1 elric } 85 1.1 elric if (exists $local_exports{$symbol}) { 86 1.1 elric print "\t".$symbol; 87 1.1 elric print " = ".$local_exports{$symbol}; 88 1.1 elric if ($in ne $local_exports{$symbol} and $in ne "") { 89 1.1 elric print STDERR "Incorrect calling convention for local $symbol\n"; 90 1.1 elric print STDERR " ".$in." != ".$local_exports{$symbol}."\n"; 91 1.1 elric } 92 1.1 elric print "\t@".$ordinal."\n"; 93 1.1 elric } elsif (exists $local_exports{$local_prefix.$symbol}) { 94 1.1 elric print "\t".$symbol; 95 1.1 elric print " = ".$local_exports{$local_prefix.$symbol}; 96 1.1 elric print "\t@".$ordinal."\n"; 97 1.1 elric } elsif (exists $forward_exports{$symbol}) { 98 1.1 elric print "\t".$symbol; 99 1.1 elric print " = ".$module_name; 100 1.1 elric if ($in ne $forward_exports{$symbol} and $in ne "") { 101 1.1 elric print STDERR "Incorrect calling convention for $symbol\n"; 102 1.1 elric print STDERR " ".$in." != ".$forward_exports{$symbol}."\n"; 103 1.1 elric } 104 1.1 elric my $texp = $forward_exports{$symbol}; 105 1.1 elric if ($texp =~ /^_([^@]+)$/) { $texp = $1; } 106 1.1 elric print $texp."\t@".$ordinal."\n"; 107 1.1 elric } elsif ($always_export) { 108 1.1 elric print "\t".$symbol." = ".$local_prefix.$symbol; 109 1.1 elric print "\t@".$ordinal."\n"; 110 1.1 elric } else { 111 1.1 elric print STDERR "Symbol not found: $symbol\n"; 112 1.1 elric } 113 1.1 elric }; 114 1.1 elric } 115 1.1 elric 116 1.1 elric close SP; 117 1.1 elric } 118 1.1 elric 119 1.1 elric sub build_local_exports_list($) 120 1.1 elric { 121 1.1 elric $fn = shift; 122 1.1 elric 123 1.1 elric print STDERR "Opening dump of object [$fn]\n"; 124 1.1 elric 125 1.1 elric open(SP, '-|', "dumpbin /symbols \"".$fn."\"") or die "Can't open pipe for $fn"; 126 1.1 elric 127 1.1 elric LINE: 128 1.1 elric while (<SP>) { 129 1.1 elric # 009 00000010 SECT3 notype () External | _remove_error_table@4 130 1.1 elric m/^[[:xdigit:]]{3,}\s[[:xdigit:]]{8,}\s(\w+)\s+\w*\s+(?:\(\)| )\s+(\w+)\s+\|\s+(\S+)$/ && do { 131 1.1 elric my ($section, $visibility, $symbol) = ($1, $2, $3); 132 1.1 elric 133 1.1 elric if ($section ne "UNDEF" && $visibility eq "External") { 134 1.1 elric 135 1.1 elric my $exp_name = $symbol; 136 1.1 elric 137 1.1 elric if ($symbol =~ m/^_(\w+)(?:@.*|)$/) { 138 1.1 elric $exp_name = $1; 139 1.1 elric } 140 1.1 elric 141 1.1 elric if ($symbol =~ m/^_([^@]+)$/) { 142 1.1 elric $symbol = $1; 143 1.1 elric } 144 1.1 elric 145 1.1 elric $local_exports{$exp_name} = $symbol; 146 1.1 elric } 147 1.1 elric }; 148 1.1 elric } 149 1.1 elric 150 1.1 elric close SP; 151 1.1 elric } 152 1.1 elric 153 1.1 elric sub process_file($) 154 1.1 elric { 155 1.1 elric $fn = shift; 156 1.1 elric 157 1.1 elric if ($fn =~ m/\.dll$/i) { 158 1.1 elric build_def_file($fn); 159 1.1 elric } elsif ($fn =~ m/\.obj$/i) { 160 1.1 elric build_local_exports_list($fn); 161 1.1 elric } else { 162 1.1 elric die "File type not recognized for $fn."; 163 1.1 elric } 164 1.1 elric } 165 1.1 elric 166 1.1 elric sub use_response_file($) 167 1.1 elric { 168 1.1 elric $fn = shift; 169 1.1 elric 170 1.1 elric open (RF, '<', $fn) or die "Can't open response file $fn"; 171 1.1 elric 172 1.1 elric while (<RF>) { 173 1.1 elric /^(\S+)$/ && do { 174 1.1 elric process_file($1); 175 1.1 elric } 176 1.1 elric } 177 1.1 elric close RF; 178 1.1 elric } 179 1.1 elric 180 1.1 elric print "; This is a generated file. Do not modify directly.\n"; 181 1.1 elric print "EXPORTS\n"; 182 1.1 elric 183 1.1 elric for (@ARGV) { 184 1.1 elric ARG: { 185 1.1 elric /^-m(.*)$/ && do { 186 1.1 elric $module_name = $1."."; 187 1.1 elric last ARG; 188 1.1 elric }; 189 1.1 elric 190 1.1 elric /^-l(.*)$/ && do { 191 1.1 elric $local_prefix = $1."_"; 192 1.1 elric last ARG; 193 1.1 elric }; 194 1.1 elric 195 1.1 elric /^-a$/ && do { 196 1.1 elric $always_export = 1; 197 1.1 elric last ARG; 198 1.1 elric }; 199 1.1 elric 200 1.1 elric /^-e(.*)$/ && do { 201 1.1 elric build_forwarder_target_list($1); 202 1.1 elric last ARG; 203 1.1 elric }; 204 1.1 elric 205 1.1 elric /^@(.*)$/ && do { 206 1.1 elric use_response_file($1); 207 1.1 elric last ARG; 208 1.1 elric }; 209 1.1 elric 210 1.1 elric process_file($_); 211 1.1 elric } 212 1.1 elric } 213