001/** 002 * Copyright 2012 Emmanuel Bourg 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package net.jsign.pe; 018 019import java.util.List; 020 021/** 022 * Section of an executable file. 023 * 024 * @author Emmanuel Bourg 025 * @since 1.0 026 */ 027public class Section { 028 029 private PEFile peFile; 030 private int baseOffset; 031 032 Section(PEFile peFile, int baseOffset) { 033 this.peFile = peFile; 034 this.baseOffset = baseOffset; 035 } 036 037 /** 038 * An 8-byte, null-padded UTF-8 encoded string. If the string is exactly 039 * 8 characters long, there is no terminating null. For longer names, this 040 * field contains a slash (/) that is followed by an ASCII representation 041 * of a decimal number that is an offset into the string table. Executable 042 * images do not use a string table and do not support section names longer 043 * than 8 characters. Long names in object files are truncated if they are 044 * emitted to an executable file. 045 */ 046 public String getName() { 047 byte[] buffer = new byte[8]; 048 peFile.read(buffer, baseOffset, 0); 049 String name = new String(buffer); 050 if (name.indexOf(0) != -1) { 051 name = name.substring(0, name.indexOf(0)); 052 } 053 054 return name; 055 } 056 057 /** 058 * The total size of the section when loaded into memory. If this value is 059 * greater than SizeOfRawData, the section is zero-padded. This field is 060 * valid only for executable images and should be set to zero for object files. 061 */ 062 public long getVirtualSize() { 063 return peFile.readDWord(baseOffset, 8); 064 } 065 066 /** 067 * For executable images, the address of the first byte of the section 068 * relative to the image base when the section is loaded into memory. 069 * For object files, this field is the address of the first byte before 070 * relocation is applied; for simplicity, compilers should set this to zero. 071 * Otherwise, it is an arbitrary value that is subtracted from offsets 072 * during relocation. 073 */ 074 public long getVirtualAddress() { 075 return peFile.readDWord(baseOffset, 12); 076 } 077 078 /** 079 * The size of the section (for object files) or the size of the initialized 080 * data on disk (for image files). For executable images, this must be a 081 * multiple of FileAlignment from the optional header. If this is less than 082 * VirtualSize, the remainder of the section is zero-filled. Because the 083 * SizeOfRawData field is rounded but the VirtualSize field is not, it is 084 * possible for SizeOfRawData to be greater than VirtualSize as well. When 085 * a section contains only uninitialized data, this field should be zero. 086 */ 087 public long getSizeOfRawData() { 088 return peFile.readDWord(baseOffset, 16); 089 } 090 091 /** 092 * The file pointer to the first page of the section within the COFF file. 093 * For executable images, this must be a multiple of FileAlignment from the 094 * optional header. For object files, the value should be aligned on a 4 byte 095 * boundary for best performance. When a section contains only uninitialized 096 * data, this field should be zero. 097 */ 098 public long getPointerToRawData() { 099 return peFile.readDWord(baseOffset, 20); 100 } 101 102 /** 103 * The file pointer to the beginning of relocation entries for the section. 104 * This is set to zero for executable images or if there are no relocations. 105 */ 106 public long getPointerToRelocations() { 107 return peFile.readDWord(baseOffset, 24); 108 } 109 110 /** 111 * The file pointer to the beginning of line-number entries for the section. 112 * This is set to zero if there are no COFF line numbers. This value should 113 * be zero for an image because COFF debugging information is deprecated. 114 */ 115 public long getPointerToLineNumbers() { 116 return peFile.readDWord(baseOffset, 28); 117 } 118 119 /** 120 * The number of relocation entries for the section. This is set to zero 121 * for executable images. 122 */ 123 public int getNumberOfRelocations() { 124 return peFile.readWord(baseOffset, 32); 125 } 126 127 /** 128 * The number of line-number entries for the section. This value should 129 * be zero for an image because COFF debugging information is deprecated. 130 */ 131 public int getNumberOfLineNumbers() { 132 return peFile.readWord(baseOffset, 34); 133 } 134 135 /** 136 * The flags that describe the characteristics of the section. 137 */ 138 public List<SectionFlag> getCharacteristics() { 139 return SectionFlag.getFlags((int) peFile.readDWord(baseOffset, 36)); 140 } 141}