Skip to content

Instantly share code, notes, and snippets.

@winocm
Created March 26, 2012 02:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save winocm/2202495 to your computer and use it in GitHub Desktop.
Save winocm/2202495 to your computer and use it in GitHub Desktop.
kernel stuff for ARM XNU
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdio.h>
#include <unistd.h>
#include <CoreFoundation/CoreFoundation.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach/mach.h>
mach_port_t kernel_task = 0; /* pid 0 */
int main(int argc, char** argv)
{
kern_return_t ret;
uint32_t i, sz;
pointer_t buf;
vm_address_t addr;
uint8_t *oldp, *patch;
size_t b0, b1;
ret = task_for_pid(mach_task_self(), 0, &kernel_task);
if(ret) {
printf("task_for_pid returned %x: missing task-for-pid kernel patch or wrong entitlements\n", ret);
return -1;
}
addr = 0x80000000;
FILE *fp = fopen("kernel_dump.bin", "wb+");
if(!fp) {
printf("cannot open file.\n");
return -1;
};
while(addr < (0x80002000 + 0x1F00000))
{
vm_read(kernel_task, addr, 2048, &buf, &sz);
if(!buf || sz == 0)
continue;
uint8_t* p = (uint8_t*) buf;
fwrite(p, 2048, 1, fp);
addr += 2048;
}
fclose(fp);
printf("done dumping\n");
return -1;
}
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdio.h>
#include <unistd.h>
#include <CoreFoundation/CoreFoundation.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach/mach.h>
mach_port_t kernel_task = 0; /* pid 0 */
static inline void hex_to_bytes(const char* hex, uint8_t** buffer, size_t* bytes) {
*bytes = strlen(hex) / 2;
*buffer = (uint8_t*) malloc(*bytes);
size_t i;
for(i = 0; i < *bytes; i++) {
uint32_t byte;
sscanf(hex, "%2x", &byte);
(*buffer)[i] = byte;
hex += 2;
}
}
kern_return_t
kr_write(mach_port_t p, void* addr, uint8_t *value, uint32_t size)
{
kern_return_t ret;
int i;
size -= 1;
for(i = 0; i <= size; i++) {
ret = vm_write(p, (vm_address_t)(addr + i), (vm_address_t)(value + i), 1);
if (ret) {
printf("vm_write into kernel_task failed at byte %d (ret %d)\n", i, ret);
return ret;
} else {
printf("vm_write into kernel_task OK at byte %d of %d\n", i, size);
}
}
return ret;
}
int main(int argc, char** argv)
{
kern_return_t ret;
uint32_t i, sz;
pointer_t buf;
vm_address_t addr;
uint8_t *oldp, *patch;
size_t b0, b1;
if(argc != 3) {
printf("usage: <old_patch> <new_patch>\n");
return -1;
}
hex_to_bytes(argv[1], &oldp, &b0);
hex_to_bytes(argv[2], &patch, &b1);
if(b0 != b1) {
printf("patches must be equal length. %d != %d\n", (int)b0, (int)b1);
return -1;
}
ret = task_for_pid(mach_task_self(), 0, &kernel_task);
if(ret) {
printf("task_for_pid returned %x: missing task-for-pid kernel patch or wrong entitlements\n", ret);
return -1;
}
addr = 0x80002000;
while(addr < (0x80002000 + 0x1F00000))
{
vm_read(kernel_task, addr, 2048, &buf, &sz);
if(!buf || sz == 0)
continue;
uint8_t* p = (uint8_t*) buf;
for(i = 0; i < sz; i++)
{
if (!memcmp(p + i, oldp, b0))
{
printf("Found ptr at %x\n", (uint32_t)addr + i);
kr_write(kernel_task, (void*) (addr + i), patch, b0);
}
}
addr += 2048;
}
printf("done patching\n");
return -1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment