Skip to content

Commit

Permalink
Added new FindBaseAddressSymbol and ReplaceBytesAtSymbol instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
pgaskin committed Feb 4, 2019
1 parent 2de6b3f commit de36f39
Show file tree
Hide file tree
Showing 7 changed files with 5,536 additions and 0 deletions.
69 changes: 69 additions & 0 deletions patchfile/kobopatch/kobopatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type instruction struct {
BaseAddress *int32 `yaml:"BaseAddress,omitempty"`
FindBaseAddressHex *string `yaml:"FindBaseAddressHex,omitempty"`
FindBaseAddressString *string `yaml:"FindBaseAddressString,omitempty"`
FindBaseAddressSymbol *string `yaml:"FindBaseAddressSymbol,omitempty"`
FindZlib *string `yaml:"FindZlib,omitempty"`
FindZlibHash *string `yaml:"FindZlibHash,omitempty"`
FindReplaceString *struct {
Expand Down Expand Up @@ -53,6 +54,15 @@ type instruction struct {
Find []byte `yaml:"Find,omitempty"`
Replace []byte `yaml:"Replace,omitempty"`
} `yaml:"ReplaceBytes,omitempty"`
ReplaceBytesAtSymbol *struct {
Symbol string `yaml:"Symbol,omitempty"`
Offset int32 `yaml:"Offset,omitempty"`
FindH *string `yaml:"FindH,omitempty"`
ReplaceH *string `yaml:"ReplaceH,omitempty"`
FindBLX *uint32 `yaml:"FindBLX,omitempty"`
Find []byte `yaml:"Find,omitempty"`
Replace []byte `yaml:"Replace,omitempty"`
} `yaml:"ReplaceBytesAtSymbol,omitempty"`
ReplaceBytesNOP *struct {
Offset int32 `yaml:"Offset,omitempty"`
FindH *string `yaml:"FindH,omitempty"`
Expand Down Expand Up @@ -132,6 +142,34 @@ func Parse(buf []byte) (patchfile.PatchSet, error) {
patchfile.Log(" decoded hex `%s` to `%v`\n", hex, ((*ps)[n][i].ReplaceBytes).Replace)
}
}
if (*ps)[n][i].ReplaceBytesAtSymbol != nil {
if ((*ps)[n][i].ReplaceBytesAtSymbol).FindH != nil {
hex := *((*ps)[n][i].ReplaceBytesAtSymbol).FindH
_, err := fmt.Sscanf(
strings.Replace(hex, " ", "", -1),
"%x\n",
&((*ps)[n][i].ReplaceBytesAtSymbol).Find,
)
if err != nil {
patchfile.Log(" error decoding hex `%s`: %v\n", hex, err)
return nil, errors.Errorf("error parsing patch file: error expanding shorthand hex `%s`", hex)
}
patchfile.Log(" decoded hex `%s` to `%v`\n", hex, ((*ps)[n][i].ReplaceBytesAtSymbol).Find)
}
if ((*ps)[n][i].ReplaceBytesAtSymbol).ReplaceH != nil {
hex := *((*ps)[n][i].ReplaceBytesAtSymbol).ReplaceH
_, err := fmt.Sscanf(
strings.Replace(hex, " ", "", -1),
"%x\n",
&((*ps)[n][i].ReplaceBytesAtSymbol).Replace,
)
if err != nil {
patchfile.Log(" error decoding hex `%s`: %v\n", hex, err)
return nil, errors.Errorf("error parsing patch file: error expanding shorthand hex `%s`", hex)
}
patchfile.Log(" decoded hex `%s` to `%v`\n", hex, ((*ps)[n][i].ReplaceBytesAtSymbol).Replace)
}
}
}
}

