mirror of
https://wiilab.wiimart.org/wiimart/WiiMart-Patcher
synced 2025-09-05 21:11:13 +02:00
Support b/bl instructions
This commit is contained in:
parent
4eb530b71e
commit
c8559722ea
@ -54,7 +54,7 @@ func generateTag(tag Tag, tagContents []byte) []byte {
|
|||||||
byte(tag),
|
byte(tag),
|
||||||
}
|
}
|
||||||
// Tag length
|
// Tag length
|
||||||
contents = append(contents, toLength(len(tagContents))...)
|
contents = append(contents, fourByte(uint32(len(tagContents)))...)
|
||||||
// Tag contents
|
// Tag contents
|
||||||
contents = append(contents, tagContents...)
|
contents = append(contents, tagContents...)
|
||||||
|
|
||||||
@ -120,9 +120,9 @@ func generateOperaCertStore() {
|
|||||||
file.Write(append(header, caCertTag...))
|
file.Write(append(header, caCertTag...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// toLength returns 4 bytes, suitable for the given length.
|
// fourByte returns 4 bytes, suitable for the given length.
|
||||||
func toLength(value int) []byte {
|
func fourByte(value uint32) []byte {
|
||||||
holder := make([]byte, 4)
|
holder := make([]byte, 4)
|
||||||
binary.BigEndian.PutUint32(holder, uint32(value))
|
binary.BigEndian.PutUint32(holder, value)
|
||||||
return holder
|
return holder
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ func LoadCustomCA() PatchSet {
|
|||||||
LWZ(R3, 0xac, R28),
|
LWZ(R3, 0xac, R28),
|
||||||
LWZ(R5, 0xc4, R28),
|
LWZ(R5, 0xc4, R28),
|
||||||
// SSLSetRootCA(ssl_fd, ca_cert, cert_index)
|
// SSLSetRootCA(ssl_fd, ca_cert, cert_index)
|
||||||
Instruction{0x48, 0x01, 0x59, 0x49},
|
BL(0x800acae4, 0x800c242c),
|
||||||
|
|
||||||
// Check if successful
|
// Check if successful
|
||||||
CMPWI(R3, 0),
|
CMPWI(R3, 0),
|
||||||
@ -46,7 +46,7 @@ func LoadCustomCA() PatchSet {
|
|||||||
// Return error -1004 if failed
|
// Return error -1004 if failed
|
||||||
LI(R3, 0xfc14),
|
LI(R3, 0xfc14),
|
||||||
// b FUNCTION_PROLOG
|
// b FUNCTION_PROLOG
|
||||||
Instruction{0x48, 0x00, 0x00, 0xbc},
|
B(0x800acaf4, 0x800acbb0),
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ func LoadCustomCA() PatchSet {
|
|||||||
LWZ(R3, 0xac, R28),
|
LWZ(R3, 0xac, R28),
|
||||||
LWZ(R4, 0xd8, R28),
|
LWZ(R4, 0xd8, R28),
|
||||||
// SSLSetBuiltinRootCA(ssl_fd, cert_index)
|
// SSLSetBuiltinRootCA(ssl_fd, cert_index)
|
||||||
Instruction{0x48, 0x01, 0x5a, 0x75},
|
BL(0x800acb00, 0x800c2574),
|
||||||
|
|
||||||
// Check if successful
|
// Check if successful
|
||||||
CMPWI(R3, 0),
|
CMPWI(R3, 0),
|
||||||
@ -66,7 +66,7 @@ func LoadCustomCA() PatchSet {
|
|||||||
// Return error -1004 if failed
|
// Return error -1004 if failed
|
||||||
LI(R3, 0xfc14),
|
LI(R3, 0xfc14),
|
||||||
// b FUNCTION_PROLOG
|
// b FUNCTION_PROLOG
|
||||||
Instruction{0x48, 0x00, 0x00, 0xa0},
|
B(0x800acb10, 0x800acbb0),
|
||||||
}.toBytes(),
|
}.toBytes(),
|
||||||
After: Instructions{
|
After: Instructions{
|
||||||
// Our certificate is present at 0x802e97b8.
|
// Our certificate is present at 0x802e97b8.
|
||||||
@ -84,7 +84,7 @@ func LoadCustomCA() PatchSet {
|
|||||||
LWZ(R3, 0xac, R28),
|
LWZ(R3, 0xac, R28),
|
||||||
|
|
||||||
// SSLSetRootCA(ssl_fd, ca_cert, cert_index)
|
// SSLSetRootCA(ssl_fd, ca_cert, cert_index)
|
||||||
Instruction{0x48, 0x01, 0x59, 0x49},
|
BL(0x800acae4, 0x800c242c),
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
CMPWI(R3, 0),
|
CMPWI(R3, 0),
|
||||||
@ -94,7 +94,7 @@ func LoadCustomCA() PatchSet {
|
|||||||
// Return error -1004 if failed
|
// Return error -1004 if failed
|
||||||
LI(R3, 0xfc14),
|
LI(R3, 0xfc14),
|
||||||
// b FUNCTION_PROLOG
|
// b FUNCTION_PROLOG
|
||||||
Instruction{0x48, 0x00, 0x00, 0xbc},
|
B(0x800acaf4, 0x800acbb0),
|
||||||
|
|
||||||
// NOP the rest in order to allow execution to continue.
|
// NOP the rest in order to allow execution to continue.
|
||||||
NOP(), NOP(), NOP(), NOP(), NOP(), NOP(), NOP(),
|
NOP(), NOP(), NOP(), NOP(), NOP(), NOP(), NOP(),
|
||||||
|
35
powerpc.go
35
powerpc.go
@ -1,5 +1,15 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
// uint24 returns
|
||||||
|
func uint24(num uint32) [3]byte {
|
||||||
|
if num > 0x00FFFFFF {
|
||||||
|
panic("invalid uint24 passed")
|
||||||
|
}
|
||||||
|
|
||||||
|
result := fourByte(num)
|
||||||
|
return [3]byte{result[1], result[2], result[3]}
|
||||||
|
}
|
||||||
|
|
||||||
// Instruction represents a 4-byte PowerPC instruction.
|
// Instruction represents a 4-byte PowerPC instruction.
|
||||||
type Instruction [4]byte
|
type Instruction [4]byte
|
||||||
|
|
||||||
@ -102,3 +112,28 @@ func MFSPR() Instruction {
|
|||||||
func STWU(rS Register, rA Register, offset uint16) Instruction {
|
func STWU(rS Register, rA Register, offset uint16) Instruction {
|
||||||
return EncodeInstrDForm(37, rS, rA, offset)
|
return EncodeInstrDForm(37, rS, rA, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calcDestination determines the proper offset from a given
|
||||||
|
// calling address and target address.
|
||||||
|
func calcDestination(from uint, target uint) [3]byte {
|
||||||
|
// TODO(spotlightishere): Handle negative offsets properly
|
||||||
|
offset := target - from
|
||||||
|
|
||||||
|
// Sign-extend by two bytes
|
||||||
|
calc := uint32(offset >> 2)
|
||||||
|
return uint24(calc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BL represents the bl PowerPC instruction.
|
||||||
|
// It calculates the offset from the given current address and the given
|
||||||
|
// target address, saving the current address in the link register. It then branches.
|
||||||
|
func BL(current uint, target uint) Instruction {
|
||||||
|
return EncodeInstrIForm(18, calcDestination(current, target), false, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// B represents the b PowerPC instruction.
|
||||||
|
// It calculates the offset from the given current address
|
||||||
|
// and the given target address, and then branches.
|
||||||
|
func B(current uint, target uint) Instruction {
|
||||||
|
return EncodeInstrIForm(18, calcDestination(current, target), false, false)
|
||||||
|
}
|
||||||
|
@ -116,6 +116,42 @@ func EncodeInstrDForm(opcode byte, rT Register, rA Register, value uint16) Instr
|
|||||||
return Instruction{firstInstr, secondInstr, valByte[0], valByte[1]}
|
return Instruction{firstInstr, secondInstr, valByte[0], valByte[1]}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EncodeInstrIForm handles encoding a given opcode, LI, AA and LK.
|
||||||
|
// I-form assumes:
|
||||||
|
// - 6 bits for the opcode
|
||||||
|
// - 24 bits for LI
|
||||||
|
// - 1 bit for absolute (AA)
|
||||||
|
// - 1 bit for should store in link register (LK)
|
||||||
|
func EncodeInstrIForm(opcode byte, LI [3]byte, AA bool, LK bool) Instruction {
|
||||||
|
opBits := getBits(opcode)
|
||||||
|
liOne := getBits(LI[0])
|
||||||
|
liTwo := getBits(LI[1])
|
||||||
|
liThree := getBits(LI[2])
|
||||||
|
|
||||||
|
instr := [4]Bits{
|
||||||
|
{
|
||||||
|
// We need the upper six bits for our opcode.
|
||||||
|
opBits[2], opBits[3], opBits[4], opBits[5], opBits[6], opBits[7],
|
||||||
|
// Otherwise, copy LI as-is.
|
||||||
|
liOne[0], liOne[1],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
liOne[2], liOne[3], liOne[4], liOne[5], liOne[6], liOne[7], liTwo[0], liTwo[1],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
liTwo[2], liTwo[3], liTwo[4], liTwo[5], liTwo[6], liTwo[7], liThree[0], liThree[1],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
liThree[2], liThree[3], liThree[4], liThree[5], liThree[6], liThree[7],
|
||||||
|
// Copy AA and LK as-is.
|
||||||
|
AA,
|
||||||
|
LK,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return Instruction{instr[0].getByte(), instr[1].getByte(), instr[2].getByte(), instr[3].getByte()}
|
||||||
|
}
|
||||||
|
|
||||||
// twoByte converts a uint16 to two big-endian bytes.
|
// twoByte converts a uint16 to two big-endian bytes.
|
||||||
func twoByte(passed uint16) [2]byte {
|
func twoByte(passed uint16) [2]byte {
|
||||||
result := make([]byte, 2)
|
result := make([]byte, 2)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user