96 lines
2.4 KiB
NASM
Executable File
96 lines
2.4 KiB
NASM
Executable File
; vim: set ts=4 sw=4 tw=99 noet ft=nasm:
|
|
;
|
|
; AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
|
; Copyright (C) The AMX Mod X Development Team.
|
|
;
|
|
; This software is licensed under the GNU General Public License, version 3 or higher.
|
|
; Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
|
; https://alliedmods.net/amxmodx-license
|
|
|
|
;
|
|
; register_native functions for amd64
|
|
; Based on the concept by Julien "dJeyL" Laurent
|
|
; Thanks to T(+)rget for pushing to implement this
|
|
;
|
|
|
|
;;Initializes the global variable
|
|
|
|
BITS 64
|
|
|
|
section .text
|
|
|
|
global amxx_DynaInit, _amxx_DynaInit
|
|
;void amxx_DynaInit(void *ptr);
|
|
amxx_DynaInit:
|
|
_amxx_DynaInit:
|
|
mov [GLOBAL_GATE wrt rip], rdi
|
|
ret
|
|
|
|
;;Assembles the gateway function
|
|
global amxx_DynaMake, _amxx_DynaMake
|
|
;int amxx_DynaMake(char *buffer, int id);
|
|
amxx_DynaMake:
|
|
_amxx_DynaMake:
|
|
;we're not damaging the stack I think so we should be safe with no prologue
|
|
|
|
;save these two we're about to destroy them
|
|
push rsi ;push id
|
|
push rdi ;push buffer
|
|
|
|
mov rsi, _amxx_DynaFuncStart
|
|
mov rcx, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
|
cld ;clear direction flag (just in case)
|
|
rep movsb
|
|
|
|
pop rdi ;get buffer as destination
|
|
pop rax ;get id
|
|
;align us to mov rsi, 1234... - on x86-64 this is 2 bytes after the differential
|
|
add rdi, (_amxx_DynaFuncStart.move-_amxx_DynaFuncStart) + 2
|
|
mov [rdi], qword rax
|
|
;align rdi to the call
|
|
add rdi, (_amxx_DynaFuncStart.call-_amxx_DynaFuncStart.move)
|
|
mov rax, qword [GLOBAL_GATE wrt rip]
|
|
;copy the real address
|
|
mov [rdi], rax
|
|
|
|
ret
|
|
|
|
;;The gateway function we will re-assemble
|
|
;; This is similar to dJeyL's but a tad more elegant, as it's written in pure assembly
|
|
;; and NASM > GAS :')
|
|
global amxx_DynaFunc, _amxx_DynaFunc
|
|
;int amxx_DynaFunc(AMX *amx, cell *params);
|
|
amxx_DynaFunc:
|
|
_amxx_DynaFunc:
|
|
_amxx_DynaFuncStart:
|
|
push rbp
|
|
mov rbp, rsp
|
|
|
|
;we're given an amx and params... we're also hardcoded for this though:
|
|
mov rdx, rsi ;move 2nd param to 3rd
|
|
mov rsi, rdi ;move 1st param to 2nd
|
|
;this old trick, we'll move in the real pointer in a bit.
|
|
.move:
|
|
mov rdi, qword 1234567812345678h
|
|
.call:
|
|
mov rcx, qword 1234567812345678h
|
|
call rcx
|
|
|
|
pop rbp
|
|
ret
|
|
_amxx_DynaFuncEnd:
|
|
|
|
;;Just returns the buffer size required
|
|
global _amxx_DynaCodesize, amxx_DynaCodesize
|
|
;int amxx_DynaCodesize()
|
|
amxx_DynaCodesize:
|
|
_amxx_DynaCodesize:
|
|
; on x86-64 this is 34 bytes
|
|
mov rax, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
|
ret
|
|
|
|
section .data
|
|
|
|
GLOBAL_GATE DQ 0
|
|
|