Skip to content

Instantly share code, notes, and snippets.

@artempyanykh
Last active February 20, 2019 12:28
Show Gist options
  • Save artempyanykh/0f512fff9eb2db9696afae7eb627a296 to your computer and use it in GitHub Desktop.
Save artempyanykh/0f512fff9eb2db9696afae7eb627a296 to your computer and use it in GitHub Desktop.
Memory mapping with RWX prot on aarch64

Memory mapping on aarch64

System information:

lscpu
echo "================================================="
cat /proc/cpuinfo
Architecture:        aarch64
Byte Order:          Little Endian
CPU(s):              4
On-line CPU(s) list: 0-3
Thread(s) per core:  1
Core(s) per socket:  4
Socket(s):           1
Vendor ID:           ARM
Model:               4
Model name:          Cortex-A53
Stepping:            r0p4
CPU max MHz:         1200.0000
CPU min MHz:         600.0000
BogoMIPS:            38.40
Flags:               fp asimd evtstrm crc32 cpuid
=================================================
processor	: 0
BogoMIPS	: 38.40
Features	: fp asimd evtstrm crc32 cpuid
CPU implementer	: 0x41
CPU architecture: 8
CPU variant	: 0x0
CPU part	: 0xd03
CPU revision	: 4

processor	: 1
BogoMIPS	: 38.40
Features	: fp asimd evtstrm crc32 cpuid
CPU implementer	: 0x41
CPU architecture: 8
CPU variant	: 0x0
CPU part	: 0xd03
CPU revision	: 4

processor	: 2
BogoMIPS	: 38.40
Features	: fp asimd evtstrm crc32 cpuid
CPU implementer	: 0x41
CPU architecture: 8
CPU variant	: 0x0
CPU part	: 0xd03
CPU revision	: 4

processor	: 3
BogoMIPS	: 38.40
Features	: fp asimd evtstrm crc32 cpuid
CPU implementer	: 0x41
CPU architecture: 8
CPU variant	: 0x0
CPU part	: 0xd03
CPU revision	: 4

Code

This is example_foo.c:

int foo(int a, int b)
{
        return a + b;
}
cc -c -o example_foo.o example_foo.c -O2

These are machine codes for add and sub:

0:	0b010000 	add	w0, w0, w1
---------------------------------------
0:	4b010000 	sub	w0, w0, w1

Let’s mmap example_foo.o object file and run some code from it:

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

typedef int foo_t(int, int);

int main()
{
        int fd;
        struct stat fs;
        assert((fd = open("example_foo.o", O_RDONLY)) != -1);
        assert(fstat(fd, &fs) == 0);

        long pagesize = sysconf(_SC_PAGESIZE);
        size_t roundedSize = (fs.st_size + (pagesize - 1)) & ~(pagesize - 1);

        printf("File size is %zu\n"
               "Page size is %ld\n"
               "Bytes to mmap %zu\n",
               fs.st_size, pagesize, roundedSize);

        void *reg = mmap(NULL, roundedSize,
                         PROT_READ | PROT_WRITE | PROT_EXEC,
                         MAP_PRIVATE,
                         fd, 0);
        assert(reg != MAP_FAILED);
        printf("Mapped file at address %p\n", reg);

        /* 0x40 is an offset to .text section inside object file where
         * foo is defined
         */
        foo_t *foo = (foo_t *)((char *)reg + 0x40);
        int result = foo(42, 23);
        printf("The result before write should be (42 + 23) = %d\n", result);

        /* sub instruction starts with 0x4b, due to little endianness
         * we need to modify 4th byte to turn add into sub
         */

        *((char *)reg + 0x40 + 3) = 0x4b;
        result = foo(42, 23);
        printf("The result after write should be (42 - 23) = %d\n", result);

        assert(munmap(reg, roundedSize) == 0);

        return 0;
}
: File size is 1016
: Page size is 4096
: Bytes to mmap 4096
: Mapped file at address 0xffffb27a6000
: The result before write should be (42 + 23) = 65
: The result after write should be (42 - 23) = 19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment