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

📄 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 页
字号:
  |                             enter_pe_Fixup                              |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void enter_pe_fixup(bit_32 address,loc_type location) 
BeginDeclarations
EndDeclarations
BeginCode
	If pefile.val IsTrue
    Then
    	If location IsNotEqualTo offset32_location AndIf location IsNotEqualTo secondary_offset32_location
		    Then
			    linker_error(4,"PE Fixup error:\n"
                        " Error:  segment-relative fixups in PE files must be 32 bits\n");
    			return ;
		    EndIf ;
    	If n_pe_fixups IsEqualTo max_pe_fixups
		    Then
    			max_pe_fixups += 10000 ;
		    	pe_fixup_array = (fixup_hold_ptr_array)reallocate_memory(pe_fixup_array, max_pe_fixups*sizeof(fixup_hold_ptr)) ;
		    EndIf ;
			pe_fixup_array[n_pe_fixups] = (fixup_hold_ptr)allocate_memory(sizeof(fixup_hold_type));
			pe_fixup_array[n_pe_fixups]->offset = address ;
			pe_fixup_array[n_pe_fixups++]->type = PE_FIXUP_HIGHLOW ;
    EndIf ;	
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                                SortFixups                               |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
static int sortcmp(fixup_hold_ptr *left, fixup_hold_ptr *right)
{
    if ((*left)->offset < (*right)->offset)
        return -1;
    if ((*left)->offset < (*right)->offset)
        return 1;
    return 0;        
}
static void SortFixups(void)
BeginDeclarations
  bit_32 i,j;
  fixup_hold_ptr temp ;
EndDeclarations
BeginCode
  qsort(pe_fixup_array,n_pe_fixups,sizeof(void *),(int (*)(const void *, const void *))sortcmp);
#ifdef XXXXX
  For i=0 ; i < n_pe_fixups; i++
    BeginFor
      For j=i+1; j < n_pe_fixups; j++
        BeginFor
          If pe_fixup_array[i]->offset > pe_fixup_array[j]->offset
            Then
              temp = pe_fixup_array[i] ;
              pe_fixup_array[i] = pe_fixup_array[j] ;
              pe_fixup_array[j] = temp ;
            EndIf ;
        EndFor ;
    EndFor ;
#endif
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                              BuildPERelocs                              |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void BuildPERelocs(bit_32 sectNum, pe_object_ptr objectTable, pe_header_ptr pehead)
BeginDeclarations
  fixup_block_type block ;
  int_32 pos ;
  int_32 base ;
  int_32 current ;
  pe_section_ptr sect ;
  int_32 k ;
  pe_object_ptr lastObjectTable ;
  int_32 current_size;
#define PEHead (*pehead)
#define LastObjectTable (*lastObjectTable)
#define ObjectTable (*objectTable) 
#define Sect (*sect)
EndDeclarations
BeginCode
  SortFixups() ;
  pos = 0;
  current_size = 0;
  sect = outList[sectNum] ;

  // Make winnt happy if no fixups 
  If n_pe_fixups IsZero
    Then
      block.rva = 0 ;
      block.size = 12;
      block.data[0] = block.data[1] = 0;
      Sect.data = allocate_memory(block.size) ;
      memcpy(Sect.data, &block, block.size);
      Sect.length = Sect.initlength = block.size ;
    EndIf ;
  While pos LessThan n_pe_fixups
    BeginWhile
      base = pe_fixup_array[pos]->offset And Complement 4095;
      current = 0;
      block.rva = base - imageBase.val ;
      block.size = 8 ;
      While pos LessThan n_pe_fixups AndIf base IsEqualTo (pe_fixup_array[pos]->offset And Complement 4095)
        BeginWhile
          block.size += 2 ;
          block.data[current++] = (pe_fixup_array[pos]->offset And 4095) Or (pe_fixup_array[pos]->type ShiftedLeft 12);
					pos++ ;
        EndWhile ;
      If block.size And 3
        Then
          block.size += 2 ;
          block.data[current++] = 0;
        EndIf ;
      if (Sect.length + block.size >= current_size) {  
          current_size += (n_pe_fixups - pos) * (8 + 1024) + 10000 ;
          if (current_size < Sect.length + block.size) // should never happen
            current_size = Sect.length + block.size;
        Sect.data = reallocate_memory(Sect.data, current_size) ;
      }
      memcpy(Sect.data + Sect.length, &block, block.size);
      Sect.initlength = Sect.length += block.size ;
// fixme max lengths 

    EndWhile ;
    lastObjectTable = objectTable + sectNum-1 ;
    objectTable = lastObjectTable + 1;

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

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

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

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

    Sect.base=k+imageBase.val; /* relocate section */
		PEHead.fixup_rva  = Sect.base - imageBase.val ;
		PEHead.fixup_size  = Sect.length;

    return;
}
#undef ObjectTable
#undef Sect
#undef PEHead


/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                             BuildPEExports                              |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
int expfunc(void *a, void *b)
{
    return strcmp(String(((public_entry_ptr)*(void **)a)->entryident), String(((public_entry_ptr)*(void **)b)->entryident));
}
void BuildPEExports(int_32 sectNum,pe_object_ptr objectTable, pe_header_ptr pehead)
BeginDeclarations
    bit_32 i,j,k;
    pe_section_ptr  sect;
    bit_32 nameLen;
    bit_32 numNames=0;
    bit_32 RVAStart;
    bit_32 nameRVAStart;
    bit_32 ordinalStart;
    bit_32 nameSpaceStart;
    bit_32 minOrd;
    bit_32 maxOrd;
    bit_32 numOrds;
    pe_object_ptr lastObjectTable ;
		public_entry_ptr pub ;
		bit_32_ptr ordinals ;
		bit_16_ptr ordinals2 ;
		bit_32_ptr rvas ;
		export_header_ptr exportHeader ;
		byte_ptr nm,nm1,nm2 ;
		public_entry_ptr_array nameList ;
#define PEHead (*pehead)
#define Sect (*sect)
#define ObjectTable (*objectTable)
#define Pub (*pub)
#define LastObjectTable (*lastObjectTable)
#define ExportHeader (*exportHeader)
EndDeclarations
BeginCode

		ReturnIf (Not n_exports OrIf sectNum < 0) ;

    sect=outList[sectNum];
		lastObjectTable = objectTable + sectNum - 1;
		objectTable = lastObjectTable + 1;

		nm = exe_file_list.first->filename ;
		nm1 = strrchr(nm,'\\') ;
		If nm1 IsNotNull
			Then
			  nm = nm1 + 1;
			Else
				nm1 = strrchr(nm,':');
				If nm1 IsNotNull
					Then
						nm = nm1 + 1;
					EndIf ;
			EndIf ;
		nameLen = strlen(nm) ;

    Sect.initlength = Sect.length=sizeof(export_header_type)+nameLen+1;
    /* min section size= header size + num exports * pointer size */
    /* plus space for null-terminated name */

    minOrd=0xffffffff; /* max ordinal num */
    maxOrd=0;
    numOrds=n_exports ;

		For i=0; i < n_exports; i++
			BeginFor
				pub = exports[i] ;
				If Length(Pub.entryident) IsNotZero
					Then
						Sect.initlength = Sect.length += Length(Pub.entryident) + 1 + 6;
						numNames++ ;
					EndIf ;
				If Pub.ordinal IsNotEqualTo 0xffffffff
					Then
						If Pub.ordinal LessThan minOrd
							Then
								minOrd = Pub.ordinal ;
							EndIf ;
						If Pub.ordinal GreaterThan maxOrd
							Then
								maxOrd = Pub.ordinal ;
							EndIf ;
					EndIf ;
			EndFor ;

		If maxOrd GreaterThanOrEqualTo minOrd
			Then
				numOrds = (maxOrd-minOrd + 1) ;
			Else
				minOrd = 0 ;
			EndIf ;
		
		Sect.initlength = Sect.length += 4* numOrds ;
    exportHeader = (export_header_ptr) (Sect.data= allocate_memory(Sect.length)) ;

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

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

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

    Sect.base=k+imageBase.val; /* relocate section */

		memset(Sect.data,0,Sect.length) ;

		ExportHeader.time = time(0) ;
		ExportHeader.ord_base = minOrd ;
		ExportHeader.n_eat_entries = numOrds ;
		ExportHeader.n_name_ptrs = numNames ;

    RVAStart=sizeof(export_header_type); /* start address of RVA table */
    nameRVAStart=RVAStart+numOrds*4; /* start of name table entries */
    ordinalStart=nameRVAStart+numNames*4; /* start of associated ordinal entries */
    nameSpaceStart=ordinalStart+numNames*2; /* start of actual names */

		ExportHeader.address_rva = RVAStart + Sect.base - imageBase.val ;
		ExportHeader.name_rva = nameRVAStart + Sect.base - imageBase.val ;
		ExportHeader.ordinal_rva = ordinalStart + Sect.base - imageBase.val ;

    If numNames
     Then
		/* sort */
		nameList = (public_entry_ptr_array)allocate_memory(numNames * sizeof (public_entry_ptr));
        j=0; /* no entries yet */
		For i=0; i < n_exports; i++
			BeginFor
				pub = exports[i] ;
				If Length(Pub.entryident)
					Then ;
						nameList[j++] = pub ;
					EndIf ;
			EndFor ;
       qsort(nameList,numNames,sizeof(nameList[0]),expfunc);
     EndIf
    /* process numbered exports */
		rvas = (bit_32_ptr)(Sect.data + RVAStart) ;
    For i=0; i LessThan n_exports; i++
			BeginFor
				pub = exports[i] ;
				If Pub.ordinal IsNotEqualTo 0xffffffff
					Then
						k = rvas[Pub.ordinal - minOrd] ;
						If k IsNotZero
							Then
								linker_error(4,"Export error:\n"
														"\tExport:  \"%s\"\n"
														"\t   Ord: %08lx\n"
														"\t Error: Ordinal already assigned to \n"
														"\t        another export\n",
														String(Pub.entryident),
														Pub.ordinal);
							Else
   							  If Pub.Internal.lseg IsNull
    							Then
     								k = (Bit_32(Pub.Internal.frame) ShiftedLeft 4);
    							Else
     								k = (*Pub.Internal.lseg).address;
    							EndIf;
						 	  k = k + Pub.Internal.offset ;
							  rvas[Pub.ordinal - minOrd] = k -imageBase.val;
							EndIf ;
					EndIf ;
			EndFor ;
			
				
    /* process non-numbered exports */
		For i=0,j=0; i < n_exports; i++
			BeginFor
				pub = exports[i] ;
				If Pub.ordinal IsEqualTo 0xffffffff
					Then
						While rvas[j]
							BeginWhile
								j++ ;
							EndWhile ;
						
						Pub.ordinal = j + minOrd ;
						If Pub.Internal.lseg IsNull
							Then
 								k = (Bit_32(Pub.Internal.frame) ShiftedLeft 4);

⌨️ 快捷键说明

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