I have been getting the virtual memory address slide amount of the application by
#include <mach-o/dyld.h>
_dyld_get_image_vmaddr_slide(0);
_dyld_get_image_vmaddr_slide: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dyld.3.html
However, on Palera1n (v1.4.1), "/usr/lib/substitute-loader.dylib" seems to be the 0th image index.
Therefore, the argument to _dyld_get_image_vmaddr_slide must be 1.
uint64_t getRealOffset(uint64_t offset) {
return _dyld_get_image_vmaddr_slide(1) + offset;
// return _dyld_get_image_vmaddr_slide(0) + offset;
}
With Framework
If the image index is not fixed as in Unity, it can be done as follows
#include <string.h>
#include <stdlib.h>
uint64_t getRealOffset$Palera1n(const char *image_name, uint64_t offset) {
if (image_name == NULL) {
const char *progname = getprogname();
if (progname) {
return getRealOffset$Palera1n(progname, offset);
}
return _dyld_get_image_vmaddr_slide(1) + offset;
}
const uint32_t image_count = _dyld_image_count();
for (int i = 0; i < image_count; ++i) {
if (strstr(_dyld_get_image_name(i), image_name)) {
return _dyld_get_image_vmaddr_slide(i) + offset;
}
}
// error...
return offset;
}
getprogname: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/getprogname.3.html
Example argument for image_name:
// PUBG
getRealOffset$Palera1n("ShadowTrackerExtra", 0x100345678);
// or
getRealOffset$Palera1n(NULL, 0x100345678);
// YouTube
getRealOffset$Palera1n("YouTube", 0x100345678);
// or
getRealOffset$Palera1n(NULL, 0x100345678);
// Unity - (e.g. Survivor!.io)
getRealOffset$Palera1n("UnityFramework", 0x345678);
Conclusion
The following may only work with Palera1n or only with the current version of Palera1n.
const uint64_t slide = _dyld_get_image_vmaddr_slide(1);
MSHookFunction((void *)(0x100345678 + slide), ...);
MSHookFunction((void *)(0x100789ABC + slide), ...);
It might be better to specify by image name so that it works without worrying about the argument to _dyld_get_image_vmaddr_slide.
const uint64_t slide = getRealOffset$Palera1n("ImageName", 0x0);
if (slide) {
MSHookFunction((void *)(0x100345678 + slide), ...);
MSHookFunction((void *)(0x100789ABC + slide), ...);
}