Last active
April 21, 2020 08:51
-
-
Save mvo5/dab54b1c038c1e6f63a66106db09e170 to your computer and use it in GitHub Desktop.
Find needle in a ubuntu initrd (that is concated from multiple initrds)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"bytes" | |
"fmt" | |
"io" | |
"os" | |
"github.com/kjk/lzma" | |
"github.com/surma/gocpio" | |
) | |
func inspectSubCpio(r *cpio.Reader, fname, needle string) (found bool, err error) { | |
for { | |
h, err := r.Next() | |
if err != nil { | |
return false, err | |
} | |
if h.Name == fname { | |
buf := make([]byte, h.Size) | |
_, err := r.Read(buf) | |
if err != nil { | |
return false, err | |
} | |
if bytes.Contains(buf, []byte(needle)) { | |
return true, nil | |
} | |
return false, fmt.Errorf("needle %q not found in %q", needle, fname) | |
} | |
} | |
return false, nil | |
} | |
func findInInitramfs(initrdPath, fname, needle string) (found bool, err error) { | |
f, err := os.Open(initrdPath) | |
if err != nil { | |
return false, err | |
} | |
defer f.Close() | |
bf := bufio.NewReader(f) | |
for { | |
// XXX: there are some zeros between the cpio archives | |
// (or surma/gocpio is buggy), we need to skip those | |
x, err := bf.Peek(1) | |
if err == io.EOF { | |
break | |
} | |
if err != nil { | |
return false, err | |
} | |
// skip of zeros | |
if x[0] == 0x0 { | |
var buf [1]byte | |
bf.Read(buf[:]) | |
continue | |
} | |
// check file header | |
hrd, err := bf.Peek(6) | |
if err != nil { | |
return false, err | |
} | |
var mr io.Reader | |
// lzma, horrible to detect | |
if bytes.Equal(hrd[:3], []byte{0x5d, 0x00, 0x00}) { | |
mr = lzma.NewReader(bf) | |
// plain cpio | |
} else if string(hrd) == "070701" { | |
mr = bf | |
} else { | |
return false, fmt.Errorf("unknown header: %v", hrd) | |
} | |
// found a new "sub" cpio archive | |
r := cpio.NewReader(mr) | |
found, err := inspectSubCpio(r, fname, needle) | |
if found { | |
return found, nil | |
} | |
if err != nil && err != cpio.ErrInvalidHeader { | |
return false, err | |
} | |
} | |
return false, fmt.Errorf("file %q not found in %q", fname, initrdPath) | |
} | |
func main() { | |
// use as e.g. ./findininitramfs /path/to/unpacked/pc-kernel/ scripts/ubuntu-core-rootfs 'handle_writable_defaults()' | |
found, err := findInInitramfs(os.Args[1], os.Args[2], os.Args[3]) | |
if err != nil { | |
fmt.Printf("error: %v\n", err) | |
os.Exit(1) | |
} | |
fmt.Printf("found: %v\n", found) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment