package main import ( "io"; "os"; "fmt"; "regexp"; "xml"; "encoding/hex"; "bytes"; ); type Patch struct { Name string; Org string; Mod string; } type Binchg struct { Target string; Patch []Patch; } func main() { if( len(os.Args) < 3 ){ fmt.Printf( "Argument Error!\n" ); fmt.Printf( "\tUsage: binchg targetfile patchfile\n" ); return; } // read patch file patch_file, err := os.Open( os.Args[2], os.O_RDONLY, 0 ); if err != nil { patch_file.Close(); fmt.Printf( "patch file open Error!\n" ); } // parse patch file var result Binchg; xml.Unmarshal( patch_file, &result ) ; // read target file target_file, err := os.Open( os.Args[1], os.O_RDONLY, 0 ); if err != nil { target_file.Close(); fmt.Printf( "target file open Error!\n" ); } target, err := io.ReadAll( target_file ); if err != nil { target_file.Close(); fmt.Printf( "target file read Error!\n" ); } for i := range target { for j, p := range result.Patch { var org_bin []byte; var mod_bin []byte; if false { notuse := j; j = notuse}; r, err := regexp.Compile( " +" ); org_bin, err = hex.DecodeString(r.ReplaceAllString( p.Org, "" )); if err != nil { fmt.Printf( "%v\n", err ); } mod_bin, err = hex.DecodeString(r.ReplaceAllString( p.Mod, "" )); if err != nil { fmt.Printf( "%v\n", err ); } if i > len( org_bin ) { if bytes.Compare( target[i-len(org_bin):i], org_bin ) == 0 { fmt.Printf( "%d:%v\n", i, p.Name ); for k,v := range mod_bin { target[i-2:i][k] = v; } } } } } output_file, err := os.Open( os.Args[1] + ".patched" , os.O_WRONLY|os.O_CREAT, 0666 ); if err != nil { target_file.Close(); fmt.Printf( "open Error!\n" ); } output_file.Write( target ); output_file.Close(); }