talm

Форк
0
84 строки · 2.0 Кб
1
// This Source Code Form is subject to the terms of the Mozilla Public
2
// License, v. 2.0. If a copy of the MPL was not distributed with this
3
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4

5
package uki
6

7
import (
8
	"debug/pe"
9
	"errors"
10
	"fmt"
11
	"os"
12
	"os/exec"
13
	"path/filepath"
14
)
15

16
// assemble the UKI file out of sections.
17
func (builder *Builder) assemble() error {
18
	peFile, err := pe.Open(builder.SdStubPath)
19
	if err != nil {
20
		return err
21
	}
22

23
	defer peFile.Close() //nolint: errcheck
24

25
	// find the first VMA address
26
	lastSection := peFile.Sections[len(peFile.Sections)-1]
27

28
	// align the VMA to 512 bytes
29
	// https://github.com/saferwall/pe/blob/main/helper.go#L22-L26
30
	const alignment = 0x1ff
31

32
	header, ok := peFile.OptionalHeader.(*pe.OptionalHeader64)
33
	if !ok {
34
		return errors.New("failed to get optional header")
35
	}
36

37
	baseVMA := header.ImageBase + uint64(lastSection.VirtualAddress) + uint64(lastSection.VirtualSize)
38
	baseVMA = (baseVMA + alignment) &^ alignment
39

40
	// calculate sections size and VMA
41
	for i := range builder.sections {
42
		if !builder.sections[i].Append {
43
			continue
44
		}
45

46
		st, err := os.Stat(builder.sections[i].Path)
47
		if err != nil {
48
			return err
49
		}
50

51
		builder.sections[i].Size = uint64(st.Size())
52
		builder.sections[i].VMA = baseVMA
53

54
		baseVMA += builder.sections[i].Size
55
		baseVMA = (baseVMA + alignment) &^ alignment
56
	}
57

58
	// create the output file
59
	args := []string{}
60

61
	for _, section := range builder.sections {
62
		if !section.Append {
63
			continue
64
		}
65

66
		args = append(args, "--add-section", fmt.Sprintf("%s=%s", section.Name, section.Path), "--change-section-vma", fmt.Sprintf("%s=0x%x", section.Name, section.VMA))
67
	}
68

69
	builder.unsignedUKIPath = filepath.Join(builder.scratchDir, "unsigned.uki")
70

71
	args = append(args, builder.SdStubPath, builder.unsignedUKIPath)
72

73
	objcopy := "/usr/x86_64-alpine-linux-musl/bin/objcopy"
74

75
	if builder.Arch == "arm64" {
76
		objcopy = "/usr/aarch64-alpine-linux-musl/bin/objcopy"
77
	}
78

79
	cmd := exec.Command(objcopy, args...)
80
	cmd.Stdout = os.Stdout
81
	cmd.Stderr = os.Stderr
82

83
	return cmd.Run()
84
}
85

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.