Skip to content

Instantly share code, notes, and snippets.

@benphelps
Created October 22, 2013 19:09
Show Gist options
  • Save benphelps/7106366 to your computer and use it in GitHub Desktop.
Save benphelps/7106366 to your computer and use it in GitHub Desktop.
Memory pattern or signature searching using vm_read on OS X.
// Byte Searching for OS X
// BenPhelps http://benphelps.me/
#include <stdio.h>
#include <stdlib.h>
#include <mach/mach.h>
unsigned int scanMem(task_t wow, mach_vm_address_t start, mach_msg_type_number_t size, unsigned char *signature, int signature_size)
{
unsigned int buffer_size = 0x100000;
int bytes_read = 0;
uint32_t sz;
while (bytes_read <= size)
{
unsigned char buffer[buffer_size];
unsigned int address = bytes_read;
pointer_t buffer_pointer;
vm_read(wow, address, buffer_size, &buffer_pointer, &sz);
// copy over to us
memcpy(buffer, (const void *)buffer_pointer, sz);
// parse 1mb
unsigned int buffer_position = 0;
while (buffer_position <= buffer_size) {
unsigned int signature_start = buffer_position;
unsigned int signature_position = 0;
// parse bytes
while (buffer[signature_start + signature_position] == signature[signature_position]) {
signature_position++;
if(signature_position == signature_size){
return (int) bytes_read + buffer_position;
}
}
buffer_position++;
}
bytes_read+=buffer_size;
}
return 0;
}
int main() {
kern_return_t kern_return;
mach_port_t task;
int pid = 0;
scanf("%d", &pid);
kern_return = task_for_pid(mach_task_self(), pid, &task);
if (kern_return != KERN_SUCCESS)
{
printf("task_for_pid() failed, error %d - %s", kern_return, mach_error_string(kern_return));
exit(1);
}
int signature_size = 4;
unsigned char signature[4] = "\xBB\x8D\x24\x3F";
unsigned int ptr = scanMem(task, 0x1000, 0xffff3000, signature, signature_size);
if (ptr){
printf("%X\n", ptr);
}
else {
printf("Nothing found.\n");
}
return 0;
}
@CMarker
Copy link

CMarker commented Mar 24, 2016

I think you should be using 'vm_deallocate' after the read or use 'vm_read_overwrite' (http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/vm_read.html).

You should also consider zeroing the buffer before copying the results of the read to it incase read count != buffer size (maybe not an issue in release mode depending on compiler?).

@keefo
Copy link

keefo commented Apr 12, 2021

Hi @benphelps

How is the function argument mach_vm_address_t start used here!?

@benphelps
Copy link
Author

benphelps commented Apr 12, 2021

Hi @benphelps

How is the function argument mach_vm_address_t start used here!?

This would have been the start of the address range to scan, however, in current macOS versions (and for a long time now), ASLR has been enabled (Address Space Layout Randomization) system wide, so this method will not work anymore.

You'll need to get a handle to a pid_t and the process's ASLR'd base address.

I'd recommend checking out https://github.com/ItsJustMeChris/m0ch4 for the current methods used to do this kind of thing.

@keefo
Copy link

keefo commented Apr 12, 2021

Thank you @benphelps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment