github.com/saferwall/pe@v1.5.2/resource_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  	"reflect"
     9  	"testing"
    10  )
    11  
    12  type TestRsrcDir struct {
    13  	Level1ImgRsrcDir   ImageResourceDirectory
    14  	Level2Index        int
    15  	Level2ImgRsrcDir   ImageResourceDirectory
    16  	Level3Index        int
    17  	Level3ImgRsrcDir   ImageResourceDirectory
    18  	Level3RsrcDirEntry ResourceDirectoryEntry
    19  	Level4Index        int
    20  	Level4RsrcDirEntry ResourceDirectoryEntry
    21  }
    22  
    23  func TestParseResourceDirectory(t *testing.T) {
    24  
    25  	tests := []struct {
    26  		in  string
    27  		out TestRsrcDir
    28  	}{
    29  		{
    30  			getAbsoluteFilePath("test/putty.exe"),
    31  			TestRsrcDir{
    32  				Level1ImgRsrcDir: ImageResourceDirectory{
    33  					Characteristics:      0x0,
    34  					TimeDateStamp:        0x0,
    35  					MajorVersion:         0x0,
    36  					MinorVersion:         0x0,
    37  					NumberOfNamedEntries: 0x0,
    38  					NumberOfIDEntries:    0x6,
    39  				},
    40  				Level2Index: 0x3,
    41  				Level2ImgRsrcDir: ImageResourceDirectory{
    42  					Characteristics:      0x0,
    43  					TimeDateStamp:        0x0,
    44  					MajorVersion:         0x0,
    45  					MinorVersion:         0x0,
    46  					NumberOfNamedEntries: 0x0,
    47  					NumberOfIDEntries:    0x1,
    48  				},
    49  				Level3Index: 0x0,
    50  				Level3ImgRsrcDir: ImageResourceDirectory{
    51  					Characteristics:      0x0,
    52  					TimeDateStamp:        0x0,
    53  					MajorVersion:         0x0,
    54  					MinorVersion:         0x0,
    55  					NumberOfNamedEntries: 0x0,
    56  					NumberOfIDEntries:    0x1,
    57  				},
    58  				Level4Index: 0x0,
    59  				Level4RsrcDirEntry: ResourceDirectoryEntry{
    60  					Struct: ImageResourceDirectoryEntry{
    61  						Name:         0x409,
    62  						OffsetToData: 0x460,
    63  					},
    64  					Name:          "",
    65  					ID:            0x409,
    66  					IsResourceDir: false,
    67  					Data: ResourceDataEntry{
    68  						Lang:    0x9,
    69  						SubLang: 0x1,
    70  						Struct: ImageResourceDataEntry{
    71  							OffsetToData: 0x124838,
    72  							Size:         0x324,
    73  							CodePage:     0x0,
    74  							Reserved:     0x0,
    75  						},
    76  					},
    77  				},
    78  			},
    79  		},
    80  	}
    81  
    82  	for _, tt := range tests {
    83  		t.Run(tt.in, func(t *testing.T) {
    84  			ops := Options{Fast: true}
    85  			file, err := New(tt.in, &ops)
    86  			if err != nil {
    87  				t.Fatalf("New(%s) failed, reason: %v", tt.in, err)
    88  			}
    89  
    90  			err = file.Parse()
    91  			if err != nil {
    92  				t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err)
    93  			}
    94  
    95  			var va, size uint32
    96  			if file.Is64 {
    97  				oh64 := file.NtHeader.OptionalHeader.(ImageOptionalHeader64)
    98  				dirEntry := oh64.DataDirectory[ImageDirectoryEntryResource]
    99  				va = dirEntry.VirtualAddress
   100  				size = dirEntry.Size
   101  			} else {
   102  				oh32 := file.NtHeader.OptionalHeader.(ImageOptionalHeader32)
   103  				dirEntry := oh32.DataDirectory[ImageDirectoryEntryResource]
   104  				va = dirEntry.VirtualAddress
   105  				size = dirEntry.Size
   106  			}
   107  
   108  			err = file.parseResourceDirectory(va, size)
   109  			if err != nil {
   110  				t.Fatalf("parseResourceDirectory(%s) failed, reason: %v", tt.in, err)
   111  			}
   112  
   113  			rsrc := file.Resources
   114  			if rsrc.Struct != tt.out.Level1ImgRsrcDir {
   115  				t.Fatalf("level 1 resource directory assertion failed, got %v, want %v",
   116  					rsrc.Struct, tt.out.Level1ImgRsrcDir)
   117  			}
   118  
   119  			rsrcDirLevel2 := rsrc.Entries[tt.out.Level2Index].Directory
   120  			if rsrcDirLevel2.Struct != tt.out.Level2ImgRsrcDir {
   121  				t.Fatalf("level 2 resource directory assertion failed, got %v, want %v",
   122  					rsrc.Struct, tt.out.Level2ImgRsrcDir)
   123  			}
   124  
   125  			rsrcDirLevel3 := rsrcDirLevel2.Entries[tt.out.Level3Index].Directory
   126  			if rsrcDirLevel3.Struct != tt.out.Level3ImgRsrcDir {
   127  				t.Fatalf("level 3 resource directory assertion failed, got %v, want %v",
   128  					rsrc.Struct, tt.out.Level3ImgRsrcDir)
   129  			}
   130  
   131  			rsrcDirEntry := rsrcDirLevel3.Entries[tt.out.Level4Index]
   132  			if !reflect.DeepEqual(rsrcDirEntry, tt.out.Level4RsrcDirEntry) {
   133  				t.Fatalf("level 3 resource directory entry assertion failed, got %v, want %v",
   134  					rsrc.Struct, tt.out.Level3ImgRsrcDir)
   135  			}
   136  		})
   137  	}
   138  }
   139  
   140  func TestResourceTypeString(t *testing.T) {
   141  
   142  	tests := []struct {
   143  		in  ResourceType
   144  		out string
   145  	}{
   146  		{
   147  			RTCursor,
   148  			"Cursor",
   149  		},
   150  		{
   151  			ResourceType(0xff),
   152  			"?",
   153  		},
   154  	}
   155  
   156  	for _, tt := range tests {
   157  		t.Run(tt.out, func(t *testing.T) {
   158  
   159  			rsrcTypeString := tt.in.String()
   160  			if rsrcTypeString != tt.out {
   161  				t.Fatalf("resource type string conversion failed, got %v, want %v",
   162  					rsrcTypeString, tt.out)
   163  			}
   164  		})
   165  	}
   166  }
   167  
   168  func TestResourceLangString(t *testing.T) {
   169  
   170  	tests := []struct {
   171  		in  ResourceLang
   172  		out string
   173  	}{
   174  		{
   175  
   176  			LangArabic,
   177  			"Arabic (ar)",
   178  		},
   179  		{
   180  			ResourceLang(0xffff),
   181  			"?",
   182  		},
   183  	}
   184  
   185  	for _, tt := range tests {
   186  		t.Run(tt.out, func(t *testing.T) {
   187  
   188  			rsrcLangString := tt.in.String()
   189  			if rsrcLangString != tt.out {
   190  				t.Fatalf("resource language string conversion failed, got %v, want %v",
   191  					rsrcLangString, tt.out)
   192  			}
   193  		})
   194  	}
   195  }
   196  
   197  func TestResourceSubLangString(t *testing.T) {
   198  
   199  	tests := []struct {
   200  		in  ResourceSubLang
   201  		out string
   202  	}{
   203  		{
   204  
   205  			SubLangArabicMorocco,
   206  			"Arabic Morocco (ar-MA)",
   207  		},
   208  		{
   209  			ResourceSubLang(0xffff),
   210  			"?",
   211  		},
   212  	}
   213  
   214  	for _, tt := range tests {
   215  		t.Run(tt.out, func(t *testing.T) {
   216  
   217  			rsrcSubLangString := tt.in.String()
   218  			if rsrcSubLangString != tt.out {
   219  				t.Fatalf("resource sub-language string conversion failed, got %v, want %v",
   220  					rsrcSubLangString, tt.out)
   221  			}
   222  		})
   223  	}
   224  }
   225  
   226  func TestPrettyResourceLang(t *testing.T) {
   227  
   228  	type resourceLang struct {
   229  		lang    ResourceLang
   230  		subLang int
   231  	}
   232  
   233  	tests := []struct {
   234  		in  resourceLang
   235  		out string
   236  	}{
   237  		{
   238  			resourceLang{
   239  				lang:    LangEnglish,
   240  				subLang: 0x1,
   241  			},
   242  			"English United States (en-US)",
   243  		},
   244  		{
   245  			resourceLang{
   246  				lang:    ResourceLang(0xff),
   247  				subLang: 0x1,
   248  			},
   249  			"?",
   250  		},
   251  	}
   252  
   253  	for _, tt := range tests {
   254  		t.Run(tt.out, func(t *testing.T) {
   255  
   256  			prettyRsrcLang := PrettyResourceLang(tt.in.lang, tt.in.subLang)
   257  			if prettyRsrcLang != tt.out {
   258  				t.Fatalf("pretty resource language failed, got %v, want %v",
   259  					prettyRsrcLang, tt.out)
   260  			}
   261  		})
   262  	}
   263  }