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

📄 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 页
字号:
							Else
 								k = (*Pub.Internal.lseg).address;
							EndIf;
						k = k + Pub.Internal.offset ;
						rvas[j++] = k -imageBase.val;
					EndIf
      EndFor ;

		If numNames
			Then
				nm1 = Sect.data + nameSpaceStart ;
				ordinals = (bit_32_ptr)(Sect.data + nameRVAStart) ;
				ordinals2 =  (bit_16_ptr)(Sect.data + ordinalStart) ;
			
        /* and store */
				For i=0; i < numNames; i++
					BeginFor
						pub = nameList[i] ;
						*(ordinals2)++ = Pub.ordinal ;
						*(ordinals)++ = nm1 - Sect.data + Sect.base - imageBase.val ;
						nm2 = String(Pub.entryident);
					    For j=0; j < Length(Pub.entryident); j++
							BeginFor
								*nm1++ =*nm2++ ;
							EndFor ;
						*nm1++ = 0;
					EndFor
			EndIf ;

		If nameLen IsNotZero
			Then
				ExportHeader.exe_name_rva = nm1 - Sect.data + Sect.base - imageBase.val ;
				For j=0; j < nameLen; j++
					BeginFor
						*nm1++ =toupper(*nm++) ;
					EndFor ;
				*nm1++ = 0 ;
			EndIf ;
	PEHead.export_rva  = Sect.base - imageBase.val ;
	PEHead.export_size  = Sect.length;
EndCode ;
#undef ObjectTable
#undef Pub
#undef LastObjectTable
#undef ExportHeader
#undef Sect
#undef PEHead


/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                              CountResource                              |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void CountResource(resource_data_ptr resource, bit_32_ptr dirs, bit_32_ptr entries, bit_32_ptr data_headers, bit_32_ptr datasize, bit_32_ptr name_size, bit_32 typeorhead)
BeginDeclarations
  resource_data_ptr res ;
  #define Resource (*resource)
EndDeclarations
BeginCode
  If typeorhead OrIf (Resource.name_count + Resource.ident_count) IsNotZero
    Then
      (*dirs)++;
    EndIf ;
  *entries += Resource.name_count + Resource.ident_count ;
  If Resource.length 
    Then
      (*data_headers) ++ ;
      (*datasize) += (Resource.length + 3) & 0xFFFFFFFC ;
    EndIf ;
	If Resource.name
		Then
			(*name_size) += wstrlen(Resource.name) * 2 + 2 ;
		EndIf ;
  TraverseList(Resource.name_list,res)
    BeginTraverse
      CountResource(res,dirs,entries,data_headers,datasize, name_size, resource IsEqualTo &resource_head) ;
    EndTraverse ;
  TraverseList(Resource.ident_list,res)
    BeginTraverse
      CountResource(res,dirs,entries,data_headers,datasize, name_size, resource IsEqualTo &resource_head) ;
    EndTraverse ;

EndCode
#undef Resource


/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                              DumpResources                              |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void DumpResources(byte_ptr data, resource_data_ptr resource, bit_32_ptr dir_start, bit_32_ptr data_header_start, bit_32_ptr name_start, bit_32_ptr data_start, bit_32 va)
BeginDeclarations
	resource_data_ptr res ;
  resource_dir_table_ptr dirhead ;
	resource_dir_entry_ptr direntries ;
  resource_data_entry_ptr datahead ;
  bit_32 i;
#define DirHead (*dirhead)
#define DirEntries (*direntries)
#define Res (*res)
#define DataHead (*datahead)
#define Resource (*resource)

EndDeclarations
BeginCode
	If Resource.name_count + Resource.ident_count IsNotZero
		Then
			dirhead = (resource_dir_table_ptr)(data + *dir_start) ;
			direntries = (resource_dir_entry_ptr)(dirhead + 1) ;
			*dir_start = (byte_ptr) (direntries + (Resource.name_count + Resource.ident_count)) - data;
			DirHead.time = time(0) ;
			DirHead.name_entry = Resource.name_count ;
			DirHead.ident_entry = Resource.ident_count ;
			TraverseList(Resource.name_list,res)
				BeginTraverse
					DirEntries.rva_or_id = *name_start + 0x80000000 ;
					DirEntries.subdir_or_data = (bit_32)*dir_start ;
					DirEntries.escape = 1 ; /* Subdir */
					direntries++ ;
					*(bit_16_ptr)(data + *name_start) = i = wstrlen(Res.name) ;
					wstrcpy((bit_16_ptr)(data + *name_start + 2),Res.name) ;
					*name_start += i*2+2 ;
					DumpResources(data,res,dir_start, data_header_start, name_start, data_start,va) ;
				EndTraverse
			TraverseList(Resource.ident_list,res)
				BeginTraverse
					DirEntries.rva_or_id = Res.id ;
					DirEntries.escape = (Res.name_count + Res.ident_count) ? 1 : 0 ;
					If DirEntries.escape
						Then
							DirEntries.subdir_or_data = (bit_32)*dir_start;
						Else
							DirEntries.subdir_or_data = (bit_32)*data_header_start;
						EndIf ;
					direntries++ ;
					DumpResources(data,res,dir_start, data_header_start, name_start, data_start,va) ;
				EndTraverse
		Else
			If Resource.data IsNull
				Then
					If Resource.name_count
						Then
							res = Resource.name_list.first ;
						Else
							res = Resource.ident_list.first ;
						EndIf ;
				EndIf ;
			datahead = (resource_data_entry_ptr)(data + *data_header_start) ;
			*data_header_start += sizeof (resource_data_entry_type) ;
			memcpy(data + *data_start, Resource.data, Resource.length) ;
			DataHead.rva = *data_start + va ;
			*data_start += (Resource.length + 3) & 0xfffffffc ;
			DataHead.size = Resource.length ;
			DataHead.codepage = 0;
			DataHead.reserved = 0 ;
		EndIf ;
EndCode
#undef DirHead
#undef DirEntries
#undef Res
#undef DataHead
#undef Resource


/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                            BuildPEResources                             |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void BuildPEResources(int_32 sectNum,pe_object_ptr objectTable, pe_header_ptr pehead)
BeginDeclarations
  bit_32 num_dirs = 1 ;
  bit_32 num_dir_entries =0 ;
  bit_32 num_data_headers =0 ;
  bit_32 data_size = 0 ;
  bit_32 name_size = 0 ;
  bit_32 i,j,k ;
  bit_32 dir_start = 0;
  bit_32 data_start ;
  bit_32 data_header_start ;
  bit_32 name_start ;
  bit_32 total_size ;
  pe_object_ptr lastObjectTable ;
  pe_section_ptr  sect ;
#define ObjectTable (*objectTable)
#define LastObjectTable (*lastObjectTable)
#define Sect (*sect)
#define PEHead (*pehead)
EndDeclarations
BeginCode
  ReturnIf(sectNum LessThan 0 OrIf Not n_resources) ;

  CountResource(&resource_head,&num_dirs, &num_dir_entries, &num_data_headers, & data_size, &name_size, True) ;
  data_header_start = num_dirs * sizeof(resource_dir_table_type) +
                      num_dir_entries * sizeof(resource_dir_entry_type) ;
  name_start = data_header_start + num_data_headers * sizeof(resource_data_entry_type) ;
  data_start = (name_start + name_size  + 3) & 0xfffffffc;
  total_size = (data_start + data_size + 3) & 0xfffffffc;

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

  sect = outList[sectNum] ;
  Sect.length = Sect.initlength = total_size ;
  Sect.data = allocate_memory(total_size) ;
  Sect.base = k + imageBase.val ;
  k=total_size + objectAlign.val - 1;
  k&=(0xffffffff-(objectAlign.val-1));
  Sect.virtualSize=ObjectTable.virtual_size = k;
  ObjectTable.raw_size = total_size ;

  DumpResources(Sect.data, &resource_head, &dir_start, &data_header_start, &name_start, &data_start, ObjectTable.virtual_addr) ;

	PEHead.resource_rva  = Sect.base - imageBase.val ;
	PEHead.resource_size  = Sect.length;
EndCode
#undef PEHead
#undef Sect
#undef ObjectTable
#undef LastObjecTable


/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                            BuildPEDebug                                 |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void BuildPEDebug(int_32 sectNum,pe_object_ptr objectTable, pe_header_ptr pehead)
BeginDeclarations
  bit_32                                  k ;
  bit_32                                  total_size ;
  byte_ptr                                data ;
  pe_object_ptr                           lastObjectTable ;
  pe_section_ptr                          sect ;
#define ObjectTable (*objectTable)
#define LastObjectTable (*lastObjectTable)
#define Sect (*sect)
#define PEHead (*pehead)
EndDeclarations
BeginCode
//  ReturnIf(sectNum LessThan 0) ;

  ReturnIf (debug.val IsFalse) ;
  create_codeview_data( &data, &total_size) ;
  file_open_for_write(cv_file_list.first);
  file_write(data+32, total_size-32) ;
  file_close_for_write() ;

#ifdef XXXXX  // Win2K doesn't support embedded debug info...
  lastObjectTable = objectTable + sectNum - 1;
  objectTable = lastObjectTable + 1 ;
  k = LastObjectTable.raw_ptr + LastObjectTable.raw_size + fileAlign.val-1 ;
  k&=(0xffffffff-(fileAlign.val-1)); /* aligned */
  ObjectTable.raw_ptr = k ;
  k = ObjectTable.virtual_addr = LastObjectTable.virtual_addr + LastObjectTable.virtual_size ;

  sect = outList[sectNum] ;
  Sect.length = Sect.initlength = total_size ;
  Sect.data = data ;
  Sect.base = k + imageBase.val ;
  k=total_size + objectAlign.val - 1;
  k&=(0xffffffff-(objectAlign.val-1));
  Sect.virtualSize=ObjectTable.virtual_size = k;
  ObjectTable.raw_size = total_size ;

  PEHead.debug_rva  = Sect.base - imageBase.val ;
  PEHead.debug_size  = Sect.length;

  *(bit_32 *)(data + 16) = total_size - 32 ;
  *(bit_32 *)(data + 20) = ObjectTable.virtual_addr + 0x20 ;
  *(bit_32 *)(data + 24) = ObjectTable.raw_ptr + 0x20 ;
#endif
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                                 load_stub                               |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void load_stub(byte_ptr *pstubData,bit_32_ptr pstubSize)
BeginDeclarations
    EXE_header_type headbuf;
    byte_ptr headerdata;
    bit_32 imageSize;
    bit_32 headerSize;
    bit_32 relocSize;
    bit_32 relocStart;
    int_32 i;
EndDeclarations
BeginCode

    If stub_file_list.first IsNotNull
      Then
        file_open_for_read(stub_file_list.first) ;
        file_read((byte_ptr)&headbuf,sizeof(headbuf)) ;
        If headbuf.signature IsNotEqualTo 0x5a4d
          Then
            linker_error(4,"Invalid EXE Stub File:\n"
                          "\t  File:  \"%s\"\n"
                          "\tOffset:  %08lx\n"
                          "\t Error:  Invalid header\n",
                          stub_file_list.first->filename,0L) ;
            file_close_for_read() ;
            return ;
        	EndIf ;
        /* get size of image */
        imageSize=headbuf.image_length_MOD_512+(headbuf.image_length_DIV_512<<9);
        If (imageSize Mod 512) IsNotZero 
          Then
            imageSize-=512;
          EndIf ;
        headerSize=(headbuf.n_header_paragraphs)<<4;
        relocSize= headbuf.n_relocation_items << 2;
        imageSize-=headerSize;

        /* allocate buffer for load image */
        headerdata=allocate_memory(imageSize+0x40+((relocSize+15) And Not 15));

        /* copy header */
        memcpy(headerdata,(byte_ptr)&headbuf,sizeof(headbuf)) ;

        relocStart=headbuf.offset_to_relocation_table ;
        /* load relocs */
        file_position(relocStart) ;
        file_read(headerdata+0x40,relocSize) ;

        /* paragraph align reloc size */
        relocSize += 15;
        relocSize &= Complement 15;

        /* move to start of data */
        file_position(headerSize) ;

        /* new header is 4 paragraphs long + relocSize*/
        headbuf.n_header_paragraphs = (headerSize = (relocSize + 0x40)) >> 4 ;
        headbuf.offset_to_relocation_table = 0x40 ;       

        /* load data into correct position */

⌨️ 快捷键说明

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