-
-
Save samdmarshall/8edb5e246fcbb09ce6e7 to your computer and use it in GitHub Desktop.
This file contains 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
// | |
// 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