github.com/Rookout/GoSDK@v0.1.48/pkg/services/protector/writer_darwin_arm64.go (about)

     1  //go:build arm64 && darwin
     2  // +build arm64,darwin
     3  
     4  package protector
     5  
     6  /* #cgo CFLAGS:
     7  #include <mach/mach.h>
     8  #include <sys/mman.h>
     9  #include <libkern/OSCacheControl.h>
    10  #include <unistd.h>
    11  
    12  void  __attribute__ ((noinline)) align_writer_darwin_arm64_start() {
    13      asm(".align 14");
    14  }
    15  
    16  int get_current_memory_protection(uint64_t addr, uint64_t size);
    17  
    18  int mprotect_darwin(uint64_t addr, uint64_t size, int protection);
    19  
    20  // Parameters:
    21  //     dest - Address to write bytes to
    22  //     src - Address to take bytes to write from
    23  //     size - Number of bytes to write
    24  //     dest_start_page - Page aligned address of start of dest memory area
    25  //     dest_end_page - Page aligned address of end of dest memory area
    26  // Returns 0 on success, and on error:
    27  // -1: Failed to get current memory protection
    28  // -2: Failed to add write permission to memory
    29  // -3: Failed to return to previous memory permissions
    30  int write_bytes(unsigned long long dest, unsigned long long src, unsigned long long size, unsigned long long dest_start_page, unsigned long long dest_end_page) {
    31  	int current_memory_protection = get_current_memory_protection(dest_start_page, size);
    32  	if (-1 == current_memory_protection) {
    33  		return -1;
    34  	}
    35  
    36      int mprotect_res = mprotect_darwin(dest_start_page, dest_end_page-dest_start_page, PROT_READ|PROT_WRITE);
    37      if(0 != mprotect_res){
    38          return -2;
    39      }
    40  
    41      for(int i=0; i<size; i++){
    42          *(unsigned char*)(dest+i) = *(unsigned char*)(src+i);
    43      }
    44  
    45      mprotect_res = mprotect_darwin(dest_start_page, dest_end_page-dest_start_page, current_memory_protection);
    46  	if (0 != mprotect_res) {
    47  		return -3;
    48  	}
    49  
    50  	return 0;
    51  }
    52  
    53  void  __attribute__ ((noinline)) align_writer_darwin_arm64_end() {
    54  	asm(".align 14");
    55  }
    56  */
    57  import "C"
    58  import "unsafe"
    59  
    60  
    61  func Write(addr uintptr, bytes []byte, pageStart uintptr, pageEnd uintptr) int {
    62  	return int(C.write_bytes(C.ulonglong(addr), C.ulonglong(uintptr(unsafe.Pointer(&(bytes[0])))), C.ulonglong(len(bytes)), C.ulonglong(pageStart), C.ulonglong(pageEnd)))
    63  }