github.com/saferwall/pe@v1.5.2/symbol_test.go (about)

     1  // Copyright 2018 Saferwall. All rights reserved.
     2  // Use of this source code is governed by Apache v2 license
     3  // license that can be found in the LICENSE file.
     4  
     5  package pe
     6  
     7  import "testing"
     8  
     9  type TestCOFFSymbol struct {
    10  	errTooManySymbols error
    11  	symbolsCount      int
    12  	symbolIdx         int
    13  	symbol            COFFSymbol
    14  	stringTableOffset uint32
    15  	symbolName        string
    16  	sectionNumberName string
    17  	symbolTypeString  string
    18  }
    19  
    20  var symbolTests = []struct {
    21  	in  string
    22  	out TestCOFFSymbol
    23  }{
    24  	{
    25  		getAbsoluteFilePath("test/liblzo2-2.dll"),
    26  		TestCOFFSymbol{
    27  			errTooManySymbols: nil,
    28  			symbolsCount:      50,
    29  			symbolIdx:         0,
    30  			symbol: COFFSymbol{
    31  				Name:               [8]byte{0, 0, 0, 0, 4, 0, 0, 0},
    32  				Value:              0x2ac,
    33  				SectionNumber:      8,
    34  				Type:               0x0,
    35  				StorageClass:       0x2,
    36  				NumberOfAuxSymbols: 0x0,
    37  			},
    38  			stringTableOffset: 0x35184,
    39  			symbolName:        "__imp_abort",
    40  			sectionNumberName: ".idata",
    41  			symbolTypeString:  "Null",
    42  		},
    43  	},
    44  
    45  	{
    46  		getAbsoluteFilePath(
    47  			"test/0103daa751660333b7ae5f098795df58f07e3031563e042d2eb415bffa71fe7a",
    48  		),
    49  		TestCOFFSymbol{
    50  			errTooManySymbols: nil,
    51  			symbolsCount:      346,
    52  			symbolIdx:         3,
    53  			symbol: COFFSymbol{
    54  				Name:               [8]byte{0, 0, 0, 0, 4, 0, 0, 0},
    55  				Value:              0x2ac,
    56  				SectionNumber:      8,
    57  				Type:               0x0,
    58  				StorageClass:       0x2,
    59  				NumberOfAuxSymbols: 0x0,
    60  			},
    61  			stringTableOffset: 0x1b054,
    62  			symbolName:        "___mingw_CRTStartup",
    63  			sectionNumberName: ".text",
    64  			symbolTypeString:  "",
    65  		},
    66  	},
    67  
    68  	{
    69  		getAbsoluteFilePath(
    70  			"test/0000e876c5b712b6b7b3ce97f757ddd918fb3dbdc5a3938e850716fbd841309f",
    71  		),
    72  		TestCOFFSymbol{
    73  			errTooManySymbols: errCOFFSymbolsTooHigh,
    74  		},
    75  	},
    76  }
    77  
    78  func TestParseCOFFSymbolTable(t *testing.T) {
    79  	for _, tt := range symbolTests {
    80  		t.Run(tt.in, func(t *testing.T) {
    81  			ops := Options{Fast: true}
    82  			file, err := New(tt.in, &ops)
    83  			if err != nil {
    84  				t.Fatalf("New(%s) failed, reason: %v", tt.in, err)
    85  			}
    86  			err = file.Parse()
    87  			if err != nil {
    88  				t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err)
    89  			}
    90  			err = file.ParseCOFFSymbolTable()
    91  			if err != tt.out.errTooManySymbols {
    92  				t.Errorf(
    93  					"errTooManySymbols assertion failed, reason: %v",
    94  					tt.out.errTooManySymbols,
    95  				)
    96  			}
    97  
    98  			// exit early when err is errCOFFSymbolsTooHigh.
    99  			if err == errCOFFSymbolsTooHigh {
   100  				return
   101  			}
   102  
   103  			if len(file.COFF.SymbolTable) != tt.out.symbolsCount {
   104  				t.Errorf(
   105  					"symbolsCount assertion failed, want: %d, got: %d",
   106  					tt.out.symbolsCount,
   107  					len(file.COFF.SymbolTable),
   108  				)
   109  			}
   110  			if file.COFF.StringTableOffset != tt.out.stringTableOffset {
   111  				t.Errorf(
   112  					"stringTableOffset assertion failed, want: %d, got: %d",
   113  					tt.out.stringTableOffset,
   114  					file.COFF.StringTableOffset,
   115  				)
   116  			}
   117  			if !stringInSlice(tt.out.symbolName, file.COFF.StringTable) {
   118  				t.Errorf(
   119  					"symbolName assertion failed, want: %s, got: %v",
   120  					tt.out.symbolName,
   121  					file.COFF.StringTable,
   122  				)
   123  			}
   124  
   125  			coffSymbol := file.COFF.SymbolTable[tt.out.symbolIdx]
   126  			symbolNameStr, err := coffSymbol.String(file)
   127  			if err != nil {
   128  				t.Errorf("COFFSymbol.String() failed with: %v", err)
   129  			}
   130  			if symbolNameStr != tt.out.symbolName {
   131  				t.Errorf(
   132  					"symbol name to string failed, want: %s, got: %s",
   133  					tt.out.symbolName,
   134  					symbolNameStr,
   135  				)
   136  			}
   137  
   138  			secNumName := coffSymbol.SectionNumberName(file)
   139  			if secNumName != tt.out.sectionNumberName {
   140  				t.Errorf(
   141  					"SectionNumberName assertion failed, want: %s, got: %s",
   142  					tt.out.sectionNumberName,
   143  					secNumName,
   144  				)
   145  			}
   146  
   147  			typeString := file.PrettyCOFFTypeRepresentation(coffSymbol.Type)
   148  			if typeString != tt.out.symbolTypeString {
   149  				t.Errorf(
   150  					"PrettyCOFFTypeRepresentation assertion failed, want: %s, got: %s",
   151  					tt.out.symbolTypeString,
   152  					typeString,
   153  				)
   154  			}
   155  		})
   156  	}
   157  }