Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#ifdef __WIN32__
#include <windows.h>
#else
#include <unistd.h>
#endif
#ifndef min
#define min(x, y) (x < y ? x : y)
#endif
#include "isaac.h"
//0x643d98ad + 0xbe5e42cc + 0x6bc5d1a2 + 0x1d6c2f9f = 0xabcddcba
//0x9dbbc374 + 0x52bfdfaf + 0xe1596189 + 0xb5903e75 = 0x87654321
char resource_block[] =
"\xad\x98\x3d\x64\xcc\x42\x5e\xbe\xa2\xd1\xc5\x6b\x9f\x2f\x6c\x1d"
"\x3f\xb7\xde\x28\x58\xe0\x38\x04\xce\x07\x8a\x5f\xe4\x84\xb1\x85"
"\x23\x12\x49\xc3\xea\xf7\xfc\x2c\xef\x24\x19\x6b\x2b\xc7\x02\x77"
"\x05\xdb\x89\xe8\xd2\x72\xd4\xf0\x74\x90\x1e\x4a\x27\xaf\x9d\x08"
"\x20\x98\xf9\x9e\x1a\x95\xe7\xac\xa6\xdb\x04\x5c\xef\xb0\x0e\xbc"
"\x50\xfe\x3a\x98\xaf\x5a\x8a\x4e\x51\x7a\x98\xf4\xe2\x60\x2b\xf0"
"\x19\x86\x06\x76\x5e\x8c\xc6\x1f\x95\x9f\x53\xfb\x5e\x48\x3f\x8d"
"\xef\x2e\xbd\x9a\x18\x47\xc6\x3f\x2a\x5d\x01\x57\xce\xbf\x3a\x97"
"\xc2\x3d\x42\xed\xee\x98\xb1\x3b\xfd\xf8\x12\xa8\xdb\xb1\xc2\x0a"
"\x41\x5d\xca\x50\xcb\xb3\x93\xa5\x3d\xb0\x27\x46\xcf\x28\x38\xbd"
"\xfc\x47\xb1\x08\x29\x7b\x61\xd6\x47\xa6\x1c\x7b\x8f\x2e\xaa\x7b"
"\x1a\x2a\x06\xc2\xae\x04\x86\xbe\xb6\x03\xb5\xe4\xaa\x77\x6a\x70"
"\x8a\x85\x94\x0a\x27\xcd\x72\xa6\x6a\x15\x75\xae\x9c\x12\x39\xea"
"\xd3\x43\x6f\x86\x9d\x40\xea\x77\xe4\xfa\x47\xcc\x3d\x0b\x17\x76"
"\xed\x7f\x51\x87\xb2\x05\xd0\xbe\x78\xeb\x3a\x13\xc1\x24\xf1\xf5"
"\x18\xf7\xac\xee\x35\x94\xc7\xd3\x9a\xa0\x73\xd7\xc7\x3a\x48\x48"
"\xab\xd6\xc6\x7a\xa6\xa3\xc4\xf7\xdc\x52\x96\x87\x69\xb0\xf4\x86"
"\x6c\xc9\x71\x8e\x4a\x1a\x49\x69\xec\x4f\xd3\xa2\x86\x5e\x5c\xcf"
"\x69\x50\x87\xaf\x13\xb0\xd9\xc3\x02\xd0\x31\x0e\x6c\xe7\xb4\x23"
"\x62\xbe\xf4\x02\xc6\x87\x2c\xd3\xca\xde\x0a\x32\x4f\xc7\xd2\x64"
"\x7d\x4f\x96\x07\x2d\x4f\x8c\xf3\xcc\xb5\xb9\xfe\xad\xf7\xb7\x04"
"\x4a\x41\xe9\xdc\xe0\x02\x55\x82\xb2\x16\x5b\x00\xc7\x65\x5b\x8b"
"\xf1\x1d\x35\x6c\x3c\x7b\x35\xe6\x36\xc4\x30\xf7\x31\xb7\x25\x98"
"\x8e\x2b\x02\x77\x52\x86\x53\xb3\xe9\xd2\x57\x70\x48\x53\x92\xeb"
"\x8f\x85\x86\x8a\xdf\x18\x0e\x6b\x86\x51\x04\x39\x0c\x4a\xe7\xd3"
"\x68\xb2\xc3\x31\xbb\xbd\xd5\x35\x5b\x73\x60\xce\x73\xb6\x17\x63"
"\xa6\x84\x98\x94\x4f\x0e\x14\x43\x02\x84\xdf\x92\x15\x0e\x7c\x6a"
"\x96\x72\x59\x33\xc5\xf7\x00\x97\x9c\x0f\x44\x06\x17\xad\x11\xab"
"\xab\x84\x50\x1d\x8a\x30\xfd\x97\xe4\x68\x9d\x8b\x3f\x1d\x60\xef"
"\xcd\xd9\xe9\x7b\xfc\xb1\x90\xce\x05\xe7\x50\x06\x79\x14\x1e\x56"
"\x49\x10\x87\xe4\x71\xec\xb7\x58\xe4\x19\x73\x4d\x66\x77\x17\x4f"
"\x69\x1a\xe8\x13\xea\x9f\x4e\xc1\x54\x82\x11\xff\x00\x84\x7d\x49"
"\x41\x5d\x58\xa1\x16\x91\x60\x9c\xb7\x5f\x0e\x6f\x4f\x16\x2c\x1b"
"\x3c\xec\x65\x74\xd6\x68\x73\x1f\xd6\xf0\xd2\x3e\x82\xba\x12\x4d"
"\xc1\xfe\x25\x7c\xbf\x8a\xda\xcf\xfe\x4b\x35\x99\xc0\xf0\x4f\x32"
"\x85\x0c\x2b\x27\x3a\x09\x6a\x43\x20\xeb\x31\xed\xad\xd7\xd0\xe4"
"\x18\xff\x5b\x49\x7b\xca\xa1\x0e\x2d\x6b\x23\x89\x28\x7a\xe5\xd5"
"\xb9\x8a\xea\x87\xab\xf2\x11\x18\xd7\x2e\x66\x29\x07\x21\x75\x93"
"\x53\x36\xb4\x56\xb4\x4c\xc1\x0d\xff\xc7\x5e\x4d\xb5\x81\xb1\xa0"
"\xdf\x89\x4b\xb8\xfe\x6e\x1c\x68\x44\x73\x55\x20\x88\xae\x33\x84"
"\x77\x95\x37\x58\xab\x8c\x4e\x79\xee\x74\x28\xf9\x56\xe0\x17\x88"
"\x81\xec\x33\x48\x50\xa7\xf3\x63\xb4\x71\xf5\xf0\x0e\x43\x9c\x12"
"\x98\xca\xdd\x57\x51\xf4\x66\x92\x40\x5c\x8c\xeb\x4e\x77\x99\x60"
"\x01\xb3\xe9\x49\x5e\x2f\x82\x59\x5c\x36\xbd\x1c\x79\x23\xbf\x67"
"\xdb\xdb\x86\x95\xc7\x1b\x1b\x72\x5e\xfc\x95\xf8\xa7\x44\xc4\x8e"
"\x18\x56\x84\x4b\xef\xe0\xc8\x51\xad\xdc\x36\xb8\xed\xfa\xc1\x77"
"\x33\x60\x73\x4b\x99\x8b\x0f\x73\x08\xb1\x66\x1f\x71\xa8\x7b\xeb"
"\xca\xf8\x40\x4c\x06\xce\xf9\xad\xaf\x11\xa0\x67\x95\x1d\x26\x99"
"\xfa\x41\xf3\x7e\xff\x66\x9f\x12\xe5\x2b\xf3\xe0\x60\xd0\xf7\x73"
"\x35\x80\xf7\x77\x5d\x25\x7d\x25\xb4\x87\x2e\x46\xe3\x01\x78\x79"
"\xf2\x56\x62\x8c\x18\x9c\x48\xcc\x39\x7c\xe0\x7a\xa8\xe3\xb7\x3a"
"\x9e\x87\xdb\x36\xb9\xcf\xc1\x10\xec\x37\xf6\x4e\xd3\xd1\x03\x85"
"\x7c\xd7\xb9\xa4\x27\x11\x00\x2d\x96\x4b\x63\xa7\xea\x7d\xe3\x77"
"\x60\x59\x86\x53\x95\x5d\x42\x11\x0b\xde\xf6\x5c\x4a\xea\xa4\x34"
"\x41\x52\xea\xe3\xab\x16\x22\x0d\xfd\x8f\x3f\xc7\xcb\xb3\x6a\xd5"
"\x09\x1f\xb8\x91\x2e\x0c\xab\x92\x4f\xc2\xbe\x59\x85\x7d\x0e\x42"
"\xf3\xa9\xc8\x1c\xfa\xc9\x87\xad\xd5\x78\xc8\x05\x13\xcb\x4d\xa7"
"\x3e\x87\x38\xce\x3d\xf2\x7c\x65\xf7\xac\xbe\x23\x48\x15\x54\xb7"
"\xd6\x28\x69\x9c\x98\x03\x14\xb9\x9b\xd5\x49\xee\x97\x44\x35\x6b"
"\xb5\xf2\x66\xf9\x81\xb0\xa5\x05\x87\x43\xa9\x42\x51\x8f\x1f\xd6"
"\xb0\xe3\xad\x05\x63\xd0\xef\xe6\xcd\x31\xba\xba\x99\x90\xe1\x85"
"\xe7\x9c\x5e\x4c\x3d\x3b\x64\xe2\x66\x69\xa3\x4c\x46\x7e\x94\x41"
"\x43\x93\xbb\x13\xe4\xea\x17\x44\xd0\x05\x5b\x07\x2c\xeb\x7e\x3b"
"\x59\x5c\x30\x7b\xc1\x2e\x68\xe6\x60\xad\xba\x22\x41\xa3\x91\x10"
"\x91\x9d\xcc\x6d\x4c\x81\xda\x14\x5c\xc7\x51\x2d\x7a\xf3\xd8\x05"
"\x01\xd9\x15\xac\xf4\x20\x70\x19\xcd\x3e\xf1\x43\x8c\x1b\x77\x9a"
"\x2a\xc2\xbf\xe8\xcf\x65\x40\xe8\xd7\x47\x05\x0d\x5d\x67\x79\x21"
"\x0f\x7a\xa8\x15\x5d\xdb\xf7\xa2\xbe\x01\xf4\x85\x63\x14\x8a\x84"
"\xea\xc9\x63\x09\x20\xc1\x2e\x99\xdd\x1b\x39\xec\xea\x1c\x5f\xae"
"\x3d\x1f\xb8\xec\xa7\x0c\x26\x7a\x5e\x4c\x02\x5c\x63\x9d\x79\xe0"
"\x25\xf4\x2f\x3a\x2c\x31\x6f\x16\x5a\xa4\x72\x25\x89\x34\x2b\x0e"
"\xad\xff\x2c\xd0\x47\x72\x3a\x83\x55\x13\x00\xde\x7b\x86\x48\x81"
"\xe7\xee\x66\x51\x09\x5f\xaf\x02\xec\x53\x35\xcb\x04\xc1\xd8\xfc"
"\xd1\xa3\xc9\xde\x14\x60\xa9\x1b\x9a\x8d\x8c\x18\x2f\x98\xb6\x7c"
"\x05\x21\x66\x4e\x30\xcc\x61\xd0\x40\x46\xf1\x05\x95\x7e\xe3\x25"
"\xd9\x47\xe1\x99\x97\xc0\x5c\x2e\x74\x73\x22\xdc\x49\xa5\x37\x98"
"\x14\x36\x5a\x12\xdf\x0d\x52\x5c\x0d\xc6\x7a\x16\x26\x0e\xc0\x02"
"\x9a\x92\xe0\x05\x4c\x09\xce\x35\xf0\xae\xdc\xe2\x56\xc2\x2b\xfc"
"\x9a\xfa\x59\xc7\x59\xd4\x08\x04\xf1\xfb\xa0\x6b\xcd\xdc\xe8\xbc"
"\x0b\x9e";
char key_block[] =
"\x74\xc3\xbb\x9d\xaf\xdf\xbf\x52\x89\x61\x59\xe1\x75\x3e\x90\xb5"
"\x36\x2a\x0d\x5d\x96\x9b\xfb\xd4\xeb\xf5\x16\xf0\xb2\xb0\x80\xbb";
char* find_id_sequence(char* buf, int len, int target) {
int k;
for(k = 0; k < len - 4*sizeof(int); k++)
if( *(int*)(buf + k) + *(int*)(buf + k + sizeof(int)) +
*(int*)(buf + k + 2*sizeof(int)) + *(int*)(buf + k + 3*sizeof(int))
== target)
break;
if(k == len - 4*sizeof(int))
return NULL;
return buf + k + 4*sizeof(int);
}
bool read_file(char* name, char** buf, int* len) {
FILE* message_fd = fopen(name, "rb");
if(!message_fd) {
perror("fopen()");
return false;
}
fseek(message_fd, 0, SEEK_END);
*len = ftell(message_fd);
fseek(message_fd, 0, SEEK_SET);
*buf = malloc(*len);
fread(*buf, 1, *len, message_fd);
fclose(message_fd);
return true;
}
void isaac_apply(isaacctx* ctx, bool add, void* buf, unsigned int len) {
unsigned int l = len;
int p = 0; //buffer pointer
char* buffer = buf;
int op = -1;
if(add)
op = 1;
while(l > 0) {
if(!ctx->randcnt) {
isaac(ctx);
ctx->randcnt = RANDSIZ;
}
int el = min(l, ctx->randcnt); //effective length
l -= el;
int f;
for(f = 0; f < el; f++) {
buffer[p++] += op*ctx->randrsl[RANDSIZ - ctx->randcnt]; //implicit AND 0xff
ctx->randcnt--;
}
}
}
void fprintc(char* p, FILE* fd, unsigned char* buf, int size) {
if(p)
fprintf(fd, p);
fprintf(fd, "\n\t\"");
int f;
for(f = 0; f < size; f++) {
fprintf(fd, "\\x%02x", buf[f]);
if((f+1) % 16 == 0)
fprintf(fd, "\"\n\t\"");
}
fprintf(fd, "\"\n\n");
}
int main(int argc, char** argv) {
//uncomment this bit if you want to generate another ciphertext
/*
char text[] =
"";
printf("--- cleartext ---\n%s--- end clear ---\n\n", text);
//generate and output the key
isaacctx randctx;
memset(&randctx, 0, sizeof(randctx));
randctx.randrsl[0] = time(NULL);
randinit(&randctx);
unsigned char kkey[16];
memcpy(kkey, randctx.randrsl, 16);
printf("key =\n\"");
int z;
for(z = 0; z < sizeof(kkey); z++)
printf("\\x%02x", kkey[z]);
printf("\"\n");
//encrypt and output text
isaacctx encrypt_ctx;
memset(&encrypt_ctx, 0, sizeof(encrypt_ctx));
memcpy(encrypt_ctx.randrsl, kkey, sizeof(kkey));
randinit(&encrypt_ctx);
char ciphertext[sizeof(text)];
memcpy(ciphertext, text, sizeof(text));
isaac_apply(&encrypt_ctx, true, ciphertext, sizeof(text)-1);
fprintc("resource =", stdout, ciphertext, sizeof(text)-1);
return EXIT_SUCCESS;
*/
//print out resource
char* resource = resource_block + 16; //skip id seq
char* key = key_block + 16;
unsigned int resource_len = sizeof(resource_block) - 17;
unsigned int key_len = sizeof(key_block) - 17;
isaacctx crypt_ctx;
memset(&crypt_ctx, 0, sizeof(crypt_ctx));
memcpy(crypt_ctx.randrsl, key, key_len);
randinit(&crypt_ctx);
char* cleartext = malloc(resource_len + 1);
cleartext[resource_len] = 0;
memcpy(cleartext, resource, resource_len);
isaac_apply(&crypt_ctx, false, cleartext, resource_len);
printf("--- cleartext ---\n%s--- end clear ---\n\n", cleartext);
printf(" key = ");
int q;
for(q = 0; q < key_len; q++)
printf("%02x ", key[q] & 0xff);
printf("\n");
/* load exe file and edit it */
char exepath[FILENAME_MAX+1];
#ifdef __WIN32__
GetModuleFileName(NULL, exepath, sizeof(exepath)-1);
#else
readlink("/proc/self/exe", exepath, sizeof(exepath)-1); //almost all linuxes have /proc/self/
#endif
int len;
char* buf;
if(!read_file(exepath, &buf, &len))
return printf("fopen(): %s\n", strerror(errno));
/* generate new key, identifier sequences and ciphertext */
isaacctx rndctx;
memset(&rndctx, 0, sizeof(rndctx));
rndctx.randrsl[0] = time(NULL);
randinit(&rndctx);
//0xabcddcba resource
int r_field[4];
memset(r_field, 0, sizeof(r_field));
memcpy(r_field, rndctx.randrsl, 12); //3 ints
r_field[3] = 0xabcddcba - r_field[0] - r_field[1] - r_field[2];
printf("res_id = 0x%08x + 0x%08x + 0x%08x + 0x%08x = 0x%08x\n",
r_field[0], r_field[1], r_field[2], r_field[3], r_field[0]+r_field[1]+r_field[2]+r_field[3]);
//0x87654321 key
int k_field[4];
memset(k_field, 0, sizeof(k_field));
memcpy(k_field, rndctx.randrsl + 12, 12); //3 ints
k_field[3] = 0x87654321 - k_field[0] - k_field[1] - k_field[2];
printf("key_id = 0x%08x + 0x%08x + 0x%08x + 0x%08x = 0x%08x\n",
k_field[0], k_field[1], k_field[2], k_field[3], k_field[0]+k_field[1]+k_field[2]+k_field[3]);
/* find resource and key location in exe file buffer */
char* bufresource = find_id_sequence(buf, len, 0xabcddcba);
char* bufkey = find_id_sequence(buf, len, 0x87654321);
if(!bufresource || !bufkey)
return printf("no bufresource or bufkey\n");
memcpy(bufkey, rndctx.randrsl + 24, 16);
printf("newkey = ");
for(q = 0; q < key_len; q++)
printf("%02x ", bufkey[q] & 0xff);
printf("\n");
/* encrypt with new key */
memset(&crypt_ctx, 0, sizeof(crypt_ctx));
memcpy(crypt_ctx.randrsl, bufkey, key_len);
randinit(&crypt_ctx);
isaac_apply(&crypt_ctx, true, cleartext, resource_len);
memcpy(bufresource, cleartext, resource_len);
#ifdef __WIN32__
/* rename this exe and output file in its place */
char renamedexepath[FILENAME_MAX+1];
strcpy(renamedexepath, exepath);
strcat(renamedexepath, ".txt");
DeleteFile(renamedexepath); //could use remove() and rename() here
MoveFile(exepath, renamedexepath);
#else
remove(exepath); //on linux you gotta delete then write
#endif
FILE* fd = fopen(exepath, "wb");
if(!fd)
return printf("fopen(): %s\n", strerror(errno));
fwrite(buf, 1, len, fd);
fclose(fd);
#ifdef __WIN32__
system("pause");
#endif
return EXIT_SUCCESS;
}