Created
April 18, 2018 22:11
-
-
Save ArcaneNibble/1a1834b784283add7955af4300973118 to your computer and use it in GitHub Desktop.
Code segment trickery / "Heaven's Gate" on Linux
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
global call_64_from_64 | |
global call_32_from_64 | |
global call_32_from_32 | |
section .text | |
call_64_from_64: | |
mov rsi, rdi | |
mov rax, 1 | |
mov rdi, 1 | |
mov rdx, 44 | |
syscall | |
ret | |
call_32_from_64: | |
push rbx | |
mov rax, 4 | |
mov rbx, 1 | |
mov rcx, rdi | |
mov rdx, 44 | |
int 0x80 | |
pop rbx | |
ret | |
call_32_from_32: | |
push rbx | |
; Stash stack | |
mov [_stack_stash], rsp | |
lea rsp, [rdi + 0x80] | |
; Stash "how to get back" | |
mov r9, 0x3300000000 | |
or r9, _call32_return_64 | |
push r9 | |
push _call32_return_32 | |
; Set up far return/jump | |
push 0x23 | |
push _call_32_from_32 | |
db 0x48 ; REX | |
retf | |
_call32_return_64: | |
mov rsp, [_stack_stash] | |
pop rbx | |
ret | |
section .bss | |
_stack_stash: resq 1 | |
BITS 32 | |
section .text | |
_call32_return_32: | |
add esp, 4 | |
retf | |
_call_32_from_32: | |
mov eax, 4 | |
mov ebx, 1 | |
mov ecx, edi | |
mov edx, 44 | |
int 0x80 | |
ret |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// nasm -f elf64 asmbits.asm | |
// gcc -no-pie -ggdb -Wall -O2 -o llgames llgames.c asmbits.o | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <string.h> | |
#include <sys/mman.h> | |
extern void call_64_from_64(void *buf); | |
extern void call_32_from_64(void *buf); | |
extern void call_32_from_32(void *buf); | |
int main(int argc, char **argv) { | |
printf("Hello world!\n"); | |
char *buf = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); | |
if (buf == MAP_FAILED) { | |
perror("mmap"); | |
return -1; | |
} | |
printf("buf = %p\n", buf); | |
strcpy(buf + 0x0, "Hello from 64-bit syscall from 64-bit code\n"); | |
strcpy(buf + 0x100, "Hello from 32-bit syscall from 64-bit code\n"); | |
// strcpy(buf + 0x200, "Hello from 64-bit syscall from 32-bit code\n"); | |
strcpy(buf + 0x300, "Hello from 32-bit syscall from 32-bit code\n"); | |
call_64_from_64(buf + 0x0); | |
call_32_from_64(buf + 0x100); | |
call_32_from_32(buf + 0x300); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment