10100110
11100000
11111011
01010010
11110000
/*
______________
Date:
	2006-02-27

______________
Author:
	Anna Wiejak
	anias@popoludnica.pl


______________
Buzzwords:
	perl2exe, decryption, decrypt, decompilation, decompile, cracking, crack, security, secure

______________
Description:

This code should recover the perl code from an executable file,
created by a crispy-fresh version of perl2exe ("Perl2Exe V8.70 for Linux").
The "Perl2Exe V8.70 for Windows" unfortunately (?) lacks a rc4 encryption (surprise!).

For all earlier versions the procedure is simpler (each previous version lacks one or more feature, added just to confuse and amuse ;) ) and is documented or explained elsewhere.

______________
Purpose:
Estimation if the solution is suitable for intellectual property protection and code obfuscation.

______________
References:

* http://p.ulh.as/xploitsdb/NT/6009.html  (Perl2Exe V5-V6*)
* http://www.indigostar.com/perl2exe.htm

*/


#include <openssl/rc4.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

char *get_from_file(int, long, long);
char *encrypt_string(char *, int, char *, int);


main(int argc, char *argv[]) {
int offset;
long size;
int i;
int fhandle;

if(argc!=2) {
	printf("Usage: %s <filename>\n",argv[0]);
	exit(1);
}

fhandle=open(argv[1],O_RDONLY);

if(fhandle==-1) {
	printf("Error opening the file: %s\n",argv[0]);
	exit(1);
}

//let's generate the key used later
char *base_key=encrypt_string("For more information visit www.indigostar.com",strlen("For more information visit www.indigostar.com"),"continue",strlen("continue"));


//IN CASE OF ANY PROBLEMS JUST CRASH GRACEFULLY! ;)

//read 0x100 bytes from the end of a file
//decrypt it
offset=lseek(fhandle,-0x100,SEEK_END);
char *header_indata=malloc(0x100);
read(fhandle,header_indata,0x100);
char *header_decoded=encrypt_string(header_indata,0x100,base_key,strlen(base_key));

//read the subheader - use the size given in the header 
//decrypt it
sscanf(strstr(header_decoded,"SIZE=")+5, "%ld",&size); 
lseek(fhandle,offset-size,SEEK_SET);
char *subheader_indata=malloc(size+1);
subheader_indata[size]='\0';
read(fhandle,subheader_indata,size);
char *subheader_decoded=encrypt_string(subheader_indata,size,base_key,strlen(base_key));

//walk the entries/lines in subheader
//we assume the format is correct here..
//no error checking routines
char *rest=strtok(subheader_decoded,"\n");
int fileoffset=0;

while(rest) {
  int size_local=strstr(rest,";SIZE")-rest-5; //filename length
  char *filename=malloc(size_local+1);
  strncpy(filename,rest+5,size_local);

  long filesize;
  int fileenc;
  sscanf(rest+size_local+11,"%ld;ENC=%d",&filesize,&fileenc); 
  if(strncmp(filename,"p2x",3)!=0) { //omit all the p2x entries, we don't care
				     //get and decrypt data from the file
	char *outbuf=encrypt_string(get_from_file(fhandle,fileoffset,filesize), filesize,base_key,strlen(base_key));

	printf("***** %s - %ld - %d\n",filename, filesize, fileenc);
	for(i=0;i<=filesize;i++) {
	  printf("%c",outbuf[i]);
	}

  }
  fileoffset+=filesize;
  rest=strtok(NULL,"\n");
}


close(fhandle);

}


char *get_from_file(int fhandle, long fileoffset, long filesize) {
char *buffer=NULL;

buffer=malloc(filesize);
lseek(fhandle,fileoffset,SEEK_SET);
read(fhandle,buffer,filesize);

return(buffer);
}

char *encrypt_string(char *string, int string_length, char *key, int key_length) {
char *cipher=NULL;
RC4_KEY S;

RC4_set_key(&S, key_length, key);
cipher=malloc(string_length);
RC4(&S, string_length, string, cipher);

return(cipher);
}