Implemented indirect calls
This commit is contained in:
parent
499fe8aec8
commit
34aeba740a
@ -1,7 +1,8 @@
|
||||
package x64
|
||||
|
||||
// Call places the return address on the top of the stack and continues
|
||||
// program flow at the new address. The address is relative to the next instruction.
|
||||
// program flow at the new address.
|
||||
// The address is relative to the next instruction.
|
||||
func Call(code []byte, address uint32) []byte {
|
||||
return append(
|
||||
code,
|
||||
@ -12,3 +13,18 @@ func Call(code []byte, address uint32) []byte {
|
||||
byte(address>>24),
|
||||
)
|
||||
}
|
||||
|
||||
// CallAtAddress places the return address on the top of the stack and
|
||||
// continues program flow at the address stored at the given memory address.
|
||||
// The memory address is relative to the next instruction.
|
||||
func CallAtAddress(code []byte, address uint32) []byte {
|
||||
return append(
|
||||
code,
|
||||
0xFF,
|
||||
0x15,
|
||||
byte(address),
|
||||
byte(address>>8),
|
||||
byte(address>>16),
|
||||
byte(address>>24),
|
||||
)
|
||||
}
|
||||
|
@ -111,6 +111,25 @@ func (a Assembler) Finalize() ([]byte, []byte) {
|
||||
|
||||
codePointers = append(codePointers, pointer)
|
||||
|
||||
case CALL_AT:
|
||||
code = x64.CallAtAddress(code, 0x00_00_00_00)
|
||||
size := 4
|
||||
// label := x.Data.(*Label)
|
||||
|
||||
pointer := &Pointer{
|
||||
Position: Address(len(code) - size),
|
||||
OpSize: 2,
|
||||
Size: uint8(size),
|
||||
}
|
||||
|
||||
pointer.Resolve = func() Address {
|
||||
destination := Address(0x1038)
|
||||
distance := destination - (pointer.Position + Address(pointer.Size))
|
||||
return Address(distance)
|
||||
}
|
||||
|
||||
codePointers = append(codePointers, pointer)
|
||||
|
||||
case COMMENT:
|
||||
continue
|
||||
|
||||
|
@ -29,6 +29,7 @@ const (
|
||||
|
||||
// Control flow
|
||||
CALL
|
||||
CALL_AT
|
||||
JE
|
||||
JNE
|
||||
JG
|
||||
@ -54,6 +55,8 @@ func (m Mnemonic) String() string {
|
||||
return "and"
|
||||
case CALL:
|
||||
return "call"
|
||||
case CALL_AT:
|
||||
return "call at"
|
||||
case COMMENT:
|
||||
return "comment"
|
||||
case COMPARE:
|
||||
|
@ -48,8 +48,9 @@ func (r *Result) finalize() ([]byte, []byte) {
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 0)
|
||||
final.Syscall()
|
||||
case "windows":
|
||||
final.RegisterNumber(asm.MOVE, x64.RAX, 0)
|
||||
final.Return()
|
||||
final.RegisterNumber(asm.SUB, x64.RSP, 32+8)
|
||||
final.RegisterNumber(asm.MOVE, x64.RCX, 0)
|
||||
final.Label(asm.CALL_AT, "ExitProcess")
|
||||
}
|
||||
|
||||
// This will place the main function immediately after the entry point
|
||||
@ -70,8 +71,9 @@ func (r *Result) finalize() ([]byte, []byte) {
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 1)
|
||||
final.Syscall()
|
||||
case "windows":
|
||||
final.RegisterNumber(asm.MOVE, x64.RAX, 1)
|
||||
final.Return()
|
||||
final.RegisterNumber(asm.SUB, x64.RSP, 32+8)
|
||||
final.RegisterNumber(asm.MOVE, x64.RCX, 1)
|
||||
final.Label(asm.CALL_AT, "ExitProcess")
|
||||
}
|
||||
|
||||
code, data := final.Finalize()
|
||||
|
Loading…
Reference in New Issue
Block a user