⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pe.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 
   Copyright 1994-2003 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  

   You may contact the author at:

   mailto::camille@bluegrass.net

   or by snail mail at:

   David Lindauer
   850 Washburn Ave Apt 99
   Louisville, KY 40222
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <dos.h>

#include "langext.h"
#include "defines.h"
#include "types.h"
#include "subs.h"
#include "globals.h"

bit_16 osMajor =4;
bit_16 osMinor =0;
bit_16 subsysMajor =4 ;
bit_16 subsysMinor =0;

static byte defaultStub[]={
    0x4D,0x5A,0x6C,0x00,0x01,0x00,0x00,0x00,
    0x04,0x00,0x11,0x00,0xFF,0xFF,0x03,0x00,
    0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
    0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x0E,0x1F,0xBA,0x0E,0x00,0xB4,0x09,0xCD,
    0x21,0xB8,0x00,0x4C,0xCD,0x21,0x54,0x68,
    0x69,0x73,0x20,0x70,0x72,0x6F,0x67,0x72,
    0x61,0x6D,0x20,0x72,0x65,0x71,0x75,0x69,
    0x72,0x65,0x73,0x20,0x57,0x69,0x6E,0x33,
    0x32,0x0D,0x0A,0x24
};

static int_32 defaultStubSize=sizeof(defaultStub);

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                           createOutputSection                           |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
bit_32 createOutputSection(byte_ptr name, bit_32 winflags)
BeginDeclarations
  bit_32 rv = n_pe_sections++ ;
EndDeclarations
BeginCode
	outList = (pe_section_ptr_array)reallocate_memory(outList,sizeof(pe_section_ptr) * n_pe_sections) ;
  outList[rv] = (pe_section_ptr)allocate_memory(sizeof(pe_section_type)) ;
  outList[rv]->winFlags = winflags ;
	memcpy(outList[rv]->name,name,8) ;
	return rv ;
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                          enter_pe_import_Fixup                          |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void enter_pe_import_fixup(byte_ptr location_ptr, 
													 bit_32 location_address,
                           public_entry_ptr import, bit_32 isdata) 
BeginDeclarations
EndDeclarations
BeginCode
	If pefile.val IsTrue
    Then
    	If n_pe_import_fixups IsEqualTo max_pe_import_fixups
		    Then
    			max_pe_import_fixups += 20 ;
		    	pe_import_fixup_array = (pe_import_fixup_ptr_array)reallocate_memory(pe_import_fixup_array, max_pe_import_fixups*sizeof(pe_import_fixup_ptr)) ;
		    EndIf ;
         import->isdata = isdata ;
			pe_import_fixup_array[n_pe_import_fixups] = (pe_import_fixup_ptr) allocate_memory(sizeof(pe_import_fixup_type)) ;
			pe_import_fixup_array[n_pe_import_fixups]->pub = import ;
			pe_import_fixup_array[n_pe_import_fixups]->location_ptr = location_ptr;
         pe_import_fixup_array[n_pe_import_fixups]->isdata = isdata;
			pe_import_fixup_array[n_pe_import_fixups++]->location_addr = location_address;
    EndIf ;	
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                         apply_pe_import_fixups                          |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void apply_pe_import_fixups(pe_object_ptr objectTable)
BeginDeclarations
  bit_32 i,j ;
  pe_import_fixup_ptr fixup ;
#define Pub (*pub)
#define Fixup (*fixup) 
EndDeclarations
BeginCode
  For i=0; i LessThan n_pe_import_fixups; i++
    BeginFor
			fixup = pe_import_fixup_array[i] ;
         If Fixup.isdata
           Then
             *(bit_32_ptr)(Fixup.location_ptr) = Fixup.pub->Internal.offset + import_thunk_table->address + *(bit_32_ptr)(Fixup.location_ptr);
           Else
             *(bit_32_ptr)(Fixup.location_ptr) = Fixup.pub->Internal.offset + 
										import_thunk_table->address - Fixup.location_addr - 4 ;
           EndIf
    EndFor ;
EndCode
#undef Fixup
#undef Pub

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                              BuildPEImports                             |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void BuildPEImports(int_32 sectNum,pe_object_ptr objectTable, pe_header_ptr pehead)
BeginDeclarations

    bit_32 i,j,k;
		bit_32 dllCount = 0;
    bit_32 importCount = 0 ;
		bit_32 nameSize = 0;
		bit_32 impNameSize = 0;
		bit_32 namePos, lookupPos,hintPos,addressPos ;
		bit_32 reqCount = 0;
    bit_32 raw ;
    bit_32 impThunkAddress = 0;
    pe_section_ptr sect;
		pe_import_module_ptr modules =0;
    pe_object_ptr lastObjectTable ;
    pe_import_dir_ptr impdir ;
    pe_import_lookup_ptr lookup, lookup2 ;
		string_ptr name ;
#define Lookup (*lookup)
#define Lookup2 (*lookup2)
#define Sect (*sect )
#define ImpDir (*impdir) 
#define ObjectTable (*objectTable)
#define LastObjectTable (*lastObjectTable)
#define PEHead (*pehead)
EndDeclarations
BeginCode

    ReturnIf (sectNum LessThan 0) ;
		sect = outList[sectNum] ;

    For i=0;i<n_imports;i++
     BeginFor
			LoopIf(!imports[i]->use_count);
			 reqCount++ ;
			 For j=0; j<dllCount; j++
        BeginFor
					ExitIf( Not compare_string(modules[j].name,imports[i]->moduleident)) ;
				EndFor ;
			 If j IsEqualTo dllCount 
				Then
					modules = (pe_import_module_ptr)reallocate_memory(modules,(++dllCount)*sizeof(pe_import_module_type)) ;
					modules[j].name = imports[i]->moduleident;
					modules[j].n_imports = modules[j].max_imports = 0;
					modules[j].funcnames = modules[j].ordinals = 0;
					modules[j].pubs = 0 ;
					nameSize += Length(modules[j].name) + 1;
          If nameSize And 1
						Then
							 nameSize++;
						EndIf ;
				EndIf ;
			 If modules[j].n_imports IsEqualTo modules[j].max_imports
				Then
					modules[j].max_imports += 16 ;
					modules[j].funcnames = (string_ptr_array)reallocate_memory(modules[j].funcnames, modules[j].max_imports * sizeof(string_ptr)) ;
					modules[j].ordinals = (bit_32_ptr)reallocate_memory(modules[j].ordinals,modules[j].max_imports*sizeof(bit_32)) ;
					modules[j].pubs = (public_entry_ptr_array)reallocate_memory(modules[j].pubs,modules[j].max_imports * sizeof(public_entry_ptr)) ;
				EndIf ;
			 name = imports[i]->entryident ;
			 /* If the entry identifier does not exist we have an ordinal;
        * but just in case windows ordinals change places we will import
        * by the public name.
        */
			 If name IsNull
				Then	
					name = (string_ptr)&imports[i]->max_length ;
				EndIf ;
			 modules[j].funcnames[modules[j].n_imports] = name;
			 modules[j].ordinals[modules[j].n_imports] = imports[i]->ordinal ;
			 modules[j].pubs[modules[j].n_imports++] = imports[i] ;
			 impNameSize += Length(name) + 1 + 2 ;
  		 If impNameSize And 1
			 	 Then
			 		impNameSize++;
			 	 EndIf ;
			 importCount++ ;
		 EndFor ;
 
    ReturnIf(!importCount) ;

		 namePos = (dllCount+1) *sizeof(pe_import_dir_type) ;
		 lookupPos = namePos + nameSize ;
		 If lookupPos Mod 4
      Then
       lookupPos += 4 - (lookupPos Mod 4) ;
			EndIf ;
		 hintPos = lookupPos + (importCount  + dllCount) * sizeof(pe_import_lookup_type) ;
     addressPos = hintPos + impNameSize ;
		 If addressPos Mod 4
			Then
				addressPos += 4- (addressPos Mod 4) ;
			EndIf ;
		 Sect.initlength = Sect.length = addressPos + (importCount  + dllCount) * sizeof(pe_import_lookup_type) ;
		 Sect.data = (byte_ptr) allocate_memory(Sect.length) ;
		 memset(Sect.data,0,Sect.length) ;


    lastObjectTable = objectTable + sectNum-1 ;
    objectTable = lastObjectTable + 1;
    k = LastObjectTable.raw_ptr + LastObjectTable.raw_size ;
    k+=fileAlign.val-1;
    k&=(0xffffffff-(fileAlign.val-1)); /* aligned */

    /* k is now physical location of this object */
    ObjectTable.raw_ptr = k ;

    k = LastObjectTable.virtual_size + LastObjectTable.virtual_addr ;
    ObjectTable.virtual_addr = k ;
    raw = k ;

    Sect.base=k+imageBase.val; /* get base address of section */

		impdir = (pe_import_dir_ptr)Sect.data ;
		lookup = (pe_import_lookup_ptr)(Sect.data + lookupPos) ;
		lookup2 = (pe_import_lookup_ptr)(Sect.data + addressPos) ;
		For i=0; i < dllCount; i++
			BeginFor
				ImpDir.time = 0;
				ImpDir.version = 0;
				ImpDir.dllName = namePos + raw ;
				ImpDir.thunkPos = (byte_ptr)lookup - (byte_ptr)Sect.data + raw ;
				ImpDir.thunkPos2 = (byte_ptr)lookup2 - (byte_ptr)Sect.data + raw ;
				impdir++ ;
        memcpy(Sect.data + namePos,String(modules[i].name),Length(modules[i].name)) ;
				namePos += Length(modules[i].name) + 1;
				If namePos And 1
					Then
						namePos++ ;
					EndIf;
				For j=0; j < modules[i].n_imports; j++
				  BeginFor
						If modules[i].funcnames[j] IsNotNull
							Then
								Lookup.ord_or_rva = hintPos + raw ;
								Lookup2.ord_or_rva = hintPos + raw ;
								*(bit_16_ptr)(Sect.data + hintPos) = modules[i].ordinals[j] ;
								hintPos += 2 ;
        				memcpy(Sect.data + hintPos,String(modules[i].funcnames[j]),Length(modules[i].funcnames[j])) ;
								hintPos += Length(modules[i].funcnames[j]) + 1;
								If hintPos And 1
									Then
										hintPos++ ;
									EndIf;
							Else
								Lookup.ord_or_rva = Lookup2.ord_or_rva = modules[i].ordinals[j];
								Lookup.import_by_ordinal = 1 ;
								Lookup2.import_by_ordinal = 1 ;
							EndIf ;

							/* now make a thunk that has nothing to do with PE files
							 * but it allows direct jumps to import functions rather than
							 * having the compiler generate indirect calls.
							 */
//                     If modules[i].pubs[j]->isdata 
//                       Then
//                         modules[i].pubs[j]->Internal.offset =
//                                 (byte_ptr)lookup - (byte_ptr)Sect.data + Sect.base ;
//                         enter_pe_fixup(modules[i].pubs[j]->Internal.offset, offset32_location) ;
//                       Else
                         modules[i].pubs[j]->Internal.offset = impThunkAddress ; /* Store the offset to our generated thunk table... */
                         enter_pe_fixup(impThunkAddress + import_thunk_table->address+2, offset32_location) ;
                         *(bit_16_ptr)(impThunkAddress + import_thunk_table->data) = 0x25FF ; /* jump indirect */
                         impThunkAddress += 2 ;
                         *(bit_32_ptr)(impThunkAddress + import_thunk_table->data) = 
                                 (byte_ptr)lookup - (byte_ptr)Sect.data + Sect.base ;
                         impThunkAddress += 4 ;
//                       EndIf
							
							lookup++ ;
							lookup2++;
								
					EndFor ;	
				lookup++;
				lookup2++ ;
				
			EndFor ;

    k=Sect.length;
    k+=objectAlign.val-1;
    k&=(0xffffffff-(objectAlign.val-1));
    Sect.virtualSize=k;

	  ObjectTable.virtual_size = k ;
    ObjectTable.raw_size = Sect.length  ;

    PEHead.import_rva = outList[sectNum]->base-imageBase.val ;
    PEHead.import_size = outList[sectNum]->length ;

		apply_pe_import_fixups(objectTable);
}
#undef ImpDir
#undef PEHead
#undef ObjectTable 
#undef LastObjectTable 
#undef Sect 
#undef Lookup
#undef Lookup2

/*+-------------------------------------------------------------------------+
  |                                                                         |

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -