Skip to content

Commit

Permalink
FindBLX option on ReplaceBytes and ReplaceBytesNOP
Browse files Browse the repository at this point in the history
  • Loading branch information
pgaskin committed Dec 15, 2018
1 parent 5e654ef commit aec39b9
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 4 deletions.
16 changes: 13 additions & 3 deletions patchfile/kobopatch/kobopatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@ type instruction struct {
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:"ReplaceBytes,omitempty"`
ReplaceBytesNOP *struct {
Offset int32 `yaml:"Offset,omitempty"`
FindH *string `yaml:"FindH,omitempty"`
Find []byte `yaml:"Find,omitempty"`
Offset int32 `yaml:"Offset,omitempty"`
FindH *string `yaml:"FindH,omitempty"`
FindBLX *uint32 `yaml:"FindBLX,omitempty"`
Find []byte `yaml:"Find,omitempty"`
} `yaml:"ReplaceBytesNOP,omitempty"`
ReplaceZlib *struct {
Offset int32 `yaml:"Offset,omitempty"`
Expand Down Expand Up @@ -340,10 +342,18 @@ func (ps *PatchSet) ApplyTo(pt *patchlib.Patcher) error {
err = pt.FindBaseAddressString(*i.FindBaseAddressString)
case i.ReplaceBytes != nil:
r := *i.ReplaceBytes
if r.FindBLX != nil {
r.Find = patchlib.BLX(uint32(pt.GetCur()+r.Offset), *r.FindBLX)
patchfile.Log(" ReplaceBytes.FindBLX -> Set ReplaceBytes.Find to BLX(0x%X, 0x%X) -> %X", pt.GetCur()+r.Offset, *r.FindBLX, r.Find)
}
patchfile.Log(" ReplaceBytes(%#v, %#v, %#v)\n", r.Offset, r.Find, r.Replace)
err = pt.ReplaceBytes(r.Offset, r.Find, r.Replace)
case i.ReplaceBytesNOP != nil:
r := *i.ReplaceBytesNOP
if r.FindBLX != nil {
r.Find = patchlib.BLX(uint32(pt.GetCur()+r.Offset), *r.FindBLX)
patchfile.Log(" ReplaceBytesNOP.FindBLX -> Set ReplaceBytesNOP.Find to BLX(0x%X, 0x%X) -> %X", pt.GetCur()+r.Offset, *r.FindBLX, r.Find)
}
patchfile.Log(" ReplaceBytesNOP(%#v, %#v)\n", r.Offset, r.Find)
err = pt.ReplaceBytesNOP(r.Offset, r.Find)
case i.ReplaceFloat != nil:
Expand Down
6 changes: 6 additions & 0 deletions patchlib/blx.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ func blx(pc, target uint32) uint32 {
return uint32(top)<<16 | uint32(bot)
}

// BLX assembles a BLX instruction and returns a byte slice which
// can be patched directly into a binary.
func BLX(pc, target uint32) []byte {
return mustBytes(toBEBin(blx(pc, target)))
}

func swapBytes(word uint16) uint16 {
a, b := word&0x00ff, word&0xff00
return a<<8 | b>>8
Expand Down
7 changes: 6 additions & 1 deletion patchlib/patcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ func (p *Patcher) ReplaceBLX(offset int32, find, replace uint32) error {
if int32(len(p.buf)) < p.cur+offset {
return errors.New("offset past end of buf")
}
fi, ri := blx(uint32(p.cur+offset), find), blx(uint32(p.cur+offset), replace)
fi, ri := BLX(uint32(p.cur+offset), find), BLX(uint32(p.cur+offset), replace)
f, r := mustBytes(toBEBin(fi)), mustBytes(toBEBin(ri))
if len(f) != len(r) {
return errors.New("internal error: wrong blx length")
Expand Down Expand Up @@ -340,6 +340,11 @@ func (p *Patcher) ReplaceBytesNOP(offset int32, find []byte) error {
return nil
}

// GetCur gets the current base address.
func (p *Patcher) GetCur() int32 {
return p.cur
}

// replaceValue encodes find and replace as little-endian binary and replaces the first
// occurrence starting at cur. The lengths of the encoded find and replace must be the
// same, or an error will be returned.
Expand Down

0 comments on commit aec39b9

Please # to comment.