mirror of
https://github.com/geode-sdk/geode.git
synced 2025-01-05 12:12:04 -05:00
02efe58724
- move Core sources to platform folder - make sure source files on Mac include DefaultInclude - make sure sources are added in cmake
116 lines
3.6 KiB
C++
116 lines
3.6 KiB
C++
|
|
#include "Core.hpp"
|
|
#include "../../core/Core.hpp"
|
|
|
|
#include <Geode/DefaultInclude.hpp>
|
|
|
|
#ifdef GEODE_IS_MACOS
|
|
|
|
#include <mach/mach.h>
|
|
#include <mach/mach_init.h> /* mach_task_self() */
|
|
#include <mach/mach_port.h>
|
|
#include <mach/mach_vm.h> /* mach_vm_* */
|
|
#include <mach/task.h>
|
|
#include <signal.h> /* sigaction */
|
|
#include <sys/ucontext.h> /* ucontext_t */
|
|
|
|
using namespace geode::core::hook;
|
|
using namespace geode::core::impl;
|
|
|
|
namespace {
|
|
void signalHandler(int signal, siginfo_t* signal_info, void* vcontext) {
|
|
auto context = reinterpret_cast<ucontext_t*>(vcontext);
|
|
|
|
auto current = reinterpret_cast<void*>(context->uc_mcontext->__ss.__rip);
|
|
|
|
handleContext(vcontext, current);
|
|
}
|
|
}
|
|
|
|
bool MacOSX::enableSingleStep(void* vcontext) {
|
|
auto context = reinterpret_cast<ucontext_t*>(vcontext);
|
|
context->uc_mcontext->__ss.__rflags |= ((unsigned long)0x100);
|
|
return true;
|
|
}
|
|
|
|
bool MacOSX::disableSingleStep(void* vcontext) {
|
|
auto context = reinterpret_cast<ucontext_t*>(vcontext);
|
|
context->uc_mcontext->__ss.__rflags &= ~((unsigned long)0x100);
|
|
return true;
|
|
}
|
|
|
|
void* MacOSX::allocateVM(size_t size) {
|
|
mach_vm_address_t ret;
|
|
|
|
kern_return_t status; // return status
|
|
|
|
status = mach_vm_allocate(mach_task_self(), &ret, (mach_vm_size_t)size, VM_FLAGS_ANYWHERE);
|
|
|
|
return (void*)ret;
|
|
}
|
|
|
|
std::vector<std::byte> MacOSX::jump(void* from, void* to) {
|
|
constexpr size_t size = sizeof(int) + 1;
|
|
std::vector<std::byte> ret(size);
|
|
ret[0] = { 0xe9 };
|
|
|
|
int offset = (int)((size_t)to - (size_t)from - size);
|
|
// im too lazy
|
|
((int*)((size_t)ret.data() + 1))[0] = offset;
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool MacOSX::writeMemory(void* to, void* from, size_t size) {
|
|
kern_return_t status; // return status
|
|
|
|
mach_vm_size_t vmsize;
|
|
mach_vm_address_t address = (mach_vm_address_t)to;
|
|
vm_region_basic_info_data_t info;
|
|
mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT;
|
|
mach_port_t object;
|
|
|
|
// std::cout << "get memory protection" << std::endl;
|
|
// // get memory protection
|
|
// status = mach_vm_region(mach_task_self(), &address, &vmsize, VM_REGION_BASIC_INFO,
|
|
// (vm_region_info_t)&info, &info_count, &object); std::cout << status << std::endl; if (status
|
|
// != KERN_SUCCESS) return false;
|
|
|
|
// std::cout << "set to write protection" << std::endl;
|
|
// set to write protection
|
|
status = mach_vm_protect(
|
|
mach_task_self(), (mach_vm_address_t)to, size, FALSE,
|
|
VM_PROT_COPY | VM_PROT_EXECUTE | VM_PROT_WRITE | VM_PROT_READ
|
|
);
|
|
if (status != KERN_SUCCESS) return false;
|
|
|
|
// std::cout << "write to memory" << std::endl;
|
|
// write to memory
|
|
status = mach_vm_write(
|
|
mach_task_self(), (mach_vm_address_t)to, (vm_offset_t)from, (mach_msg_type_number_t)size
|
|
);
|
|
if (status != KERN_SUCCESS) return false;
|
|
|
|
// std::cout << "revert to old protection" << std::endl;
|
|
// // revert to old protection
|
|
// status = mach_vm_protect(mach_task_self(), (mach_vm_address_t)to, size, FALSE,
|
|
// info.protection); if (status != KERN_SUCCESS) return false;
|
|
|
|
return status == KERN_SUCCESS;
|
|
}
|
|
|
|
bool MacOSX::initialize() {
|
|
task_set_exception_ports(
|
|
mach_task_self(), EXC_MASK_BAD_INSTRUCTION,
|
|
MACH_PORT_NULL, // m_exception_port,
|
|
EXCEPTION_DEFAULT, 0
|
|
);
|
|
// first reached here
|
|
struct sigaction action = {};
|
|
action.sa_sigaction = &signalHandler;
|
|
action.sa_flags = SA_SIGINFO;
|
|
|
|
return sigaction(SIGILL, &action, NULL) == 0 && sigaction(SIGTRAP, &action, NULL) == 0;
|
|
}
|
|
|
|
#endif
|