跳转至

给可执行文件追加数据

  • 好像是windows、linux都行,但是mac有强文件签名校验所以可能不行

Go

package main

import (
    "bytes"
    "encoding/binary"
    "fmt"
    "os"
)

var (
    _DataFlag = []byte("__SPECIAL_EXE_DATA__")
)

func main() {
    data, err := readData(os.Args[0])
    panicIf(err)
    fmt.Printf("data: `%s`\n", string(data))
}
// writeData 文件末尾追加字节:`{data: vlen B}{vlen: 4B}{ _DataFlag }`
func writeData(path string, data []byte) error {
    file, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND, os.ModeAppend)
    if err != nil {
        return err
    }
    defer file.Close()

    data = binary.LittleEndian.AppendUint32(data, uint32(len(data)))
    data = append(data, _DataFlag...)

    n, err := file.Write(data)
    if err != nil {
        return err
    }
    if n != len(data) {
        return fmt.Errorf("dnly write %d bytes, but expect %d bytes", n, len(data))
    }
    return nil
}

func readData(path string) ([]byte, error) {
    file, err := os.Open(path)
    if err != nil {
        return nil, err
    }
    stat, err := file.Stat()
    if err != nil {
        return nil, err
    }

    size := stat.Size()
    keyV := make([]byte, len(_DataFlag))
    keyI := int64(int(size) - len(_DataFlag))
    _, err = file.ReadAt(keyV, keyI)
    if err != nil {
        return nil, err
    }
    if bytes.Compare(keyV, _DataFlag) != 0 {
        return nil, fmt.Errorf("is no end with key=`%s`, but `%s`", _DataFlag, keyV)
    }

    valueLenI := keyI - 4
    valueLenV := make([]byte, 4)
    _, err = file.ReadAt(valueLenV, valueLenI)
    if err != nil {
        return nil, err
    }
    valueLen := binary.LittleEndian.Uint32(valueLenV)

    valueBS := make([]byte, valueLen)
    _, err = file.ReadAt(valueBS, valueLenI-int64(valueLen))
    if err != nil {
        return nil, err
    }
    return valueBS, nil
}
func panicIf(err error) {
    if err != nil {
        panic(err)
    }
}
func TestWriteInviteCode(t *testing.T) {
    cmd := exec.Command("go", "build", "-o", "./gocexe.exe", ".")
    output, err := cmd.CombinedOutput()
    require.NoError(t, err)
    t.Logf("`%s` output: `%s`", cmd.String(), string(output))

    err = writeData("./gocexe.exe", []byte("__sb__"))
    require.NoError(t, err)

    data, err := readData("./gocexe.exe")
    require.NoError(t, err)
    t.Logf("data: `%s`", data)
}