Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
file_test.go738 linesDownload Raw Back to pe
1// Copyright 2009 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4 5package pe6 7import (8	"bytes"9	"debug/dwarf"10	"internal/testenv"11	"os"12	"os/exec"13	"path/filepath"14	"reflect"15	"regexp"16	"runtime"17	"strconv"18	"testing"19	"text/template"20)21 22type fileTest struct {23	file           string24	hdr            FileHeader25	opthdr         any26	sections       []*SectionHeader27	symbols        []*Symbol28	hasNoDwarfInfo bool29}30 31var fileTests = []fileTest{32	{33		file: "testdata/gcc-386-mingw-obj",34		hdr:  FileHeader{0x014c, 0x000c, 0x0, 0x64a, 0x1e, 0x0, 0x104},35		sections: []*SectionHeader{36			{".text", 0, 0, 36, 500, 1440, 0, 3, 0, 0x60300020},37			{".data", 0, 0, 0, 0, 0, 0, 0, 0, 3224371264},38			{".bss", 0, 0, 0, 0, 0, 0, 0, 0, 3224371328},39			{".debug_abbrev", 0, 0, 137, 536, 0, 0, 0, 0, 0x42100000},40			{".debug_info", 0, 0, 418, 673, 1470, 0, 7, 0, 1108344832},41			{".debug_line", 0, 0, 128, 1091, 1540, 0, 1, 0, 1108344832},42			{".rdata", 0, 0, 16, 1219, 0, 0, 0, 0, 1076887616},43			{".debug_frame", 0, 0, 52, 1235, 1550, 0, 2, 0, 1110441984},44			{".debug_loc", 0, 0, 56, 1287, 0, 0, 0, 0, 1108344832},45			{".debug_pubnames", 0, 0, 27, 1343, 1570, 0, 1, 0, 1108344832},46			{".debug_pubtypes", 0, 0, 38, 1370, 1580, 0, 1, 0, 1108344832},47			{".debug_aranges", 0, 0, 32, 1408, 1590, 0, 2, 0, 1108344832},48		},49		symbols: []*Symbol{50			{".file", 0x0, -2, 0x0, 0x67},51			{"_main", 0x0, 1, 0x20, 0x2},52			{".text", 0x0, 1, 0x0, 0x3},53			{".data", 0x0, 2, 0x0, 0x3},54			{".bss", 0x0, 3, 0x0, 0x3},55			{".debug_abbrev", 0x0, 4, 0x0, 0x3},56			{".debug_info", 0x0, 5, 0x0, 0x3},57			{".debug_line", 0x0, 6, 0x0, 0x3},58			{".rdata", 0x0, 7, 0x0, 0x3},59			{".debug_frame", 0x0, 8, 0x0, 0x3},60			{".debug_loc", 0x0, 9, 0x0, 0x3},61			{".debug_pubnames", 0x0, 10, 0x0, 0x3},62			{".debug_pubtypes", 0x0, 11, 0x0, 0x3},63			{".debug_aranges", 0x0, 12, 0x0, 0x3},64			{"___main", 0x0, 0, 0x20, 0x2},65			{"_puts", 0x0, 0, 0x20, 0x2},66		},67	},68	{69		file: "testdata/gcc-386-mingw-exec",70		hdr:  FileHeader{0x014c, 0x000f, 0x4c6a1b60, 0x3c00, 0x282, 0xe0, 0x107},71		opthdr: &OptionalHeader32{72			0x10b, 0x2, 0x38, 0xe00, 0x1a00, 0x200, 0x1160, 0x1000, 0x2000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x10000, 0x400, 0x14abb, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,73			[16]DataDirectory{74				{0x0, 0x0},75				{0x5000, 0x3c8},76				{0x0, 0x0},77				{0x0, 0x0},78				{0x0, 0x0},79				{0x0, 0x0},80				{0x0, 0x0},81				{0x0, 0x0},82				{0x0, 0x0},83				{0x7000, 0x18},84				{0x0, 0x0},85				{0x0, 0x0},86				{0x0, 0x0},87				{0x0, 0x0},88				{0x0, 0x0},89				{0x0, 0x0},90			},91		},92		sections: []*SectionHeader{93			{".text", 0xcd8, 0x1000, 0xe00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500060},94			{".data", 0x10, 0x2000, 0x200, 0x1200, 0x0, 0x0, 0x0, 0x0, 0xc0300040},95			{".rdata", 0x120, 0x3000, 0x200, 0x1400, 0x0, 0x0, 0x0, 0x0, 0x40300040},96			{".bss", 0xdc, 0x4000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0400080},97			{".idata", 0x3c8, 0x5000, 0x400, 0x1600, 0x0, 0x0, 0x0, 0x0, 0xc0300040},98			{".CRT", 0x18, 0x6000, 0x200, 0x1a00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},99			{".tls", 0x20, 0x7000, 0x200, 0x1c00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},100			{".debug_aranges", 0x20, 0x8000, 0x200, 0x1e00, 0x0, 0x0, 0x0, 0x0, 0x42100000},101			{".debug_pubnames", 0x51, 0x9000, 0x200, 0x2000, 0x0, 0x0, 0x0, 0x0, 0x42100000},102			{".debug_pubtypes", 0x91, 0xa000, 0x200, 0x2200, 0x0, 0x0, 0x0, 0x0, 0x42100000},103			{".debug_info", 0xe22, 0xb000, 0x1000, 0x2400, 0x0, 0x0, 0x0, 0x0, 0x42100000},104			{".debug_abbrev", 0x157, 0xc000, 0x200, 0x3400, 0x0, 0x0, 0x0, 0x0, 0x42100000},105			{".debug_line", 0x144, 0xd000, 0x200, 0x3600, 0x0, 0x0, 0x0, 0x0, 0x42100000},106			{".debug_frame", 0x34, 0xe000, 0x200, 0x3800, 0x0, 0x0, 0x0, 0x0, 0x42300000},107			{".debug_loc", 0x38, 0xf000, 0x200, 0x3a00, 0x0, 0x0, 0x0, 0x0, 0x42100000},108		},109	},110	{111		file: "testdata/gcc-386-mingw-no-symbols-exec",112		hdr:  FileHeader{0x14c, 0x8, 0x69676572, 0x0, 0x0, 0xe0, 0x30f},113		opthdr: &OptionalHeader32{0x10b, 0x2, 0x18, 0xe00, 0x1e00, 0x200, 0x1280, 0x1000, 0x2000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x9000, 0x400, 0x5306, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,114			[16]DataDirectory{115				{0x0, 0x0},116				{0x6000, 0x378},117				{0x0, 0x0},118				{0x0, 0x0},119				{0x0, 0x0},120				{0x0, 0x0},121				{0x0, 0x0},122				{0x0, 0x0},123				{0x0, 0x0},124				{0x8004, 0x18},125				{0x0, 0x0},126				{0x0, 0x0},127				{0x60b8, 0x7c},128				{0x0, 0x0},129				{0x0, 0x0},130				{0x0, 0x0},131			},132		},133		sections: []*SectionHeader{134			{".text", 0xc64, 0x1000, 0xe00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500060},135			{".data", 0x10, 0x2000, 0x200, 0x1200, 0x0, 0x0, 0x0, 0x0, 0xc0300040},136			{".rdata", 0x134, 0x3000, 0x200, 0x1400, 0x0, 0x0, 0x0, 0x0, 0x40300040},137			{".eh_fram", 0x3a0, 0x4000, 0x400, 0x1600, 0x0, 0x0, 0x0, 0x0, 0x40300040},138			{".bss", 0x60, 0x5000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0300080},139			{".idata", 0x378, 0x6000, 0x400, 0x1a00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},140			{".CRT", 0x18, 0x7000, 0x200, 0x1e00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},141			{".tls", 0x20, 0x8000, 0x200, 0x2000, 0x0, 0x0, 0x0, 0x0, 0xc0300040},142		},143		hasNoDwarfInfo: true,144	},145	{146		file: "testdata/gcc-amd64-mingw-obj",147		hdr:  FileHeader{0x8664, 0x6, 0x0, 0x198, 0x12, 0x0, 0x4},148		sections: []*SectionHeader{149			{".text", 0x0, 0x0, 0x30, 0x104, 0x15c, 0x0, 0x3, 0x0, 0x60500020},150			{".data", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500040},151			{".bss", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500080},152			{".rdata", 0x0, 0x0, 0x10, 0x134, 0x0, 0x0, 0x0, 0x0, 0x40500040},153			{".xdata", 0x0, 0x0, 0xc, 0x144, 0x0, 0x0, 0x0, 0x0, 0x40300040},154			{".pdata", 0x0, 0x0, 0xc, 0x150, 0x17a, 0x0, 0x3, 0x0, 0x40300040},155		},156		symbols: []*Symbol{157			{".file", 0x0, -2, 0x0, 0x67},158			{"main", 0x0, 1, 0x20, 0x2},159			{".text", 0x0, 1, 0x0, 0x3},160			{".data", 0x0, 2, 0x0, 0x3},161			{".bss", 0x0, 3, 0x0, 0x3},162			{".rdata", 0x0, 4, 0x0, 0x3},163			{".xdata", 0x0, 5, 0x0, 0x3},164			{".pdata", 0x0, 6, 0x0, 0x3},165			{"__main", 0x0, 0, 0x20, 0x2},166			{"puts", 0x0, 0, 0x20, 0x2},167		},168		hasNoDwarfInfo: true,169	},170	{171		file: "testdata/gcc-amd64-mingw-exec",172		hdr:  FileHeader{0x8664, 0x11, 0x53e4364f, 0x39600, 0x6fc, 0xf0, 0x27},173		opthdr: &OptionalHeader64{174			0x20b, 0x2, 0x16, 0x6a00, 0x2400, 0x1600, 0x14e0, 0x1000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x0, 0x0, 0x5, 0x2, 0x0, 0x45000, 0x600, 0x46f19, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,175			[16]DataDirectory{176				{0x0, 0x0},177				{0xe000, 0x990},178				{0x0, 0x0},179				{0xa000, 0x498},180				{0x0, 0x0},181				{0x0, 0x0},182				{0x0, 0x0},183				{0x0, 0x0},184				{0x0, 0x0},185				{0x10000, 0x28},186				{0x0, 0x0},187				{0x0, 0x0},188				{0xe254, 0x218},189				{0x0, 0x0},190				{0x0, 0x0},191				{0x0, 0x0},192			}},193		sections: []*SectionHeader{194			{".text", 0x6860, 0x1000, 0x6a00, 0x600, 0x0, 0x0, 0x0, 0x0, 0x60500020},195			{".data", 0xe0, 0x8000, 0x200, 0x7000, 0x0, 0x0, 0x0, 0x0, 0xc0500040},196			{".rdata", 0x6b0, 0x9000, 0x800, 0x7200, 0x0, 0x0, 0x0, 0x0, 0x40600040},197			{".pdata", 0x498, 0xa000, 0x600, 0x7a00, 0x0, 0x0, 0x0, 0x0, 0x40300040},198			{".xdata", 0x488, 0xb000, 0x600, 0x8000, 0x0, 0x0, 0x0, 0x0, 0x40300040},199			{".bss", 0x1410, 0xc000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0600080},200			{".idata", 0x990, 0xe000, 0xa00, 0x8600, 0x0, 0x0, 0x0, 0x0, 0xc0300040},201			{".CRT", 0x68, 0xf000, 0x200, 0x9000, 0x0, 0x0, 0x0, 0x0, 0xc0400040},202			{".tls", 0x48, 0x10000, 0x200, 0x9200, 0x0, 0x0, 0x0, 0x0, 0xc0600040},203			{".debug_aranges", 0x600, 0x11000, 0x600, 0x9400, 0x0, 0x0, 0x0, 0x0, 0x42500040},204			{".debug_info", 0x1316e, 0x12000, 0x13200, 0x9a00, 0x0, 0x0, 0x0, 0x0, 0x42100040},205			{".debug_abbrev", 0x2ccb, 0x26000, 0x2e00, 0x1cc00, 0x0, 0x0, 0x0, 0x0, 0x42100040},206			{".debug_line", 0x3c4d, 0x29000, 0x3e00, 0x1fa00, 0x0, 0x0, 0x0, 0x0, 0x42100040},207			{".debug_frame", 0x18b8, 0x2d000, 0x1a00, 0x23800, 0x0, 0x0, 0x0, 0x0, 0x42400040},208			{".debug_str", 0x396, 0x2f000, 0x400, 0x25200, 0x0, 0x0, 0x0, 0x0, 0x42100040},209			{".debug_loc", 0x13240, 0x30000, 0x13400, 0x25600, 0x0, 0x0, 0x0, 0x0, 0x42100040},210			{".debug_ranges", 0xa70, 0x44000, 0xc00, 0x38a00, 0x0, 0x0, 0x0, 0x0, 0x42100040},211		},212	},213	{214		// testdata/vmlinuz-4.15.0-47-generic is a trimmed down version of Linux Kernel image.215		// The original Linux Kernel image is about 8M and it is not recommended to add such a big binary file to the repo.216		// Moreover only a very small portion of the original Kernel image was being parsed by debug/pe package.217		// In order to identify this portion, the original image was first parsed by modified debug/pe package.218		// Modification essentially communicated reader's positions before and after parsing.219		// Finally, bytes between those positions where written to a separate file,220		// generating trimmed down version Linux Kernel image used in this test case.221		file: "testdata/vmlinuz-4.15.0-47-generic",222		hdr:  FileHeader{0x8664, 0x4, 0x0, 0x0, 0x1, 0xa0, 0x206},223		opthdr: &OptionalHeader64{224			0x20b, 0x2, 0x14, 0x7c0590, 0x0, 0x168f870, 0x4680, 0x200, 0x0, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e50000, 0x200, 0x7c3ab0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6,225			[16]DataDirectory{226				{0x0, 0x0},227				{0x0, 0x0},228				{0x0, 0x0},229				{0x0, 0x0},230				{0x7c07a0, 0x778},231				{0x0, 0x0},232				{0x0, 0x0},233				{0x0, 0x0},234				{0x0, 0x0},235				{0x0, 0x0},236				{0x0, 0x0},237				{0x0, 0x0},238				{0x0, 0x0},239				{0x0, 0x0},240				{0x0, 0x0},241				{0x0, 0x0},242			}},243		sections: []*SectionHeader{244			{".setup", 0x41e0, 0x200, 0x41e0, 0x200, 0x0, 0x0, 0x0, 0x0, 0x60500020},245			{".reloc", 0x20, 0x43e0, 0x20, 0x43e0, 0x0, 0x0, 0x0, 0x0, 0x42100040},246			{".text", 0x7bc390, 0x4400, 0x7bc390, 0x4400, 0x0, 0x0, 0x0, 0x0, 0x60500020},247			{".bss", 0x168f870, 0x7c0790, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc8000080},248		},249		hasNoDwarfInfo: true,250	},251}252 253func isOptHdrEq(a, b any) bool {254	switch va := a.(type) {255	case *OptionalHeader32:256		vb, ok := b.(*OptionalHeader32)257		if !ok {258			return false259		}260		return *vb == *va261	case *OptionalHeader64:262		vb, ok := b.(*OptionalHeader64)263		if !ok {264			return false265		}266		return *vb == *va267	case nil:268		return b == nil269	}270	return false271}272 273func TestOpen(t *testing.T) {274	for i := range fileTests {275		tt := &fileTests[i]276 277		f, err := Open(tt.file)278		if err != nil {279			t.Error(err)280			continue281		}282		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {283			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)284			continue285		}286		if !isOptHdrEq(tt.opthdr, f.OptionalHeader) {287			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.OptionalHeader, tt.opthdr)288			continue289		}290 291		for i, sh := range f.Sections {292			if i >= len(tt.sections) {293				break294			}295			have := &sh.SectionHeader296			want := tt.sections[i]297			if !reflect.DeepEqual(have, want) {298				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)299			}300		}301		tn := len(tt.sections)302		fn := len(f.Sections)303		if tn != fn {304			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)305		}306		for i, have := range f.Symbols {307			if i >= len(tt.symbols) {308				break309			}310			want := tt.symbols[i]311			if !reflect.DeepEqual(have, want) {312				t.Errorf("open %s, symbol %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)313			}314		}315		if !tt.hasNoDwarfInfo {316			_, err = f.DWARF()317			if err != nil {318				t.Errorf("fetching %s dwarf details failed: %v", tt.file, err)319			}320		}321	}322}323 324func TestOpenFailure(t *testing.T) {325	filename := "file.go"    // not a PE file326	_, err := Open(filename) // don't crash327	if err == nil {328		t.Errorf("open %s: succeeded unexpectedly", filename)329	}330}331 332const (333	linkNoCgo = iota334	linkCgoDefault335	linkCgoInternal336	linkCgoExternal337)338 339func getImageBase(f *File) uintptr {340	switch oh := f.OptionalHeader.(type) {341	case *OptionalHeader32:342		return uintptr(oh.ImageBase)343	case *OptionalHeader64:344		return uintptr(oh.ImageBase)345	default:346		panic("unexpected optionalheader type")347	}348}349 350func testDWARF(t *testing.T, linktype int) {351	if runtime.GOOS != "windows" {352		t.Skip("skipping windows only test")353	}354	testenv.MustHaveGoRun(t)355 356	tmpdir := t.TempDir()357 358	src := filepath.Join(tmpdir, "a.go")359	file, err := os.Create(src)360	if err != nil {361		t.Fatal(err)362	}363	err = template.Must(template.New("main").Parse(testprog)).Execute(file, linktype != linkNoCgo)364	if err != nil {365		if err := file.Close(); err != nil {366			t.Error(err)367		}368		t.Fatal(err)369	}370	if err := file.Close(); err != nil {371		t.Fatal(err)372	}373 374	exe := filepath.Join(tmpdir, "a.exe")375	args := []string{"build", "-o", exe}376	switch linktype {377	case linkNoCgo:378	case linkCgoDefault:379	case linkCgoInternal:380		args = append(args, "-ldflags", "-linkmode=internal")381	case linkCgoExternal:382		args = append(args, "-ldflags", "-linkmode=external")383	default:384		t.Fatalf("invalid linktype parameter of %v", linktype)385	}386	args = append(args, src)387	out, err := exec.Command(testenv.GoToolPath(t), args...).CombinedOutput()388	if err != nil {389		t.Fatalf("building test executable for linktype %d failed: %s %s", linktype, err, out)390	}391	out, err = exec.Command(exe).CombinedOutput()392	if err != nil {393		t.Fatalf("running test executable failed: %s %s", err, out)394	}395	t.Logf("Testprog output:\n%s", string(out))396 397	matches := regexp.MustCompile("offset=(.*)\n").FindStringSubmatch(string(out))398	if len(matches) < 2 {399		t.Fatalf("unexpected program output: %s", out)400	}401	wantoffset, err := strconv.ParseUint(matches[1], 0, 64)402	if err != nil {403		t.Fatalf("unexpected main offset %q: %s", matches[1], err)404	}405 406	f, err := Open(exe)407	if err != nil {408		t.Fatal(err)409	}410	defer f.Close()411 412	imageBase := getImageBase(f)413 414	var foundDebugGDBScriptsSection bool415	for _, sect := range f.Sections {416		if sect.Name == ".debug_gdb_scripts" || sect.Name == ".zdebug_gdb_scripts" {417			foundDebugGDBScriptsSection = true418		}419	}420	if !foundDebugGDBScriptsSection {421		t.Error(".debug_gdb_scripts section is not found")422	}423 424	d, err := f.DWARF()425	if err != nil {426		t.Fatal(err)427	}428 429	// look for main.main430	r := d.Reader()431	for {432		e, err := r.Next()433		if err != nil {434			t.Fatal("r.Next:", err)435		}436		if e == nil {437			break438		}439		if e.Tag == dwarf.TagSubprogram {440			name, ok := e.Val(dwarf.AttrName).(string)441			if ok && name == "main.main" {442				t.Logf("Found main.main")443				addr, ok := e.Val(dwarf.AttrLowpc).(uint64)444				if !ok {445					t.Fatal("Failed to get AttrLowpc")446				}447				offset := uintptr(addr) - imageBase448				if offset != uintptr(wantoffset) {449					t.Fatalf("Runtime offset (0x%x) did "+450						"not match dwarf offset "+451						"(0x%x)", wantoffset, offset)452				}453				return454			}455		}456	}457	t.Fatal("main.main not found")458}459 460func TestBSSHasZeros(t *testing.T) {461	testenv.MustHaveExec(t)462 463	if runtime.GOOS != "windows" {464		t.Skip("skipping windows only test")465	}466	gccpath, err := exec.LookPath("gcc")467	if err != nil {468		t.Skip("skipping test: gcc is missing")469	}470 471	tmpdir := t.TempDir()472 473	srcpath := filepath.Join(tmpdir, "a.c")474	src := `475#include <stdio.h>476 477int zero = 0;478 479int480main(void)481{482	printf("%d\n", zero);483	return 0;484}485`486	err = os.WriteFile(srcpath, []byte(src), 0644)487	if err != nil {488		t.Fatal(err)489	}490 491	objpath := filepath.Join(tmpdir, "a.obj")492	cmd := exec.Command(gccpath, "-c", srcpath, "-o", objpath)493	out, err := cmd.CombinedOutput()494	if err != nil {495		t.Fatalf("failed to build object file: %v - %v", err, string(out))496	}497 498	f, err := Open(objpath)499	if err != nil {500		t.Fatal(err)501	}502	defer f.Close()503 504	var bss *Section505	for _, sect := range f.Sections {506		if sect.Name == ".bss" {507			bss = sect508			break509		}510	}511	if bss == nil {512		t.Fatal("could not find .bss section")513	}514	// We expect an error from bss.Data, as there are no contents.515	if _, err := bss.Data(); err == nil {516		t.Error("bss.Data succeeded, expected error")517	}518}519 520func TestDWARF(t *testing.T) {521	testDWARF(t, linkNoCgo)522}523 524const testprog = `525package main526 527import "fmt"528import "syscall"529import "unsafe"530{{if .}}import "C"531{{end}}532 533// struct MODULEINFO from the Windows SDK534type moduleinfo struct {535	BaseOfDll uintptr536	SizeOfImage uint32537	EntryPoint uintptr538}539 540func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {541	return unsafe.Pointer(uintptr(p) + x)542}543 544func funcPC(f interface{}) uintptr {545	var a uintptr546	return **(**uintptr)(add(unsafe.Pointer(&f), unsafe.Sizeof(a)))547}548 549func main() {550	kernel32 := syscall.MustLoadDLL("kernel32.dll")551	psapi := syscall.MustLoadDLL("psapi.dll")552	getModuleHandle := kernel32.MustFindProc("GetModuleHandleW")553	getCurrentProcess := kernel32.MustFindProc("GetCurrentProcess")554	getModuleInformation := psapi.MustFindProc("GetModuleInformation")555 556	procHandle, _, _ := getCurrentProcess.Call()557	moduleHandle, _, err := getModuleHandle.Call(0)558	if moduleHandle == 0 {559		panic(fmt.Sprintf("GetModuleHandle() failed: %d", err))560	}561 562	var info moduleinfo563	ret, _, err := getModuleInformation.Call(procHandle, moduleHandle,564		uintptr(unsafe.Pointer(&info)), unsafe.Sizeof(info))565 566	if ret == 0 {567		panic(fmt.Sprintf("GetModuleInformation() failed: %d", err))568	}569 570	offset := funcPC(main) - info.BaseOfDll571	fmt.Printf("base=0x%x\n", info.BaseOfDll)572	fmt.Printf("main=%p\n", main)573	fmt.Printf("offset=0x%x\n", offset)574}575`576 577func TestBuildingWindowsGUI(t *testing.T) {578	testenv.MustHaveGoBuild(t)579 580	if runtime.GOOS != "windows" {581		t.Skip("skipping windows only test")582	}583	tmpdir := t.TempDir()584 585	src := filepath.Join(tmpdir, "a.go")586	if err := os.WriteFile(src, []byte(`package main; func main() {}`), 0644); err != nil {587		t.Fatal(err)588	}589	exe := filepath.Join(tmpdir, "a.exe")590	cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags", "-H=windowsgui", "-o", exe, src)591	out, err := cmd.CombinedOutput()592	if err != nil {593		t.Fatalf("building test executable failed: %s %s", err, out)594	}595 596	f, err := Open(exe)597	if err != nil {598		t.Fatal(err)599	}600	defer f.Close()601 602	switch oh := f.OptionalHeader.(type) {603	case *OptionalHeader32:604		if oh.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_GUI {605			t.Errorf("unexpected Subsystem value: have %d, but want %d", oh.Subsystem, IMAGE_SUBSYSTEM_WINDOWS_GUI)606		}607	case *OptionalHeader64:608		if oh.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_GUI {609			t.Errorf("unexpected Subsystem value: have %d, but want %d", oh.Subsystem, IMAGE_SUBSYSTEM_WINDOWS_GUI)610		}611	default:612		t.Fatalf("unexpected OptionalHeader type: have %T, but want *pe.OptionalHeader32 or *pe.OptionalHeader64", oh)613	}614}615 616func TestImportTableInUnknownSection(t *testing.T) {617	if runtime.GOOS != "windows" {618		t.Skip("skipping Windows-only test")619	}620 621	// ws2_32.dll import table is located in ".rdata" section,622	// so it is good enough to test issue #16103.623	const filename = "ws2_32.dll"624	path, err := exec.LookPath(filename)625	if err != nil {626		t.Fatalf("unable to locate required file %q in search path: %s", filename, err)627	}628 629	f, err := Open(path)630	if err != nil {631		t.Error(err)632	}633	defer f.Close()634 635	// now we can extract its imports636	symbols, err := f.ImportedSymbols()637	if err != nil {638		t.Error(err)639	}640 641	if len(symbols) == 0 {642		t.Fatalf("unable to locate any imported symbols within file %q.", path)643	}644}645 646func TestInvalidOptionalHeaderMagic(t *testing.T) {647	// Files with invalid optional header magic should return error from NewFile()648	// (see https://golang.org/issue/30250 and https://golang.org/issue/32126 for details).649	// Input generated by gofuzz650	data := []byte("\x00\x00\x00\x0000000\x00\x00\x00\x00\x00\x00\x000000" +651		"00000000000000000000" +652		"000000000\x00\x00\x0000000000" +653		"00000000000000000000" +654		"0000000000000000")655 656	_, err := NewFile(bytes.NewReader(data))657	if err == nil {658		t.Fatal("NewFile succeeded unexpectedly")659	}660}661 662func TestImportedSymbolsNoPanicMissingOptionalHeader(t *testing.T) {663	// https://golang.org/issue/30250664	// ImportedSymbols shouldn't panic if optional headers is missing665	data, err := os.ReadFile("testdata/gcc-amd64-mingw-obj")666	if err != nil {667		t.Fatal(err)668	}669 670	f, err := NewFile(bytes.NewReader(data))671	if err != nil {672		t.Fatal(err)673	}674 675	if f.OptionalHeader != nil {676		t.Fatal("expected f.OptionalHeader to be nil, received non-nil optional header")677	}678 679	syms, err := f.ImportedSymbols()680	if err != nil {681		t.Fatal(err)682	}683 684	if len(syms) != 0 {685		t.Fatalf("expected len(syms) == 0, received len(syms) = %d", len(syms))686	}687 688}689 690func TestImportedSymbolsNoPanicWithSliceOutOfBound(t *testing.T) {691	// https://golang.org/issue/30253692	// ImportedSymbols shouldn't panic with slice out of bounds693	// Input generated by gofuzz694	data := []byte("L\x01\b\x00regi\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x0f\x03" +695		"\v\x01\x02\x18\x00\x0e\x00\x00\x00\x1e\x00\x00\x00\x02\x00\x00\x80\x12\x00\x00" +696		"\x00\x10\x00\x00\x00 \x00\x00\x00\x00@\x00\x00\x10\x00\x00\x00\x02\x00\x00" +697		"\x04\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00" +698		"\x00\x04\x00\x00\x06S\x00\x00\x03\x00\x00\x00\x00\x00 \x00\x00\x10\x00\x00" +699		"\x00\x00\x10\x00\x00\x10\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00" +700		"\x00\x00\x00\x00\x00`\x00\x00x\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +701		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +702		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +703		"\x00\x00\x00\x00\x00\x00\x00\x00\x04\x80\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00" +704		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8`\x00\x00|\x00\x00\x00" +705		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +706		"\x00\x00\x00\x00.text\x00\x00\x00d\f\x00\x00\x00\x10\x00\x00" +707		"\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +708		"`\x00P`.data\x00\x00\x00\x10\x00\x00\x00\x00 \x00\x00" +709		"\x00\x02\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +710		"@\x000\xc0.rdata\x00\x004\x01\x00\x00\x000\x00\x00" +711		"\x00\x02\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +712		"@\x000@.eh_fram\xa0\x03\x00\x00\x00@\x00\x00" +713		"\x00\x04\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +714		"@\x000@.bss\x00\x00\x00\x00`\x00\x00\x00\x00P\x00\x00" +715		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +716		"\x80\x000\xc0.idata\x00\x00x\x03\x00\x00\x00`\x00\x00" +717		"\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00" +718		"0\xc0.CRT\x00\x00\x00\x00\x18\x00\x00\x00\x00p\x00\x00\x00\x02" +719		"\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00" +720		"0\xc0.tls\x00\x00\x00\x00 \x00\x00\x00\x00\x80\x00\x00\x00\x02" +721		"\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\xc9" +722		"H\x895\x1d")723 724	f, err := NewFile(bytes.NewReader(data))725	if err != nil {726		t.Fatal(err)727	}728 729	syms, err := f.ImportedSymbols()730	if err != nil {731		t.Fatal(err)732	}733 734	if len(syms) != 0 {735		t.Fatalf("expected len(syms) == 0, received len(syms) = %d", len(syms))736	}737}738 
codekingpro/portable-devtools · Team Ai