Skip to content

Instantly share code, notes, and snippets.

@samdmarshall
Last active January 1, 2016 04:09
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samdmarshall/8edb5e246fcbb09ce6e7 to your computer and use it in GitHub Desktop.
Save samdmarshall/8edb5e246fcbb09ce6e7 to your computer and use it in GitHub Desktop.
//
// main.c
// c4pture
//
// Created by Sam Marshall on 12/22/13.
// Copyright (c) 2013 Sam Marshall. All rights reserved.
//
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <CommonCrypto/CommonDigest.h>
#define USE_TAIG_SPACE
#ifdef USE_TAIG_SPACE
#define WRITE_OFFSET 0x8faeac
#define WRITE_LENGTH 0xd134f5
#else
#define WRITE_OFFSET 0x1a842d
#define WRITE_LENGTH 0x6d24ff
#endif
static char defaultHash[CC_SHA1_DIGEST_LENGTH] = {0xe2, 0x55, 0x94, 0x28, 0x4e, 0x87, 0xd2, 0xaf, 0xdb, 0x11, 0x1a, 0x6d, 0x45, 0xcb, 0x0c, 0xc5, 0x08, 0x79, 0x8f, 0x8c};
struct FileBuffer {
char *data;
uint32_t length;
};
struct FileBuffer* CreateBufferFromFile(char *path) {
struct FileBuffer *buffer = calloc(0x1, sizeof(struct FileBuffer));
struct stat fs;
int statResult = stat(path, &fs);
if (statResult == 0x0) {
int fd = open(path, O_RDWR);
if (fd) {
buffer->length = (uint32_t)fs.st_size;
buffer->data = calloc(0x1, sizeof(char)*buffer->length);
read(fd, buffer->data, buffer->length);
close(fd);
}
}
return buffer;
}
char* SHA1HashOfFileAtPath(char *path) {
char *hashBytes = calloc(0x1, CC_SHA1_DIGEST_LENGTH);
struct FileBuffer *file = CreateBufferFromFile(path);
CC_SHA1(file->data, file->length, (unsigned char *)hashBytes);
free(file);
return hashBytes;
}
bool RemoveTaiGPayload(char *path) {
bool status = false;
struct stat fs;
int statResult = stat(path, &fs);
if (statResult == 0x0) {
int fd = open(path, O_RDWR);
if (fd) {
// going after taig
lseek(fd, 0x8faeac, SEEK_SET);
uint32_t taigLength = 0xd134f5;
uint32_t *zero = calloc(0x1, taigLength);
size_t length = 0;
length = write(fd, zero, taigLength);
free(zero);
if (length != -1) {
status = true;
}
close(fd);
}
}
return status;
}
bool AssignNewCydia(char *path) {
bool status = false;
struct stat fs;
int statResult = stat(path, &fs);
if (statResult == 0x0) {
int fd = open(path, O_RDWR);
if (fd) {
// pointing cydia at taig space
uint32_t newPayloadSpace = WRITE_OFFSET;
uint32_t newPayloadLength = WRITE_LENGTH;
lseek(fd, 0x56c, SEEK_SET);
size_t length;
length = write(fd, &newPayloadSpace, sizeof(uint32_t));
length = write(fd, &newPayloadLength, sizeof(uint32_t));
if (length != -1) {
status = true;
}
close(fd);
}
}
return status;
}
bool WriteNewPayload(char *path, struct FileBuffer *payload) {
bool status = false;
struct stat fs;
int statResult = stat(path, &fs);
if (statResult == 0x0) {
int fd = open(path, O_RDWR);
if (fd) {
// new payload time!
lseek(fd, WRITE_OFFSET, SEEK_SET);
size_t length = 0x0;
length = write(fd, payload->data, payload->length);
if (length != -1) {
status = true;
}
close(fd);
}
}
return status;
}
void ReleaseFileBuffer(struct FileBuffer *buffer) {
free(buffer->data);
free(buffer);
}
int main(int argc, const char * argv[]) {
if (argc < 0x3) {
printf("To patch evasion, specify the path to the 'evasi0n 7' app and the path to the tar.gz of your payload.\n");
printf("./c4pture [evasion path] [payload path]\n");
} else if (argc == 0x3) {
bool patchSuccessful = false;
bool canPatch = true;
char *evasionPath = (char*)argv[0x1];
char *payloadPath = (char*)argv[0x2];
struct FileBuffer *payload = CreateBufferFromFile(payloadPath);
if (payload->length) {
if (payload->length > WRITE_LENGTH) {
canPatch = false;
}
}
if (canPatch) {
char *evasionHash = SHA1HashOfFileAtPath(evasionPath);
int result = memcmp(evasionHash, defaultHash, CC_SHA1_DIGEST_LENGTH);
free(evasionHash);
if (result == 0x0) {
bool taigRemoval = RemoveTaiGPayload(evasionPath);
if (taigRemoval) {
bool newCydia = AssignNewCydia(evasionPath);
if (newCydia) {
bool payloadStatus = WriteNewPayload(evasionPath, payload);
if (payloadStatus) {
patchSuccessful = true;
}
}
}
if (patchSuccessful) {
printf("successfully patched evasi0n7!\n");
} else {
printf("failed to patch evasi0n.\n");
}
} else {
printf("you are not using a supported version of evasi0n!\n");
}
} else {
printf("the payload size is too large to fit.\n");
}
ReleaseFileBuffer(payload);
}
return 0x0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment