/* 
 *  Copyright	1994	Eric Youndale & Erik Bos
 *
 *	based on Eric Youndale's pe-test and:
 *
 *	ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include "windows.h"
#include "dlls.h"
#include "neexe.h"
#include "peexe.h"

#define MAP_ANONYMOUS	0x20

unsigned int load_addr;

void my_wcstombs(char * result, u_short * source, int len)
{
  while(len--) {
    if(isascii(*source)) *result++ = *source++;
    else {
      printf("Unable to handle unicode right now\n");
      exit(0);
    }
  };
}

char * xmmap(char * vaddr, unsigned int v_size, int prot, int flags, 
	     int fd, unsigned int file_offset)
{
  char * result;
  result = mmap(vaddr, v_size, prot, flags, fd, file_offset);
  if((unsigned int) result != 0xffffffff) return result;

  /* Sigh.  Alignment must be wrong for mmap.  Do this the hard way. */
  if(!(flags & MAP_FIXED)) {
    vaddr = 0x40000000;
    flags |= MAP_FIXED;
  };

  mmap(vaddr, v_size, prot, MAP_ANONYMOUS | flags, 0, 0);
  lseek(fd, file_offset, SEEK_SET);
  read(fd, vaddr, v_size);
  return vaddr;
};

dump_exports(struct PE_Export_Directory * pe_exports)
{ 
  char * Module;
  int i;
  u_short * ordinal;
  u_long * function;
  u_char ** name, *ename;

  Module = ((char *) load_addr) + pe_exports->Name;
  printf("\n*******EXPORT DATA*******\nModule name is %s, %d functions, %d names\n", 
	 Module,
	 pe_exports->Number_Of_Functions,
	 pe_exports->Number_Of_Names);

  ordinal = (u_short *) (((char *) load_addr) + (int) pe_exports->Address_Of_Name_Ordinals);
  function = (u_long *)  (((char *) load_addr) + (int) pe_exports->AddressOfFunctions);
  name = (u_char **)  (((char *) load_addr) + (int) pe_exports->AddressOfNames);

  printf("%-32s Ordinal Virt Addr\n", "Function Name");
  for(i=0; i< pe_exports->Number_Of_Functions; i++)
    {
      ename =  (char *) (((char *) load_addr) + (int) *name++);
      printf("%-32s %4d    %8.8x\n", ename, *ordinal++, *function++);
    }

  return;
}

dump_imports(struct PE_Import_Directory *pe_imports)
{ 
  struct PE_Import_Directory * pe_imp;

 /* OK, now dump the import list */
  printf("\nDumping imports list\n");
  pe_imp = pe_imports;
  while (pe_imp->ModuleName)
    {
      char * Module, *Function;
      struct pe_import_name * pe_name;
      unsigned int * import_list;
      char * c;

      Module = ((char *) load_addr) + pe_imp->ModuleName;
      printf("%s\n", Module);
      c = strchr(Module, '.');
      if (c) *c = 0;

      import_list = (unsigned int *) 
	(((unsigned int) load_addr) + pe_imp->Import_List);

      while(*import_list)
	{
	  pe_name = (struct pe_import_name *) ((int) load_addr + *import_list);
	  printf("--- %s %s.%d\n", pe_name->Name, Module, pe_name->Hint);
	  import_list++;
	}
      pe_imp++;
    };
}

