Skip to content

Commit 739a8b4

Browse files
committed
Changed packer to not hold entire binary in RAM
1 parent 82b06a9 commit 739a8b4

File tree

2 files changed

+113
-46
lines changed

2 files changed

+113
-46
lines changed

Diff for: main.go

+9-46
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,32 @@
11
package main
22

33
import (
4-
"bytes"
5-
b64 "encoding/base64"
64
"flag"
75
"io"
86
"log"
97
"os"
10-
"strings"
11-
)
12-
13-
const (
14-
winPathI = iota
15-
linPathI = iota
16-
macPathI = iota
178
)
189

1910
func main() {
2011

21-
paths := make([]string, 3)
22-
23-
flag.StringVar(&paths[winPathI], "w", "", "Windows executable path")
24-
flag.StringVar(&paths[linPathI], "l", "", "Linux executable path")
25-
flag.StringVar(&paths[macPathI], "m", "", "MacOS executable path")
12+
paths := map[string]*string{
13+
"@binary_lin@": flag.String("l", "", "Linux executable path"),
14+
"@binary_win@": flag.String("w", "", "Windows executable path"),
15+
"@binary_mac@": flag.String("m", "", "MacOS executable path"),
16+
}
2617

2718
pOut := flag.String("o", "CrossBin.ps1", "Output file")
2819

2920
flag.Parse()
3021

31-
r, err := packBinaries(paths)
32-
if err != nil {
33-
log.Fatal(err)
22+
packer := Packer{
23+
PlacePath: paths,
3424
}
25+
packer.Init()
3526

3627
f, err := os.Create(*pOut)
3728
if err != nil {
3829
log.Fatal(err)
3930
}
40-
io.Copy(f, r)
41-
}
42-
43-
func packBinaries(paths []string) (io.Reader, error) {
44-
45-
templatePlaceholders := []string{"@binary_win@", "@binary_lin@", "@binary_mac@"}
46-
47-
script, err := os.ReadFile("script.template")
48-
if err != nil {
49-
return nil, err
50-
}
51-
52-
for i, p := range paths {
53-
54-
if p == "" {
55-
script = []byte(strings.Replace(string(script), templatePlaceholders[i], "", 1))
56-
continue
57-
}
58-
59-
bin, err := os.ReadFile(p)
60-
if err != nil {
61-
return nil, err
62-
}
63-
sbin := b64.StdEncoding.EncodeToString(bin)
64-
script = []byte(strings.Replace(string(script), templatePlaceholders[i], sbin, 1))
65-
}
66-
67-
return bytes.NewReader(script), nil
68-
31+
io.Copy(f, &packer)
6932
}

Diff for: packer.go

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"encoding/base64"
6+
"io"
7+
"log"
8+
"os"
9+
"sort"
10+
)
11+
12+
type Packer struct {
13+
PlacePath map[string]*string
14+
15+
Chunks []io.Reader
16+
curChunk int
17+
curPos int
18+
19+
script []byte
20+
}
21+
22+
func (p *Packer) Init() error {
23+
24+
sb, err := os.ReadFile("script.template")
25+
if err != nil {
26+
return err
27+
}
28+
p.script = sb
29+
30+
plocs := make(map[int]string)
31+
//Split by all placeholder
32+
for k, _ := range p.PlacePath {
33+
i := bytes.Index(p.script, []byte(k))
34+
plocs[i] = k
35+
}
36+
37+
var indexes []int
38+
for k, _ := range plocs {
39+
indexes = append(indexes, k)
40+
}
41+
sort.Ints(indexes)
42+
43+
scriptReader := bytes.NewBuffer(p.script)
44+
offset := 0
45+
for _, i := range indexes {
46+
47+
var buf []byte
48+
buf = make([]byte, i-offset)
49+
r, err := scriptReader.Read(buf)
50+
if err != nil {
51+
log.Println(err)
52+
break
53+
}
54+
p.Chunks = append(p.Chunks, bytes.NewBuffer(buf))
55+
56+
log.Println(plocs[i])
57+
fp := *p.PlacePath[plocs[i]]
58+
if fp != "" {
59+
f, err := os.Open(fp)
60+
if err != nil {
61+
log.Println(err)
62+
}
63+
64+
pr, pw := io.Pipe()
65+
bw := base64.NewEncoder(base64.StdEncoding, pw)
66+
go func() {
67+
io.Copy(bw, f)
68+
bw.Close()
69+
pw.Close()
70+
}()
71+
72+
p.Chunks = append(p.Chunks, pr)
73+
}
74+
75+
offset += r
76+
r, _ = scriptReader.Read(make([]byte, len(plocs[i])))
77+
offset += r
78+
}
79+
buf := make([]byte, len(p.script)-offset)
80+
scriptReader.Read(buf)
81+
p.Chunks = append(p.Chunks, bytes.NewBuffer(buf))
82+
83+
return nil
84+
}
85+
86+
func (p *Packer) Read(dst []byte) (int, error) {
87+
88+
total := 0
89+
for total < len(dst) {
90+
91+
r, err := p.Chunks[p.curChunk].Read(dst[total:])
92+
if err == io.EOF {
93+
if p.curChunk == len(p.Chunks)-1 {
94+
return total + r, io.EOF
95+
}
96+
p.curChunk += 1
97+
} else if err != nil {
98+
log.Fatal("error:", err)
99+
}
100+
total += r
101+
}
102+
103+
return total, nil
104+
}

0 commit comments

Comments
 (0)