Last active
January 14, 2018 19:32
-
-
Save arthurdapaz/2b9ffa63860f0f693f220d0c3111197f to your computer and use it in GitHub Desktop.
MemPatcher magic lines itself
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "MemPatcher.h" | |
vm_object_offset_t calcAddress(vm_object_offset_t offset) | |
{ | |
const struct mach_header *mach; | |
mach = _dyld_get_image_header(0); | |
if (mach->flags & MH_PIE) | |
{ | |
vm_object_offset_t slide = _dyld_get_image_vmaddr_slide(0); | |
return (slide + offset); | |
} | |
else | |
return offset; | |
} | |
kern_return_t readAddress(vm_object_offset_t address, unsigned char *outData, size_t size) | |
{ | |
address &= ~1; | |
mach_port_t port = mach_task_self(); | |
vm_size_t sz; | |
return vm_read_overwrite(port, address, size, (vm_object_offset_t)outData, &sz); | |
} | |
kern_return_t writeAddress(vm_object_offset_t address, unsigned char *inData, size_t size) | |
{ | |
kern_return_t status; | |
mach_port_t port = mach_task_self(); | |
address &= ~1; | |
vm_object_offset_t text_base = address; | |
status = vm_protect(port, text_base, size, false, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY); | |
if (status != KERN_SUCCESS) | |
return status; | |
status = vm_write(port, address, (vm_object_offset_t)inData, size); | |
if (status != KERN_SUCCESS) | |
return status; | |
return vm_protect(port, text_base, size, false, VM_PROT_READ | VM_PROT_EXECUTE); | |
} | |
@implementation MemPatcher | |
- (id) initAddress:(vm_object_offset_t)addr data:(uint)data | |
{ | |
self = [super init]; | |
if (self) | |
{ | |
patchAddr = calcAddress(addr); | |
if (!(((data & 0xFFFF8000) + 0x8000) & 0xFFFF7FFF)) { | |
patchSize = sizeof(unsigned short); | |
data = OSSwapInt16(data); | |
} | |
else { | |
data = OSSwapInt32(data); | |
patchSize = sizeof(int); | |
} | |
patchData = (unsigned char*)malloc(sizeof(unsigned char) * patchSize); | |
origData = (unsigned char*)malloc(sizeof(unsigned char) * patchSize); | |
memcpy(patchData, &data, patchSize); | |
readAddress(patchAddr, origData, patchSize); | |
} | |
return self; | |
} | |
+ (instancetype) patch:(vm_object_offset_t)addr data:(uint)data | |
{ | |
MemPatcher *mp = [[MemPatcher alloc] initAddress:addr data:data]; | |
return mp; | |
} | |
- (bool) apply | |
{ | |
return writeAddress(patchAddr, patchData, patchSize); | |
} | |
- (bool) reset | |
{ | |
return writeAddress(patchAddr, origData, patchSize); | |
} | |
+ (vm_object_offset_t)calculate:(vm_object_offset_t)offset | |
{ | |
return calcAddress(offset); | |
} | |
- (void)dealloc | |
{ | |
free(patchData); | |
free(origData); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
patchAddr, patchSize, origData are not declared :/ @arthurdapaz