static void dump_table(struct w_files *wpnt)
{
  int i;

  printf("Dump of segment table\n");
  printf("   Name    VSz  Vaddr     SzRaw   Fileadr  *Reloc *Lineum #Reloc #Linum Char\n");
  for(i=0; i< wpnt->pe->pe_header->coff.NumberOfSections; i++)
    {
      printf("%8s: %4.4x %8.8x %8.8x %8.8x %8.8x %8.8x %4.4x %4.4x %8.8x\n", 
	     wpnt->pe->pe_seg[i].Name, 
	     wpnt->pe->pe_seg[i].Virtual_Size,
	     wpnt->pe->pe_seg[i].Virtual_Address,
	     wpnt->pe->pe_seg[i].Size_Of_Raw_Data,
	     wpnt->pe->pe_seg[i].PointerToRawData,
	     wpnt->pe->pe_seg[i].PointerToRelocations,
	     wpnt->pe->pe_seg[i].PointerToLinenumbers,
	     wpnt->pe->pe_seg[i].NumberOfRelocations,
	     wpnt->pe->pe_seg[i].NumberOfLinenumbers,
	     wpnt->pe->pe_seg[i].Characteristics);
    }
}

/**********************************************************************
 *			LoadPEImage
 * Load one PE format executable into memory
 */
HINSTANCE LoadPEImage(struct w_files *wpnt)
{
	int i, result;

	wpnt->pe = malloc(sizeof(struct pe_data));
	wpnt->pe->pe_header = malloc(sizeof(struct pe_header_s));

	/* read PE header */
	lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
	read(wpnt->fd, wpnt->pe->pe_header, sizeof(struct pe_header_s));

	/* read sections */
	wpnt->pe->pe_seg = malloc(sizeof(struct pe_segment_table) * 
				wpnt->pe->pe_header->coff.NumberOfSections);
	read(wpnt->fd, wpnt->pe->pe_seg, sizeof(struct pe_segment_table) * 
			wpnt->pe->pe_header->coff.NumberOfSections);

	load_addr = wpnt->pe->pe_header->opt_coff.BaseOfImage;
	dump_table(wpnt);

	for(i=0; i < wpnt->pe->pe_header->coff.NumberOfSections; i++)
	{
	if(!load_addr) {
		result = xmmap(0, wpnt->pe->pe_seg[i].Size_Of_Raw_Data, 7, MAP_PRIVATE, 
		      wpnt->fd, wpnt->pe->pe_seg[i].PointerToRawData);
		load_addr = (unsigned int) result -  wpnt->pe->pe_seg[i].Virtual_Address;
	} else {
		result = xmmap((char *) load_addr + wpnt->pe->pe_seg[i].Virtual_Address, 
		      wpnt->pe->pe_seg[i].Size_Of_Raw_Data, 7, MAP_PRIVATE | MAP_FIXED, 
		      wpnt->fd, wpnt->pe->pe_seg[i].PointerToRawData);
	}

	if(strcmp(wpnt->pe->pe_seg[i].Name, ".idata") == 0)
		wpnt->pe->pe_import = (struct PE_Import_Directory *) result;

	if(strcmp(wpnt->pe->pe_seg[i].Name, ".edata") == 0)
		wpnt->pe->pe_export = (struct PE_Export_Directory *) result;

	if(strcmp(wpnt->pe->pe_seg[i].Name, ".rsrc") == 0) {
	    wpnt->pe->pe_resource = (struct PE_Resource_Directory *) result;

	    /* save offset for PE_FindResource */
	    wpnt->pe->resource_offset = wpnt->pe->pe_seg[i].Virtual_Address - 
					wpnt->pe->pe_seg[i].PointerToRawData;
	    }
	}

	if(wpnt->pe->pe_import) dump_imports(wpnt->pe->pe_import);
	if(wpnt->pe->pe_export) dump_exports(wpnt->pe->pe_export);
  
	wpnt->hinstance = 0x8000;
	return (wpnt->hinstance);
}

int PEunloadImage(struct w_files *wpnt)
{
	printf("PEunloadImage() called!\n");
	/* free resources, image, unmap */
	return 1;
}

int StartPEprogram(struct w_files *wpnt)
{
	printf("StartPEprogram() called!\n");
	return 0;
}

void InitPEDLL(struct w_files *wpnt)
{
	/* Is this a library? */
	if (wpnt->pe->pe_header->coff.Characteristics & IMAGE_FILE_DLL) {
		printf("InitPEDLL() called!\n");
	}
}
