Implemented indirect calls

This commit is contained in:
Eduard Urbach 2024-08-16 20:39:04 +02:00
parent 499fe8aec8
commit 34aeba740a
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
4 changed files with 45 additions and 5 deletions

View File

@ -1,7 +1,8 @@
package x64 package x64
// Call places the return address on the top of the stack and continues // 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 { func Call(code []byte, address uint32) []byte {
return append( return append(
code, code,
@ -12,3 +13,18 @@ func Call(code []byte, address uint32) []byte {
byte(address>>24), 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),
)
}

View File

@ -111,6 +111,25 @@ func (a Assembler) Finalize() ([]byte, []byte) {
codePointers = append(codePointers, pointer) 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: case COMMENT:
continue continue

View File

@ -29,6 +29,7 @@ const (
// Control flow // Control flow
CALL CALL
CALL_AT
JE JE
JNE JNE
JG JG
@ -54,6 +55,8 @@ func (m Mnemonic) String() string {
return "and" return "and"
case CALL: case CALL:
return "call" return "call"
case CALL_AT:
return "call at"
case COMMENT: case COMMENT:
return "comment" return "comment"
case COMPARE: case COMPARE:

View File

@ -48,8 +48,9 @@ func (r *Result) finalize() ([]byte, []byte) {
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 0) final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 0)
final.Syscall() final.Syscall()
case "windows": case "windows":
final.RegisterNumber(asm.MOVE, x64.RAX, 0) final.RegisterNumber(asm.SUB, x64.RSP, 32+8)
final.Return() final.RegisterNumber(asm.MOVE, x64.RCX, 0)
final.Label(asm.CALL_AT, "ExitProcess")
} }
// This will place the main function immediately after the entry point // 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.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 1)
final.Syscall() final.Syscall()
case "windows": case "windows":
final.RegisterNumber(asm.MOVE, x64.RAX, 1) final.RegisterNumber(asm.SUB, x64.RSP, 32+8)
final.Return() final.RegisterNumber(asm.MOVE, x64.RCX, 1)
final.Label(asm.CALL_AT, "ExitProcess")
} }
code, data := final.Finalize() code, data := final.Finalize()