github.com/saferwall/pe@v1.5.2/reloc_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 (
     8  	"testing"
     9  )
    10  
    11  func TestParseRelocDirectoryData(t *testing.T) {
    12  
    13  	type TestRelocData struct {
    14  		imgBaseRelocation ImageBaseRelocation
    15  		relocEntriesCount int
    16  		relocDataIndex    int
    17  	}
    18  
    19  	tests := []struct {
    20  		in  string
    21  		out TestRelocData
    22  	}{
    23  		{
    24  			getAbsoluteFilePath("test/putty.exe"),
    25  			TestRelocData{
    26  				imgBaseRelocation: ImageBaseRelocation{
    27  					VirtualAddress: 0xd8000, SizeOfBlock: 0xc},
    28  				relocEntriesCount: 18,
    29  				relocDataIndex:    17,
    30  			},
    31  		},
    32  	}
    33  
    34  	for _, tt := range tests {
    35  		t.Run(tt.in, func(t *testing.T) {
    36  			ops := Options{Fast: true}
    37  			file, err := New(tt.in, &ops)
    38  			if err != nil {
    39  				t.Fatalf("New(%s) failed, reason: %v", tt.in, err)
    40  			}
    41  
    42  			err = file.Parse()
    43  			if err != nil {
    44  				t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err)
    45  			}
    46  
    47  			var va, size uint32
    48  			switch file.Is64 {
    49  			case true:
    50  				oh64 := file.NtHeader.OptionalHeader.(ImageOptionalHeader64)
    51  				dirEntry := oh64.DataDirectory[ImageDirectoryEntryBaseReloc]
    52  				va = dirEntry.VirtualAddress
    53  				size = dirEntry.Size
    54  			case false:
    55  				oh32 := file.NtHeader.OptionalHeader.(ImageOptionalHeader32)
    56  				dirEntry := oh32.DataDirectory[ImageDirectoryEntryBaseReloc]
    57  				va = dirEntry.VirtualAddress
    58  				size = dirEntry.Size
    59  			}
    60  
    61  			err = file.parseRelocDirectory(va, size)
    62  			if err != nil {
    63  				t.Fatalf("parseRelocDirectory(%s) failed, reason: %v", tt.in, err)
    64  			}
    65  			relocs := file.Relocations
    66  			if len(relocs) != tt.out.relocEntriesCount {
    67  				t.Errorf("relocations entries count assertion failed, got %v, want %v",
    68  					len(relocs), tt.out.relocEntriesCount)
    69  			}
    70  
    71  			imgBaseRelocation := relocs[tt.out.relocDataIndex].Data
    72  			if imgBaseRelocation != tt.out.imgBaseRelocation {
    73  				t.Errorf("reloc data assertion failed, got %v, want %v",
    74  					imgBaseRelocation, tt.out.imgBaseRelocation)
    75  			}
    76  		})
    77  	}
    78  }
    79  
    80  func TestParseRelocDirectoryEntry(t *testing.T) {
    81  
    82  	type TestRelocEntry struct {
    83  		imgBaseRelocationEntry ImageBaseRelocationEntry
    84  		relocEntriesCount      int
    85  		relocDataIndex         int
    86  		relocEntryIndex        int
    87  		relocTypeMeaning       string
    88  	}
    89  
    90  	tests := []struct {
    91  		in  string
    92  		out TestRelocEntry
    93  	}{
    94  		{
    95  			getAbsoluteFilePath("test/putty.exe"),
    96  			TestRelocEntry{
    97  				imgBaseRelocationEntry: ImageBaseRelocationEntry{
    98  					Data:   0xab00,
    99  					Offset: 0xb00,
   100  					Type:   0xa,
   101  				},
   102  				relocDataIndex:    0x1,
   103  				relocEntriesCount: 154,
   104  				relocEntryIndex:   17,
   105  				relocTypeMeaning:  "DIR64",
   106  			},
   107  		},
   108  		{
   109  			getAbsoluteFilePath("test/arp.dll"),
   110  			TestRelocEntry{
   111  				imgBaseRelocationEntry: ImageBaseRelocationEntry{
   112  					Data:   0x8004,
   113  					Offset: 0x4,
   114  					Type:   0x8,
   115  				},
   116  				relocDataIndex:    3,
   117  				relocEntriesCount: 204,
   118  				relocEntryIndex:   1,
   119  				relocTypeMeaning:  "RISC-V Low12s",
   120  			},
   121  		},
   122  	}
   123  
   124  	for _, tt := range tests {
   125  		t.Run(tt.in, func(t *testing.T) {
   126  			ops := Options{Fast: true}
   127  			file, err := New(tt.in, &ops)
   128  			if err != nil {
   129  				t.Fatalf("New(%s) failed, reason: %v", tt.in, err)
   130  			}
   131  
   132  			err = file.Parse()
   133  			if err != nil {
   134  				t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err)
   135  			}
   136  
   137  			var va, size uint32
   138  			switch file.Is64 {
   139  			case true:
   140  				oh64 := file.NtHeader.OptionalHeader.(ImageOptionalHeader64)
   141  				dirEntry := oh64.DataDirectory[ImageDirectoryEntryBaseReloc]
   142  				va = dirEntry.VirtualAddress
   143  				size = dirEntry.Size
   144  			case false:
   145  				oh32 := file.NtHeader.OptionalHeader.(ImageOptionalHeader32)
   146  				dirEntry := oh32.DataDirectory[ImageDirectoryEntryBaseReloc]
   147  				va = dirEntry.VirtualAddress
   148  				size = dirEntry.Size
   149  			}
   150  
   151  			err = file.parseRelocDirectory(va, size)
   152  			if err != nil {
   153  				t.Fatalf("parseRelocDirectory(%s) failed, reason: %v", tt.in, err)
   154  			}
   155  
   156  			reloc := file.Relocations[tt.out.relocDataIndex]
   157  			if len(reloc.Entries) != tt.out.relocEntriesCount {
   158  				t.Errorf("relocations entries count assertion failed, got %v, want %v",
   159  					len(reloc.Entries), tt.out.relocEntriesCount)
   160  			}
   161  
   162  			relocEntry := reloc.Entries[tt.out.relocEntryIndex]
   163  			if relocEntry != tt.out.imgBaseRelocationEntry {
   164  				t.Errorf("reloc image base relocation entry assertion failed, got %v, want %v",
   165  					relocEntry, tt.out.imgBaseRelocationEntry)
   166  			}
   167  
   168  			relocType := relocEntry.Type.String(file)
   169  			if relocType != tt.out.relocTypeMeaning {
   170  				t.Errorf("pretty reloc type assertion failed, got %v, want %v", relocType,
   171  					tt.out.relocTypeMeaning)
   172  			}
   173  
   174  		})
   175  	}
   176  }