forked from security/hakurei
Compare commits
1 Commits
wip-irdump
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
9fb0b2452e
|
@@ -1,76 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"hakurei.app/command"
|
||||
"hakurei.app/internal/pkg"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.SetFlags(0)
|
||||
log.SetPrefix("irdump: ")
|
||||
|
||||
var (
|
||||
flagOutput string
|
||||
flagReal bool
|
||||
flagHeader bool
|
||||
flagForce bool
|
||||
flagRaw bool
|
||||
)
|
||||
c := command.New(os.Stderr, log.Printf, "irdump", func(args []string) (err error) {
|
||||
var input *os.File
|
||||
if len(args) != 1 {
|
||||
return errors.New("irdump requires 1 argument")
|
||||
}
|
||||
if input, err = os.Open(args[0]); err != nil {
|
||||
return
|
||||
}
|
||||
defer input.Close()
|
||||
|
||||
var output *os.File
|
||||
if flagOutput == "" {
|
||||
output = os.Stdout
|
||||
} else {
|
||||
defer output.Close()
|
||||
if output, err = os.Create(flagOutput); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var out string
|
||||
if out, err = pkg.Disassemble(input, flagReal, flagHeader, flagForce, flagRaw); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = output.WriteString(out); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}).Flag(
|
||||
&flagOutput,
|
||||
"o", command.StringFlag(""),
|
||||
"Output file for asm (leave empty for stdout)",
|
||||
).Flag(
|
||||
&flagReal,
|
||||
"r", command.BoolFlag(false),
|
||||
"skip label generation; idents print real value",
|
||||
).Flag(
|
||||
&flagHeader,
|
||||
"H", command.BoolFlag(false),
|
||||
"display artifact headers",
|
||||
).Flag(
|
||||
&flagForce,
|
||||
"f", command.BoolFlag(false),
|
||||
"force display (skip validations)",
|
||||
).Flag(
|
||||
&flagRaw,
|
||||
"R", command.BoolFlag(false),
|
||||
"don't format output",
|
||||
)
|
||||
|
||||
c.MustParse(os.Args[1:], func(err error) {
|
||||
log.Fatal(err)
|
||||
})
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type asmOutLine struct {
|
||||
pos int
|
||||
word int
|
||||
kindData int64
|
||||
valueData []byte
|
||||
indent int
|
||||
kind string
|
||||
value string
|
||||
}
|
||||
|
||||
var spacingLine = asmOutLine{
|
||||
pos: -1,
|
||||
kindData: -1,
|
||||
valueData: nil,
|
||||
indent: 0,
|
||||
kind: "",
|
||||
value: "",
|
||||
}
|
||||
|
||||
func Disassemble(r io.Reader, real bool, showHeader bool, force bool, raw bool) (s string, err error) {
|
||||
var lines []asmOutLine
|
||||
sb := new(strings.Builder)
|
||||
header := true
|
||||
pos := new(int)
|
||||
|
||||
for err == nil {
|
||||
if header {
|
||||
var kind uint64
|
||||
var size uint64
|
||||
var bsize []byte
|
||||
p := *pos
|
||||
if _, kind, err = nextUint64(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
if bsize, size, err = nextUint64(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
if showHeader {
|
||||
lines = append(lines, asmOutLine{p, 8, int64(kind), bsize, 0, "head " + intToKind(kind), ""})
|
||||
}
|
||||
for i := 0; uint64(i) < size; i++ {
|
||||
var did Checksum
|
||||
var dkind uint64
|
||||
p := *pos
|
||||
if _, dkind, err = nextUint64(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
if _, did, err = nextIdent(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
if showHeader {
|
||||
lines = append(lines, asmOutLine{p, 8, int64(dkind), nil, 1, intToKind(dkind), Encode(did)})
|
||||
}
|
||||
}
|
||||
header = false
|
||||
}
|
||||
var k uint32
|
||||
p := *pos
|
||||
if _, k, err = nextUint32(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
kind := IRValueKind(k)
|
||||
switch kind {
|
||||
case IRKindEnd:
|
||||
var a uint32
|
||||
var ba []byte
|
||||
if ba, a, err = nextUint32(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
if a&1 != 0 {
|
||||
var sum Checksum
|
||||
if _, sum, err = nextIdent(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), ba, 1, "end ", Encode(sum)})
|
||||
} else {
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), []byte{0, 0, 0, 0}, 1, "end ", ""})
|
||||
}
|
||||
lines = append(lines, spacingLine)
|
||||
header = true
|
||||
continue
|
||||
|
||||
case IRKindIdent:
|
||||
var a []byte
|
||||
// discard ancillary
|
||||
if a, _, err = nextUint32(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
var sum Checksum
|
||||
if _, sum, err = nextIdent(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), a, 1, "id ", Encode(sum)})
|
||||
continue
|
||||
case IRKindUint32:
|
||||
var i uint32
|
||||
var bi []byte
|
||||
if bi, i, err = nextUint32(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), bi, 1, "int ", strconv.FormatUint(uint64(i), 10)})
|
||||
case IRKindString:
|
||||
var l uint32
|
||||
var bl []byte
|
||||
if bl, l, err = nextUint32(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
s := make([]byte, l+(wordSize-(l)%wordSize)%wordSize)
|
||||
var n int
|
||||
if n, err = r.Read(s); err != nil {
|
||||
break
|
||||
}
|
||||
*pos = *pos + n
|
||||
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), bl, 1, "str ", strconv.Quote(string(s[:l]))})
|
||||
continue
|
||||
default:
|
||||
var bi []byte
|
||||
if bi, _, err = nextUint32(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), bi, 1, "????", ""})
|
||||
}
|
||||
}
|
||||
if err != io.EOF {
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
for _, line := range lines {
|
||||
if raw {
|
||||
if line.pos != -1 {
|
||||
sb.WriteString(fmt.Sprintf("%s\t%s\n", line.kind, line.value))
|
||||
}
|
||||
} else {
|
||||
if line.pos == -1 {
|
||||
sb.WriteString("\n")
|
||||
} else if line.word == 4 {
|
||||
sb.WriteString(fmt.Sprintf("%06x: %04x %04x%s %s %s\n", line.pos, binary.LittleEndian.AppendUint32(nil, uint32(line.kindData)), line.valueData, headerSpacing(showHeader), line.kind, line.value))
|
||||
} else {
|
||||
kind := binary.LittleEndian.AppendUint64(nil, uint64(line.kindData))
|
||||
value := line.valueData
|
||||
if len(value) == 8 {
|
||||
sb.WriteString(fmt.Sprintf("%06x: %04x %04x %04x %04x %s %s\n", line.pos, kind[:4], kind[4:], value[:4], value[4:], line.kind, line.value))
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("%06x: %04x %04x %s %s\n", line.pos, kind[:4], kind[4:], line.kind, line.value))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return sb.String(), err
|
||||
}
|
||||
func nextUint32(r io.Reader, pos *int) ([]byte, uint32, error) {
|
||||
i := make([]byte, 4)
|
||||
_, err := r.Read(i)
|
||||
if err != nil {
|
||||
return i, 0, err
|
||||
}
|
||||
p := *pos + 4
|
||||
*pos = p
|
||||
return i, binary.LittleEndian.Uint32(i), nil
|
||||
}
|
||||
func nextUint64(r io.Reader, pos *int) ([]byte, uint64, error) {
|
||||
i := make([]byte, 8)
|
||||
_, err := r.Read(i)
|
||||
if err != nil {
|
||||
return i, 0, err
|
||||
}
|
||||
p := *pos + 8
|
||||
*pos = p
|
||||
return i, binary.LittleEndian.Uint64(i), nil
|
||||
}
|
||||
func nextIdent(r io.Reader, pos *int) ([]byte, Checksum, error) {
|
||||
i := make([]byte, 48)
|
||||
if _, err := r.Read(i); err != nil {
|
||||
return i, Checksum{}, err
|
||||
}
|
||||
p := *pos + 48
|
||||
*pos = p
|
||||
return i, Checksum(i), nil
|
||||
}
|
||||
func intToKind(i uint64) string {
|
||||
switch Kind(i) {
|
||||
case KindHTTPGet:
|
||||
return "http"
|
||||
case KindTar:
|
||||
return "tar "
|
||||
case KindExec:
|
||||
return "exec"
|
||||
case KindExecNet:
|
||||
return "exen"
|
||||
case KindFile:
|
||||
return "file"
|
||||
default:
|
||||
return fmt.Sprintf("$%d ", i-KindCustomOffset)
|
||||
}
|
||||
}
|
||||
func headerSpacing(showHeader bool) string {
|
||||
if showHeader {
|
||||
return " "
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
@@ -35,7 +35,7 @@ package
|
||||
|
||||
|
||||
*Default:*
|
||||
` <derivation hakurei-static-x86_64-unknown-linux-musl-0.3.4> `
|
||||
` <derivation hakurei-static-x86_64-unknown-linux-musl-0.3.5> `
|
||||
|
||||
|
||||
|
||||
@@ -805,7 +805,7 @@ package
|
||||
|
||||
|
||||
*Default:*
|
||||
` <derivation hakurei-hsu-0.3.4> `
|
||||
` <derivation hakurei-hsu-0.3.5> `
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "hakurei";
|
||||
version = "0.3.4";
|
||||
version = "0.3.5";
|
||||
|
||||
srcFiltered = builtins.path {
|
||||
name = "${pname}-src";
|
||||
|
||||
Reference in New Issue
Block a user