/*
______________
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);
}
|