
#define _ALL_SOURCE

#include <stdio.h>
#include <string.h>
#include <sys/ldr.h>

/* Load and execute a program with an encrypted data segment.
   crypt_data is a pointer to data to XOR with the program data
   segment.

   Return value:

      0		success
     -1		could not load program
     -2		could not decrypt program

 */

static void decrypt(char *program_data, char *crypt_data, unsigned int nbytes)
{
  register int i;
  for (i = 0; i < nbytes; i++)
    *program_data++ ^= *crypt_data++;
  /* memset(crypt_data, 0, nbytes); */
}

/* program should be const char *, but AIX prototypes are wrong */

int cryptrun(char *program, char *crypt_data, int argc, char *argv[])
{
  char buf[8192];
  int (*entry)();
  struct ld_info *info;

  entry = load(program, 0, (char *)0);
  if (entry == 0)
    return -1;

  printf("%x: {%x, %x, %x}\n", entry,
	 ((int *)entry)[0], ((int *)entry)[1], ((int *)entry)[2]);

  if (loadquery(L_GETINFO, (void *)buf, sizeof buf) == -1)
    return -2;

  info = (struct ld_info *)buf;
  do
    {
      printf("%s: text = %x, %x, data = %x, %x\n",
	     info->ldinfo_filename,
	     info->ldinfo_textorg, info->ldinfo_textsize,
	     info->ldinfo_dataorg, info->ldinfo_datasize);
      if (!strcmp(info->ldinfo_filename, program))
	decrypt(info->ldinfo_dataorg, crypt_data, info->ldinfo_datasize);
      info = (struct ld_info *)((char *)info + info->ldinfo_next);
    }
  while (info->ldinfo_next);
  printf("%d\n", entry(argc, argv));
  unload (entry);
  return 0;
}
