#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <EXTERN.h>
#include <perl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define SIZE 4096
static
char
* text;
static
const
char
my_name[] =
"Module::Crypt"
;
static
const
char
author[] =
"Alessandro Ranellucci <aar@cpan.org>"
;
static
const
char
cpright[] =
"Copyright (c) 2005"
;
static
unsigned
char
stte[256], indx, jndx, kndx;
void
stte_0(
void
)
{
indx = jndx = kndx = 0;
do
{
stte[indx] = indx;
}
while
(++indx);
}
void
key(
void
* str,
int
len)
{
unsigned
char
tmp, * ptr = (unsigned
char
*)str;
while
(len > 0) {
do
{
tmp = stte[indx];
kndx += tmp;
kndx += ptr[(
int
)indx % len];
stte[indx] = stte[kndx];
stte[kndx] = tmp;
}
while
(++indx);
ptr += 256;
len -= 256;
}
}
void
arc4(
void
* str,
int
len)
{
unsigned
char
tmp, * ptr = (unsigned
char
*)str;
while
(len > 0) {
indx++;
tmp = stte[indx];
jndx += tmp;
stte[indx] = stte[jndx];
stte[jndx] = tmp;
tmp += stte[indx];
*ptr ^= stte[tmp];
ptr++;
len--;
}
}
unsigned rand_mod(unsigned mod)
{
unsigned rnd, top = RAND_MAX;
top -= top % mod;
while
(top <= (rnd =
rand
()))
continue
;
rnd = 1.0*mod*rnd/(1.0+top);
return
rnd;
}
char
rand_chr(
void
)
{
return
(
char
)rand_mod(1<<(
sizeof
(
char
)<<3));
}
int
noise(
char
* ptr, unsigned min, unsigned xtra,
int
str)
{
if
(xtra) xtra = rand_mod(xtra);
xtra += min;
for
(min = 0; min < xtra; min++, ptr++)
do
*ptr = rand_chr();
while
(str && !
isalnum
((
int
)*ptr));
if
(str) *ptr =
'\0'
;
return
xtra;
}
static
int
offset;
void
prnt_bytes(
char
* o,
char
* ptr,
int
m,
int
l,
int
n)
{
int
i;
l += m;
n += l;
for
(i = 0; i < n; i++) {
if
((i & 0xf) == 0)
strcat
(o,
"\n\t\""
);
sprintf
(o,
"%s\\%03o"
, o, (unsigned
char
)((i>=m) && (i<l) ? ptr[i-m] : rand_chr()));
if
((i & 0xf) == 0xf)
strcat
(o,
"\""
);
}
if
((i & 0xf) != 0)
strcat
(o,
"\""
);
offset += n;
}
void
prnt_array(
char
* o,
void
* ptr,
char
* name,
int
l,
char
* cast)
{
int
m = rand_mod(1+l/4);
int
n = rand_mod(1+l/4);
int
a = (offset+m)%l;
if
(cast && a) m += l - a;
char
tmpop[1000];
strcat
(o,
"\n"
);
sprintf
(tmpop,
"#define %s_z %d"
, name, l);
strcat
(o, tmpop);
strcat
(o,
"\n"
);
sprintf
(tmpop,
"#define %s (%s(&data[%d]))"
, name, cast?cast:
""
, offset+m);
strcat
(o, tmpop);
prnt_bytes(o, ptr, m, l, n);
}
void
read_script (SV* script)
{
STRLEN len;
char
* mytext = SvPV(script, len);
int
l;
l =
strlen
(mytext);
text =
malloc
(l + SIZE);
strcpy
(text, mytext);
text =
realloc
(text, l + SIZE + 1);
text[l] =
'\0'
;
}
MODULE = Module::Crypt PACKAGE = Module::Crypt
SV *
wr(SV* script)
PROTOTYPE: $
CODE:
read_script(script);
char
pswd[256];
int
pswd_z =
sizeof
(pswd);
int
text_z =
strlen
(text) + 1;
int
indx;
int
numd = 0;
int
done = 0;
srand
((unsigned)
time
(NULL)^(unsigned)getpid());
pswd_z = noise(pswd, pswd_z, 0, 0); numd++;
stte_0();
key(pswd, pswd_z);
arc4(text, text_z); numd++;
char
* o =
malloc
(
strlen
(text) +
strlen
(text)*24 + SIZE);
o[0]=
'\0'
;
strcat
(o,
"static char data [] = "
);
do
{
done = 0;
indx = rand_mod(1);
do
{
switch
(indx) {
case
0:
if
(pswd_z>=0) {prnt_array(o, pswd,
"pswd"
, pswd_z, 0); pswd_z=done=-1;
break
;}
case
1:
if
(text_z>=0) {prnt_array(o, text,
"text"
, text_z, 0); text_z=done=-1;
break
;}
}
indx = 0;
}
while
(!done);
}
while
(numd+=done);
strcat
(o,
"/* End of data[] */;\n"
);
RETVAL = newSVpv(o, 0);
OUTPUT:
RETVAL