- 首先利用 mmap allocate memory,回傳權限足夠的記憶體起點,如下:
char *memory = mmap(NULL, // address
4096, // size
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_JIT,
-1, // fd (not used here)
0); // offset (not used here)
因為在 mac 上還需要加入 MAP_JIT
- 做 assert 檢查,如下:
if (-1==*memory) return -1;
- 塞入 machine code,以 arm64 回傳指令
RET為例:0xC0035FD6考慮 byte order 在 runtime 應為0xD65F03C0
程式碼如下:
int i = 0;
memory[i++] = 0xC0;
memory[i++] = 0x03;
memory[i++] = 0x5F;
memory[i++] = 0xD6;
- 執行,接著 unmap,程式結束!
typedef int(*fn)();
fn f = (fn) memory;
遭遇的問題如下:
第一次欲 assign value 進 memory[0] pointer 指向的 value,runtime 會有 bus error。
用 lldb 檢查會卡在這一行,標標示錯誤位置在=:
memory[i++] = 0xD6;
報錯資訊為:EXC_BAD_ACCESS (code=2, address=0x10015c000)
- memory 的 type 為:
(char *) - memory 裡元素 的 type 為:
(char)
理論上應該沒錯,可以修改其值, 用 long 也是,遇到同樣問題,如下:
long *memory;
*memory = 0xD65F03C0;
一樣無法 assign..
此時若我們在 lldb 裡動態修改,則程式能順利運行完畢!
p memory[0]=0xC0
p memory[0]=0x03
p memory[0]=0x5F
p memory[0]=0xD6
可能的問題分析:
- 在 gdb 裡執行和在 gdb 外執行,stack 可能不一樣,外面執行可能帶有環境變數 link
- memory 讀寫權限可能還有問題 link
- Dereferencing Pointer 可能還沒初始化 link
- 或是我根本就沒有那一段 memory 的 ownership
潛在的 solution:
- 用
memcpy()?
[solved] stack overflow
因為我沒有初始化指標指到的變數.. XD