Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for arm64 #7

Open
trueToastedCode opened this issue Jun 14, 2023 · 9 comments
Open

Support for arm64 #7

trueToastedCode opened this issue Jun 14, 2023 · 9 comments

Comments

@trueToastedCode
Copy link

trueToastedCode commented Jun 14, 2023

Apple doesn't make x86_64 machines anymore, it would be nice, if we could update this code for Apple Silicon. Thx!

@rodionovd
Copy link
Owner

Hey there, thanks for the comment. I'm not doing low-level system programming anymore so it's not that interesting for me to work on arm64 targets support. I'd be happy to merge a PR tho!

@trueToastedCode
Copy link
Author

trueToastedCode commented Jun 14, 2023

Hey there, thanks for the comment. I'm not doing low-level system programming anymore so it's not that interesting for me to work on arm64 targets support. I'd be happy to merge a PR tho!

Mhh... I am currently trying to make rd_route function work... rd_duplicate_function already returns KERN_SUCCESS (after adding some defined(aarch64)). However _insert_jmp fails when calling _patch_memory.

I am currently using it with this code:

mach_msg_type_number_t size_of_jump = (sizeof(int) + 1);
...

int offset = (int)(to - where - size_of_jump);
opcodes[0] = 0x14; // unconditional branch with relative offset
*((int*)&opcodes[1]) = offset;
err = _patch_memory((void *)where, size_of_jump, opcodes);

Gives me this error:

../rd_route.c:343:
	error: mach_vm_protect() failed with error: 0x2
Assertion failed: (0 == strcmp(strerror(err), my_strerror(err))), function test_rd_route, file test_route.c, line 94.
Test clang_arm64: FAIL

@rodionovd
Copy link
Owner

rodionovd commented Jun 14, 2023

I strongly suspect that making arbitrary pages both writable and executable is not allowed for arm64. Could be even a macOS restriction nowadays.

While it's not clear from the error message which of two mach_vm_protect() invocation fails, I've came across this answer that suggest making a page writable-only first, writing data to it, and making it executable-only afterwards. Worth a shot 🤞

@trueToastedCode
Copy link
Author

I strongly suspect that making arbitrary pages both writable and executable is not allowed for arm64. Could be even a macOS restriction nowadays.

While it's not clear from the error message which of two mach_vm_protect() invocation fails, I've came across this answer that suggest making a page writable-only first, writing data to it, and making it executable afterwards. Worth a shot 🤞

Thanks 👍 This was indeed necessary to make the mach_vm_protect work. But now the code still fails without any specific error. Probably my branch instruction doesn't work...

@rodionovd
Copy link
Owner

Glad it helped. Unfortunately I have zero knowledge of arm64 assembly so can't help with the jump opcodes here...

@trueToastedCode
Copy link
Author

trueToastedCode commented Jun 16, 2023

Glad it helped. Unfortunately I have zero knowledge of arm64 assembly so can't help with the jump opcodes here...

The old branch instruction was indeed wrong... gave me illegal hardware instruction in console.

This is the "jump" code used on ChickenHook...

// aarch64
jump.resize(TRAMPOLINE_SIZE); // = 16

jump[0] = 0x49;
jump[1] = 0x00;
jump[2] = 0x00;
jump[3] = 0x58;
jump[4] = 0x20;
jump[5] = 0x01;
jump[6] = 0x1f;
jump[7] = 0xd6;

//int insOff = TRAMPOLINE_SIZE;
uint64_t absoluteAddr = (uint64_t) dest;

// log says relative, guess they meant absolute
log("Calculate relative jump addr <%d> - src <%p> dest <%p>", absoluteAddr, src,
    dest);

memcpy(&jump[8], &absoluteAddr, 8);

translating this...

mach_msg_type_number_t size_of_jump = (sizeof(uintptr_t) + 8); // = 16
...

opcodes[0] = 0x49;
opcodes[1] = 0x00;
opcodes[2] = 0x00;
opcodes[3] = 0x58;
opcodes[4] = 0x20;
opcodes[5] = 0x01;
opcodes[6] = 0x1f;
opcodes[7] = 0xd6;
// 49 00 00 58    ldr x9, #8
// 20 01 1F D6    br  x9

// uint64_t absoluteAddr = (uint64_t)to;
// memcpy(&opcodes[8], &absoluteAddr, 8);
// -> same thing as
*((uintptr_t*)&opcodes[8]) = (uintptr_t)to;
// write address to array, starting at index 8

Since this is tested code from another repository, it should work. Tho code still faisl, but I do have crash reports from running the build file...

lldb

Process 85050 launched: '/Users/lennard/Desktop/rd_route/tests/build/clang_arm64' (arm64)
Process 85050 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000000000000
error: memory read failed for 0x0

console
https://pastebin.com/FYr2a1vS

@trueToastedCode
Copy link
Author

trueToastedCode commented Jun 16, 2023

Glad it helped. Unfortunately I have zero knowledge of arm64 assembly so can't help with the jump opcodes here...

First partial success 🎉

Doing the usage example:

static char* my_strerror(int err)
{
    return "It's OK";
}

int main(int argc, char const *argv[])
{
    int err = 2;
    rd_route(strerror, my_strerror, NULL);
    printf("%s\n", strerror(2));
    return 0;
}

does actually print It's OK.

@rodionovd
Copy link
Owner

Yay! So what was the issue with the jump instruction?

@trueToastedCode
Copy link
Author

Yay! So what was the issue with the jump instruction?

Nothing wrong with these opcodes now... think it's rd_duplicate_function that doesn't work properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants