mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-24 03:49:45 +00:00
78b251cbd7
Not sure why I have not seen warnings about these lines on another machine...
112 lines
2.9 KiB
Go
112 lines
2.9 KiB
Go
// Copyright 2018 syzkaller project authors. All rights reserved.
|
|
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
|
|
|
// imagegen generates syz_mount_image/syz_read_part_table calls from disk images.
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
)
|
|
|
|
type Segment struct {
|
|
offset int
|
|
data []byte
|
|
}
|
|
|
|
func main() {
|
|
flagV := flag.Bool("v", false, "verbose output")
|
|
flagImage := flag.String("image", "", "image file")
|
|
flagSkip := flag.Int("skip", 32, "min zero bytes to skip")
|
|
flagAlign := flag.Int("align", 32, "non-zero block alignment")
|
|
flagFS := flag.String("fs", "", "filesystem")
|
|
flag.Parse()
|
|
data, err := ioutil.ReadFile(*flagImage)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "failed to read input file: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
data0 := data
|
|
zeros := make([]byte, *flagAlign+*flagSkip)
|
|
var segs []Segment
|
|
offset := 0
|
|
for len(data) != 0 {
|
|
pos := bytes.Index(data, zeros)
|
|
if pos == -1 {
|
|
segs = append(segs, Segment{offset, data})
|
|
break
|
|
}
|
|
pos = (pos + *flagAlign - 1) & ^(*flagAlign - 1)
|
|
if pos != 0 {
|
|
segs = append(segs, Segment{offset, data[:pos]})
|
|
}
|
|
for pos < len(data) && data[pos] == 0 {
|
|
pos++
|
|
}
|
|
pos = pos & ^(*flagAlign - 1)
|
|
offset += pos
|
|
data = data[pos:]
|
|
}
|
|
totalData := 0
|
|
for _, seg := range segs {
|
|
totalData += len(seg.data)
|
|
}
|
|
fmt.Fprintf(os.Stderr, "image size: %v, segments: %v, data: %v\n",
|
|
len(data0), len(segs), totalData)
|
|
if *flagV {
|
|
for i, seg := range segs {
|
|
next := len(data0)
|
|
if i != len(segs)-1 {
|
|
next = segs[i+1].offset
|
|
}
|
|
skip := next - seg.offset - len(seg.data)
|
|
fmt.Fprintf(os.Stderr, "segment: %8v-%8v [%8v] -%8v\n",
|
|
seg.offset, seg.offset+len(seg.data), len(seg.data), skip)
|
|
}
|
|
}
|
|
restored := make([]byte, len(data0))
|
|
for _, seg := range segs {
|
|
copy(restored[seg.offset:], seg.data)
|
|
}
|
|
if !bytes.Equal(data0, restored) {
|
|
fmt.Fprintf(os.Stderr, "restored data differs!\n")
|
|
os.Exit(1)
|
|
}
|
|
if *flagFS == "part" {
|
|
fmt.Printf(`syz_read_part_table(0x%x, 0x%x, &(0x7f0000000200)=[`,
|
|
len(data0), len(segs))
|
|
addr := 0x7f0000010000
|
|
for i, seg := range segs {
|
|
if i != 0 {
|
|
fmt.Printf(", ")
|
|
}
|
|
fmt.Printf(`{&(0x%x)="%v", 0x%x, 0x%x}`,
|
|
addr, hex.EncodeToString(seg.data), len(seg.data), seg.offset)
|
|
addr = (addr + len(seg.data) + 0xff) & ^0xff
|
|
}
|
|
fmt.Printf("])\n")
|
|
} else {
|
|
syscallSuffix := *flagFS
|
|
if syscallSuffix == "ext2" || syscallSuffix == "ext3" {
|
|
syscallSuffix = "ext4"
|
|
}
|
|
fmt.Printf(`syz_mount_image$%v(&(0x7f0000000000)='%v\x00', &(0x7f0000000100)='./file0\x00',`+
|
|
` 0x%x, 0x%x, &(0x7f0000000200)=[`,
|
|
syscallSuffix, *flagFS, len(data0), len(segs))
|
|
addr := 0x7f0000010000
|
|
for i, seg := range segs {
|
|
if i != 0 {
|
|
fmt.Printf(", ")
|
|
}
|
|
fmt.Printf(`{&(0x%x)="%v", 0x%x, 0x%x}`,
|
|
addr, hex.EncodeToString(seg.data), len(seg.data), seg.offset)
|
|
addr = (addr + len(seg.data) + 0xff) & ^0xff
|
|
}
|
|
fmt.Printf("], 0x0, &(0x%x))\n", addr)
|
|
}
|
|
}
|