Expand Down Expand Up @@ -175,13 +213,20 @@ func (ps *PatchSet) Validate() error {
ic++
fbsc++
}
if i.FindBaseAddressSymbol != nil {
ic++
}
if i.FindBaseAddressHex != nil {
ic++
}
if i.ReplaceBytes != nil {
ic++
rbc++
}
if i.ReplaceBytesAtSymbol != nil {
ic++
rbc++
}
if i.ReplaceBytesNOP != nil {
ic++
rbc++
Expand Down Expand Up @@ -340,6 +385,9 @@ func (ps *PatchSet) ApplyTo(pt *patchlib.Patcher) error {
case i.FindBaseAddressString != nil:
patchfile.Log(" FindBaseAddressString(%#v) | hex:%x\n", *i.FindBaseAddressString, []byte(*i.FindBaseAddressString))
err = pt.FindBaseAddressString(*i.FindBaseAddressString)
case i.FindBaseAddressSymbol != nil:
patchfile.Log(" FindBaseAddressSymbol(%#v) | hex:%x\n", *i.FindBaseAddressSymbol, []byte(*i.FindBaseAddressSymbol))
err = pt.FindBaseAddressSymbol(*i.FindBaseAddressSymbol)
case i.ReplaceBytes != nil:
r := *i.ReplaceBytes
if r.FindBLX != nil {
Expand All @@ -348,6 +396,27 @@ func (ps *PatchSet) ApplyTo(pt *patchlib.Patcher) error {
}
patchfile.Log(" ReplaceBytes(%#v, %#v, %#v)\n", r.Offset, r.Find, r.Replace)
err = pt.ReplaceBytes(r.Offset, r.Find, r.Replace)
case i.ReplaceBytesAtSymbol != nil:
r := *i.ReplaceBytesAtSymbol
patchfile.Log(" ReplaceBytesAtSymbol(%#v, %#v, %#v, %#v)\n", r.Symbol, r.Offset, r.Find, r.Replace)
patchfile.Log(" FindBaseAddressSymbol(%#v) -> ", r.Symbol)
err = pt.FindBaseAddressSymbol(r.Symbol)
if err != nil {
err = errors.Wrap(err, "ReplaceBytesAtSymbol")
break
}
patchfile.Log("0x%06x\n", pt.GetCur())
if r.FindBLX != nil {
r.Find = patchlib.BLX(uint32(pt.GetCur()+r.Offset), *r.FindBLX)
patchfile.Log(" ReplaceBytesAtSymbol.FindBLX -> Set ReplaceBytesAtSymbol.Find to BLX(0x%X, 0x%X) -> %X", pt.GetCur()+r.Offset, *r.FindBLX, r.Find)
}
patchfile.Log("cur=0x%06x off=0x%x bytes=%x find=%x replace=%x\n", pt.GetCur(), r.Offset, pt.GetBytes()[pt.GetCur()+r.Offset:pt.GetCur()+r.Offset+4], r.Find, r.Replace)
patchfile.Log(" ReplaceBytes(%#v, %#v, %#v)\n", r.Offset, r.Find, r.Replace)
err = pt.ReplaceBytes(r.Offset, r.Find, r.Replace)
if err != nil {
err = errors.Wrap(err, "ReplaceBytesAtSymbol")
break
}
case i.ReplaceBytesNOP != nil:
r := *i.ReplaceBytesNOP
if r.FindBLX != nil {
Expand Down
25 changes: 25 additions & 0 deletions patchlib/patcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"bytes"
"compress/zlib"
"crypto/sha1"
"debug/elf"
"encoding/binary"
"fmt"
"io/ioutil"
"strings"
"unicode/utf8"

"github.com/DataDog/czlib"
"github.com/ianlancetaylor/demangle"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -66,6 +68,29 @@ func (p *Patcher) FindBaseAddressString(find string) error {
return p.FindBaseAddress([]byte(find))
}

// FindBaseAddressSymbol moves cur to the offset of a symbol by it's demangled c++ name.
func (p *Patcher) FindBaseAddressSymbol(find string) error {
e, err := elf.NewFile(bytes.NewReader(p.buf))
if err != nil {
return wrapErrIfNotNil("FindBaseAddressSymbol: could not open file as elf binary", err)
}
syms, err := e.DynamicSymbols()
if err != nil {
return wrapErrIfNotNil("FindBaseAddressSymbol: could not read dynsyms", err)
}
for _, sym := range syms {
name, err := demangle.ToString(sym.Name)
if err != nil {
name = sym.Name
}
if find != "" && find == name {
p.cur = int32(sym.Value)
return nil
}
}
return errors.New("FindBaseAddressSymbol: could not find symbol")
}

// ReplaceBytes replaces the first occurrence of a sequence of bytes with another of the same length.
func (p *Patcher) ReplaceBytes(offset int32, find, replace []byte) error {
return wrapErrIfNotNil("ReplaceBytes", p.replaceValue(offset, find, replace, true))
Expand Down
27 changes: 27 additions & 0 deletions vendor/github.com/ianlancetaylor/demangle/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions vendor/github.com/ianlancetaylor/demangle/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit de36f39

Please sign in to comment.