pax-replace/extract/list
parent
e71cd8a105
commit
01af8d2a7a
@ -0,0 +1,98 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"git.cheetah.cat/cheetah/moto-flash-data/flashpart"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type MparPaxExtractCommand struct {
|
||||
InputFilename string `long:"mpar" short:"m" required:"true" description:"input-filename"`
|
||||
TargetFileName string `long:"file" short:"f" required:"true" description:"output-filename"`
|
||||
}
|
||||
|
||||
func (command *MparPaxExtractCommand) Execute(args []string) error {
|
||||
inputFile, err := os.Open(command.InputFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer inputFile.Close()
|
||||
inputFileStat, err := inputFile.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info().Int64("fileSize", inputFileStat.Size()).Msg("Reading raw file...")
|
||||
pdata := make([]byte, inputFileStat.Size())
|
||||
_, err = io.ReadFull(inputFile, pdata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fpHeader := flashpart.ParseFlashPartHeader(pdata[:32])
|
||||
log.Info().Msg(
|
||||
fmt.Sprintf("Media-ID: 0x%02X, Partition Size: 0x%08X / %d bytes, Partition Tag: %s",
|
||||
fpHeader.MediaID,
|
||||
fpHeader.TotalSize,
|
||||
fpHeader.TotalSize,
|
||||
fpHeader.VersionText,
|
||||
),
|
||||
)
|
||||
log.Info().Msg(
|
||||
fmt.Sprintf("Original-Full-Header-Hex: %s", hex.EncodeToString(pdata[:32])),
|
||||
)
|
||||
|
||||
if len(pdata[32:]) != len(pdata)-32 {
|
||||
return errors.New("something doesnt add up")
|
||||
}
|
||||
if len(pdata[32:]) != int(fpHeader.TotalSize)-32 {
|
||||
log.Error().Uint32("header ts", fpHeader.TotalSize).Uint32("len pdata", uint32(len(pdata))).Msg("size mismatch")
|
||||
return nil
|
||||
}
|
||||
|
||||
breader := bytes.NewReader(pdata[32:])
|
||||
tarReader := tar.NewReader(breader)
|
||||
|
||||
for {
|
||||
header, err := tarReader.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Error().Err(err)
|
||||
}
|
||||
|
||||
if header.Typeflag == tar.TypeReg && !strings.Contains(header.Name, "._") && header.Name == command.TargetFileName {
|
||||
content, err := io.ReadAll(tarReader)
|
||||
if err != nil {
|
||||
log.Error().Err(err)
|
||||
}
|
||||
|
||||
outputFile, err := os.Create(command.TargetFileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outputFile.Close()
|
||||
|
||||
_, err = outputFile.Write(content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info().Str("fileName", header.Name).Int64("fileSize", header.Size).Msg("extracted file")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
log.Error().Msg("no file extracted")
|
||||
|
||||
return nil
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"git.cheetah.cat/cheetah/moto-flash-data/flashpart"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type MparPaxListCommand struct {
|
||||
SourceFileName string `long:"file" short:"f" required:"true" description:"input-filename"`
|
||||
}
|
||||
|
||||
func (command *MparPaxListCommand) Execute(args []string) error {
|
||||
inputFile, err := os.Open(command.SourceFileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer inputFile.Close()
|
||||
|
||||
inputFileStat, err := inputFile.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info().Int64("fileSize", inputFileStat.Size()).Msg("Reading raw file...")
|
||||
pdata := make([]byte, inputFileStat.Size())
|
||||
_, err = io.ReadFull(inputFile, pdata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fpHeader := flashpart.ParseFlashPartHeader(pdata[:32])
|
||||
log.Info().Msg(
|
||||
fmt.Sprintf("Media-ID: 0x%02X, Partition Size: 0x%08X / %d bytes, Partition Tag: %s",
|
||||
fpHeader.MediaID,
|
||||
fpHeader.TotalSize,
|
||||
fpHeader.TotalSize,
|
||||
fpHeader.VersionText,
|
||||
),
|
||||
)
|
||||
log.Info().Msg(
|
||||
fmt.Sprintf("Original-Full-Header-Hex: %s", hex.EncodeToString(pdata[:32])),
|
||||
)
|
||||
|
||||
if len(pdata[32:]) != len(pdata)-32 {
|
||||
return errors.New("something doesnt add up")
|
||||
}
|
||||
if len(pdata[32:]) != int(fpHeader.TotalSize)-32 {
|
||||
log.Error().Uint32("header ts", fpHeader.TotalSize).Uint32("len pdata", uint32(len(pdata))).Msg("size mismatch")
|
||||
return nil
|
||||
}
|
||||
|
||||
breader := bytes.NewReader(pdata[32:])
|
||||
tarReader := tar.NewReader(breader)
|
||||
|
||||
for {
|
||||
header, err := tarReader.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Error().Err(err)
|
||||
}
|
||||
fmt.Println(header)
|
||||
|
||||
// if header.Typeflag == tar.TypeReg && !strings.Contains(header.Name, "._") {
|
||||
// // content, err := io.ReadAll(tarReader)
|
||||
// // if err != nil {
|
||||
// // log.Error().Err(err)
|
||||
// // }
|
||||
|
||||
// fmt.Println("FILE_NAME: ", header.Name)
|
||||
// ///fmt.Println(string(content))
|
||||
// }
|
||||
}
|
||||
return nil
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"git.cheetah.cat/cheetah/moto-flash-data/flashpart"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type MparPaxReplaceCommand struct {
|
||||
InputFilename string `long:"mpar" short:"m" required:"true" description:"Source Partition File"`
|
||||
OutputFilename string `long:"output" short:"o" required:"true" description:"Target Partition File"`
|
||||
FindFileName string `long:"file" short:"f" required:"true" description:"Name of the File to Find"`
|
||||
ReplaceWithFilename string `long:"replacewith" short:"r" required:"true" description:"Source Bytes for Replace-Action"`
|
||||
}
|
||||
|
||||
func (command *MparPaxReplaceCommand) Execute(args []string) error {
|
||||
inputFile, err := os.Open(command.InputFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer inputFile.Close()
|
||||
replaceWithFile, err := os.Open(command.ReplaceWithFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer replaceWithFile.Close()
|
||||
|
||||
inputFileStat, err := inputFile.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info().Int64("fileSize", inputFileStat.Size()).Msg("Reading raw file...")
|
||||
pdata := make([]byte, inputFileStat.Size())
|
||||
_, err = io.ReadFull(inputFile, pdata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fpHeader := flashpart.ParseFlashPartHeader(pdata[:32])
|
||||
log.Info().Msg(
|
||||
fmt.Sprintf("Media-ID: 0x%02X, Partition Size: 0x%08X / %d bytes, Partition Tag: %s",
|
||||
fpHeader.MediaID,
|
||||
fpHeader.TotalSize,
|
||||
fpHeader.TotalSize,
|
||||
fpHeader.VersionText,
|
||||
),
|
||||
)
|
||||
log.Info().Msg(
|
||||
fmt.Sprintf("Original-Full-Header-Hex: %s", hex.EncodeToString(pdata[:32])),
|
||||
)
|
||||
|
||||
if len(pdata[32:]) != len(pdata)-32 {
|
||||
return errors.New("something doesnt add up")
|
||||
}
|
||||
if len(pdata[32:]) != int(fpHeader.TotalSize)-32 {
|
||||
log.Error().Uint32("header ts", fpHeader.TotalSize).Uint32("len pdata", uint32(len(pdata))).Msg("size mismatch")
|
||||
return nil
|
||||
}
|
||||
|
||||
breader := bytes.NewReader(pdata[32:])
|
||||
tarReader := tar.NewReader(breader)
|
||||
|
||||
temporaryPaxFile, _ := os.CreateTemp("", "pax-replace.tar")
|
||||
defer temporaryPaxFile.Close()
|
||||
tarWriter := tar.NewWriter(temporaryPaxFile)
|
||||
defer tarWriter.Close()
|
||||
|
||||
for {
|
||||
header, err := tarReader.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
log.Error().Err(err)
|
||||
return err
|
||||
}
|
||||
if header.Typeflag == tar.TypeReg && !strings.Contains(header.Name, "._") && header.Name == command.FindFileName {
|
||||
log.Info().Str("fileName", header.Name).Int64("fileSize", header.Size).Msg("found file to modify")
|
||||
replaceWithFileStat, err := replaceWithFile.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
header.Size = replaceWithFileStat.Size()
|
||||
header.ModTime = replaceWithFileStat.ModTime()
|
||||
tarWriter.WriteHeader(header)
|
||||
content, err := io.ReadAll(replaceWithFile)
|
||||
if err != nil {
|
||||
log.Error().Err(err)
|
||||
}
|
||||
tarWriter.Write(content)
|
||||
} else {
|
||||
tarWriter.WriteHeader(header)
|
||||
content, err := io.ReadAll(tarReader)
|
||||
if err != nil {
|
||||
log.Error().Err(err)
|
||||
}
|
||||
tarWriter.Write(content)
|
||||
}
|
||||
}
|
||||
//log.Error().Msg("no file replaced")
|
||||
|
||||
// create new mpar with same header base
|
||||
_, err = temporaryPaxFile.Seek(0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
temporaryPaxFileStat, err := temporaryPaxFile.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rawData := make([]byte, temporaryPaxFileStat.Size())
|
||||
_, err = io.ReadFull(temporaryPaxFile, rawData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
outputFile, err := os.Create(command.OutputFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outputFile.Close()
|
||||
|
||||
fpHeader.AdjustRawSize(uint32(len(rawData)))
|
||||
|
||||
log.Info().Msg(
|
||||
fmt.Sprintf("New-Full-Header-Hex: %s", hex.EncodeToString(fpHeader.GetBytes())),
|
||||
)
|
||||
|
||||
fpHeaderNew := flashpart.ParseFlashPartHeader(fpHeader.GetBytes())
|
||||
log.Info().Msg(
|
||||
fmt.Sprintf("Media-ID: 0x%02X, Partition Size: 0x%08X / %d bytes, Partition Tag: %s",
|
||||
fpHeaderNew.MediaID,
|
||||
fpHeaderNew.TotalSize,
|
||||
fpHeaderNew.TotalSize,
|
||||
fpHeaderNew.VersionText,
|
||||
),
|
||||
)
|
||||
|
||||
_, err = outputFile.Write(fpHeaderNew.GetBytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = outputFile.Write(rawData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue