Skip to content

Commit

Permalink
Work on the Relocation section. Also tweaked the Sections class so it…
Browse files Browse the repository at this point in the history
… caches created Section instances.
  • Loading branch information
lkinsella committed Jan 21, 2016
1 parent b1bbbda commit d77e752
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Src/Demo Application/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static void Main(string[] args)

foreach(Section section in sections)
{
TLSContent content = (TLSContent)section[DataDirectoryType.TLSTable];
RelocationContent content = (RelocationContent)section[DataDirectoryType.BaseRelocationTable];

if (content != null)
{
Expand Down
32 changes: 8 additions & 24 deletions Src/Workshell.PE/Relocations/RelocationBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,15 @@ public class RelocationBlock : IEnumerable<Relocation>, ILocationSupport
private RelocationContent content;
private StreamLocation location;
private IMAGE_BASE_RELOCATION relocation;
private Section relocation_section;
private SectionTableEntry relocation_section;
private List<Relocation> list;

internal RelocationBlock(RelocationContent relocContent, long offset, long size, IMAGE_BASE_RELOCATION baseRelocation, List<ushort> relocList)
{
content = relocContent;
location = new StreamLocation(offset,size);
relocation = baseRelocation;
relocation_section = null;

foreach(Section section in relocContent.Section.Sections)
{
if (relocation.VirtualAddress >= section.TableEntry.VirtualAddress && relocation.VirtualAddress <= (section.TableEntry.VirtualAddress + section.TableEntry.VirtualSizeOrPhysicalAddress))
{
relocation_section = section;

break;
}
}

relocation_section = relocContent.Section.Sections.Reader.RVAToSectionTableEntry(baseRelocation.VirtualAddress);
list = new List<Relocation>();

long reloc_offset = offset + 8;
Expand All @@ -46,16 +35,6 @@ internal RelocationBlock(RelocationContent relocContent, long offset, long size,

#region Methods

public IMAGE_BASE_RELOCATION GetNativeRelocation()
{
return relocation;
}

public override string ToString()
{
return String.Format("0x{0:X8}+{1}",relocation.VirtualAddress,relocation_section.TableEntry.Name);
}

public IEnumerator<Relocation> GetEnumerator()
{
return list.GetEnumerator();
Expand All @@ -66,6 +45,11 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
return GetEnumerator();
}

public override string ToString()
{
return String.Format("0x{0:X8}+{1} -> {2}",relocation.VirtualAddress,relocation.SizeOfBlock,relocation_section.Name);
}

#endregion

#region Properties
Expand Down Expand Up @@ -94,7 +78,7 @@ public uint BlockSize
}
}

public Section RelocationSection
public SectionTableEntry RelocationSection
{
get
{
Expand Down
32 changes: 24 additions & 8 deletions Src/Workshell.PE/Relocations/RelocationContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,21 @@ public DataDirectoryType DirectoryType

}

public class RelocationContent : SectionContent, IEnumerable<RelocationBlock>
public class RelocationContent : SectionContent, ILocationSupport, IRawDataSupport, IEnumerable<RelocationBlock>
{

private List<RelocationBlock> blocks;
private StreamLocation location;

internal RelocationContent(DataDirectory directory, Section section) : base(directory,section)
{
Stream stream = section.Sections.Reader.Stream;

blocks = new List<RelocationBlock>();

return;

long offset = section.Location.Offset;
long offset = section.RVAToOffset(directory.VirtualAddress);
long size = 0;
Stream stream = Section.Sections.Reader.GetStream();

stream.Seek(section.Location.Offset,SeekOrigin.Begin);
stream.Seek(offset,SeekOrigin.Begin);

while (true)
{
Expand All @@ -76,12 +74,14 @@ internal RelocationContent(DataDirectory directory, Section section) : base(dire
}

RelocationBlock block = new RelocationBlock(this,block_offset,block_data.SizeOfBlock,block_data,relocations);

blocks.Add(block);

if (size >= directory.Size)
break;
}

location = new StreamLocation(offset,size);
}

#region Methods
Expand All @@ -96,10 +96,26 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
return GetEnumerator();
}

public byte[] GetBytes()
{
Stream stream = Section.Sections.Reader.GetStream();
byte[] buffer = Utils.ReadBytes(stream,location);

return buffer;
}

#endregion

#region Properties

public StreamLocation Location
{
get
{
return location;
}
}

public int Count
{
get
Expand Down
20 changes: 11 additions & 9 deletions Src/Workshell.PE/Section.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,14 @@ public class Sections : IEnumerable<Section>
private ExeReader reader;
private SectionTable table;
private Dictionary<DataDirectoryType,ISectionContentProvider> content_providers;
private Dictionary<SectionTableEntry,Section> cache;

internal Sections(ExeReader exeReader, SectionTable sectionTable)
{
reader = exeReader;
table = sectionTable;
content_providers = new Dictionary<DataDirectoryType,ISectionContentProvider>();
cache = new Dictionary<SectionTableEntry,Section>();

RegisterAssemblyContentProviders();
}
Expand Down Expand Up @@ -235,6 +237,9 @@ private Section CreateSection(SectionTableEntry entry)
if (entry.VirtualAddress == 0)
return null;

if (cache.ContainsKey(entry))
return cache[entry];

Section section = new Section(this,entry);
Dictionary<DataDirectoryType,DataDirectory> data_directories = new Dictionary<DataDirectoryType,DataDirectory>();

Expand All @@ -258,6 +263,8 @@ private Section CreateSection(SectionTableEntry entry)
section.Attach(content);
}

cache.Add(entry,section);

return section;
}

Expand Down Expand Up @@ -298,7 +305,7 @@ public Section this[int index]

SectionTableEntry entry = table[index];

return CreateSection(entry);
return this[entry];
}
}

Expand All @@ -308,23 +315,18 @@ public Section this[string sectionName]
{
SectionTableEntry entry = table.FirstOrDefault(e => String.Compare(sectionName,e.Name,StringComparison.OrdinalIgnoreCase) == 0);

if (entry == null)
return null;

return CreateSection(entry);
return this[entry];
}
}

public Section this[SectionTableEntry tableEntry]
{
get
{
SectionTableEntry entry = table.FirstOrDefault(e => e.VirtualAddress == tableEntry.VirtualAddress);

if (entry == null)
if (tableEntry == null)
return null;

return CreateSection(entry);
return CreateSection(tableEntry);
}
}

Expand Down
13 changes: 3 additions & 10 deletions Src/Workshell.PE/SectionTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -372,17 +372,10 @@ internal SectionTable(ExeReader exeReader, StreamLocation streamLoc, List<IMAGE_

public byte[] GetBytes()
{
using (MemoryStream mem = new MemoryStream(SectionTableEntry.Size * table.Count))
{
foreach(SectionTableEntry entry in table)
{
byte[] buffer = entry.GetBytes();

mem.Write(buffer,0,buffer.Length);
}
Stream stream = reader.GetStream();
byte[] buffer = Utils.ReadBytes(stream,location);

return mem.ToArray();
}
return buffer;
}

public bool Has(string name)
Expand Down

0 comments on commit d77e752

Please sign in to comment.