Skip to content

Instantly share code, notes, and snippets.

@ciscoo
Created April 13, 2018 11:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ciscoo/4ea39e436df9537a284ec619e7e9777e to your computer and use it in GitHub Desktop.
Save ciscoo/4ea39e436df9537a284ec619e7e9777e to your computer and use it in GitHub Desktop.
Parses an iOS backup for SQLite files.
package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"os"
)
func main() {
err := os.RemoveAll("./parsed")
if err != nil {
log.Fatal(err)
}
os.Mkdir("./parsed", os.ModePerm)
if err != nil {
log.Fatal(err)
}
files, err := ioutil.ReadDir("./backup")
if err != nil {
log.Fatal(err)
}
dbs, err := filterSqlite(files, "./backup")
if err != nil {
log.Fatal(err)
}
err = copyWithExtension("sqlite", dbs)
if err != nil {
log.Fatal(err)
}
}
func filterSqlite(files []os.FileInfo, path string) ([]os.FileInfo, error) {
var filtered []os.FileInfo
for _, file := range files {
f, err := os.Open(fmt.Sprintf("%s/%s", path, file.Name()))
if err != nil {
return nil, err
}
b := make([]byte, 16)
_, err = f.Read(b)
if err != nil {
if err == io.EOF {
continue
}
return nil, err
}
// https://www.sqlite.org/fileformat.html#magic_header_string
if string(b) == "SQLite format 3\000" {
filtered = append(filtered, file)
}
f.Close()
}
return filtered, nil
}
func copyWithExtension(ext string, files []os.FileInfo) error {
for _, f := range files {
src, err := os.Open(fmt.Sprintf("./backup/%s", f.Name()))
if err != nil {
return err
}
dst, err := os.Create(fmt.Sprintf("./parsed/%s.%s", f.Name(), ext))
if err != nil {
return err
}
_, err = io.Copy(dst, src)
if err != nil {
return err
}
err = dst.Sync()
if err != nil {
return err
}
src.Close()
dst.Close()
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment