#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int PROT_EXEC;
int PROT_READ;
int PROT_WRITE;
int mprotect(void *, int, int);
void stub1();
int main() {
  unsigned char mya[] = {
      0xB8, 0x04, 0x00, 0x00, 0x00, 0xBB, 0x01, 0x00, 0x00, 0x00, 0x59, 0xBA,
      0x0E, 0x00, 0x00, 0x00, 0xCD, 0x80, 0xEB, 0x09, 0xB8, 0x01, 0x00, 0x00,
      0x00, 0x31, 0xDB, 0xCD, 0x80, 0xE8, 0xDE, 0xFF, 0xFF, 0xFF, 0x48, 0x65,
      0x6C, 0x6C, 0x6F, 0x2C, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A};
  int Buffer1[5] = {1, 1, 1, 1, 1};
  int Buffer2[3] = {2, 2, 2};
  int Buffer3[3] = {3, 3, 3};
  void *addr = (void *)((unsigned long)mya & ((0UL - 1UL) ^ 0xfff));
  int ans = mprotect(addr, 1, PROT_READ | PROT_WRITE | PROT_EXEC);
  ((void (*)(void)) & Buffer3[12])();
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
movl   $0x0,-0x4(%rbp)
lea    -0x40(%rbp),%rdi
lea    0xec3(%rip),%rsi
mov    $0x30,%edx
call   1030 <memcpy@plt>
mov    0xee2(%rip),%rax
mov    %rax,-0x60(%rbp)
mov    0xedf(%rip),%rax
mov    %rax,-0x58(%rbp)
mov    0xedd(%rip),%eax
mov    %eax,-0x50(%rbp)
mov    0xed7(%rip),%rax
mov    %rax,-0x6c(%rbp)
mov    0xed5(%rip),%eax
mov    %eax,-0x64(%rbp)
mov    0xecf(%rip),%rax
mov    %rax,-0x78(%rbp)
mov    0xecd(%rip),%eax
mov    %eax,-0x70(%rbp)
lea    -0x40(%rbp),%rax
and    $0xfffffffffffff000,%rax
mov    %rax,-0x80(%rbp)
mov    -0x80(%rbp),%rdi
mov    0x2e51(%rip),%rax
mov    (%rax),%edx
mov    0x2e20(%rip),%rax
or     (%rax),%edx
mov    0x2e27(%rip),%rax
or     (%rax),%edx
mov    $0x1,%esi
call   1040 <mprotect@plt>
mov    %eax,-0x84(%rbp)
lea    -0x78(%rbp),%rax
add    $0x30,%rax
call   *%rax
xor    %eax,%eax
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
sub    $0x38,%rsp
movaps 0xf05(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
movaps 0xee9(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
movaps 0xecd(%rip),%xmm0
movaps %xmm0,(%rsp)
mov    %rsp,%rdi
mov    0x2eb7(%rip),%rax
mov    0x2e88(%rip),%rcx
mov    (%rcx),%edx
or     (%rax),%edx
and    $0xfffffffffffff000,%rdi
mov    0x2e86(%rip),%rax
or     (%rax),%edx
mov    $0x1,%esi
call   1030 <mprotect@plt>
lea    0xef3(%rip),%rax
call   *%rax
xor    %eax,%eax
add    $0x38,%rsp
ret

LLVM IR (-O0):
@__const.main.mya = [48 x i8] c"\B8\04\00\00\00\BB\01\00\00\00Y\BA\0E\00\00\00\CD\80\EB\09\B8\01\00\00\001\DB\CD\80\E8\DE\FF\FF\FFHello, World!\0A"
@__const.main.Buffer1 = [5 x i32] [i32 1, i32 1, i32 1, i32 1, i32 1]
@__const.main.Buffer2 = [3 x i32] [i32 2, i32 2, i32 2]
@__const.main.Buffer3 = [3 x i32] [i32 3, i32 3, i32 3]
@PROT_READ = global i32 0
@PROT_WRITE = global i32 0
@PROT_EXEC = global i32 0
define i32 @main() {
%1 = alloca i32
%2 = alloca [48 x i8]
%3 = alloca [5 x i32]
%4 = alloca [3 x i32]
%5 = alloca [3 x i32]
%6 = alloca i8*
%7 = alloca i32
store i32 0, i32* %1
%8 = bitcast [48 x i8]* %2 to i8*
%9 = bitcast [5 x i32]* %3 to i8*
%10 = bitcast [3 x i32]* %4 to i8*
%11 = bitcast [3 x i32]* %5 to i8*
%12 = getelementptr inbounds [48 x i8], [48 x i8]* %2, i64 0, i64 0
%13 = ptrtoint i8* %12 to i64
%14 = and i64 %13, -4096
%15 = inttoptr i64 %14 to i8*
store i8* %15, i8** %6
%16 = load i8*, i8** %6
%17 = load i32, i32* @PROT_READ
%18 = load i32, i32* @PROT_WRITE
%19 = or i32 %17, %18
%20 = load i32, i32* @PROT_EXEC
%21 = or i32 %19, %20
%22 = call i32 @mprotect(i8* %16, i32 1, i32 %21)
store i32 %22, i32* %7
%23 = getelementptr inbounds [3 x i32], [3 x i32]* %5, i64 0, i64 12
%24 = bitcast i32* %23 to void ()*
ret i32 0
}

LLVM IR (-O2):
@__const.main.mya = [48 x i8] c"\B8\04\00\00\00\BB\01\00\00\00Y\BA\0E\00\00\00\CD\80\EB\09\B8\01\00\00\001\DB\CD\80\E8\DE\FF\FF\FFHello, World!\0A"
@__const.main.Buffer3 = [3 x i32] [i32 3, i32 3, i32 3]
@PROT_READ = global i32 0
@PROT_WRITE = global i32 0
@PROT_EXEC = global i32 0
define i32 @main() {
%1 = alloca [48 x i8]
%2 = getelementptr inbounds [48 x i8], [48 x i8]* %1, i64 0, i64 0
%3 = ptrtoint [48 x i8]* %1 to i64
%4 = and i64 %3, -4096
%5 = inttoptr i64 %4 to i8*
%6 = load i32, i32* @PROT_READ
%7 = load i32, i32* @PROT_WRITE
%8 = or i32 %7, %6
%9 = load i32, i32* @PROT_EXEC
%10 = or i32 %8, %9
%11 = call i32 @mprotect(i8* %5, i32 1, i32 %10)
ret i32 0
}