Skip to content

Commit

Permalink
Added Relocation section support.
Browse files Browse the repository at this point in the history
  • Loading branch information
lkinsella committed Feb 12, 2016
1 parent 2e90b31 commit 10a229e
Show file tree
Hide file tree
Showing 7 changed files with 465 additions and 3 deletions.
6 changes: 3 additions & 3 deletions Src/Demo Application/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ static void Main(string[] args)
//string file_name = Environment.GetCommandLineArgs()[0];
//string file_name = Assembly.GetEntryAssembly().Location;
//string file_name = @"C:\Windows\SysWOW64\kernel32.dll";
//string file_name = @"C:\Windows\System32\kernel32.dll";
string file_name = @"C:\Windows\System32\kernel32.dll";
//string file_name = @"C:\Windows\SysWOW64\shell32.dll";
string file_name = @"C:\Windows\System32\shell32.dll";
//string file_name = @"C:\Windows\System32\shell32.dll";
//string file_name = @"C:\Windows\SysWOW64\xpsservices.dll";
//string file_name = @"c:\windows\system32\advapi32.dll";
//string file_name = @"P:\Workshell\dotNET Dependency Walker\Bin\Release\netdepends.exe";
Expand All @@ -43,7 +43,7 @@ static void Main(string[] args)
if (content == null)
continue;

if (content.DataDirectory.DirectoryType == DataDirectoryType.TLSTable)
if (content.DataDirectory.DirectoryType == DataDirectoryType.BaseRelocationTable)
{

}
Expand Down
132 changes: 132 additions & 0 deletions Src/Workshell.PE/Content/Relocation/Relocation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Workshell.PE.Annotations;
using Workshell.PE.Native;

namespace Workshell.PE
{

public enum RelocationType : byte
{
[EnumAnnotationAttribute("IMAGE_REL_BASED_ABSOLUTE")]
Absolute = 0,
[EnumAnnotationAttribute("IMAGE_REL_BASED_HIGH")]
High = 1,
[EnumAnnotationAttribute("IMAGE_REL_BASED_LOW")]
Low = 2,
[EnumAnnotationAttribute("IMAGE_REL_BASED_HIGHLOW")]
HighLow = 3,
[EnumAnnotationAttribute("IMAGE_REL_BASED_HIGHADJ")]
HighAdj = 4,
[EnumAnnotationAttribute("IMAGE_REL_BASED_MIPS_JMPADDR")]
MIPSJmpAddr = 5,
[EnumAnnotationAttribute("IMAGE_REL_BASED_ARM_MOV32A")]
ARMMov32a = 6,
[EnumAnnotationAttribute("IMAGE_REL_BASED_ARM_MOV32T")]
ARMMov32t = 7,
[EnumAnnotationAttribute("IMAGE_REL_BASED_MIPS_JMPADDR16")]
MIPSJmpAddr16 = 9,
[EnumAnnotationAttribute("IMAGE_REL_BASED_DIR64")]
Dir64 = 10
}

public sealed class Relocation
{

private RelocationBlock block;
private RelocationType type;
private ushort offset;
private ushort value;
private uint computed_rva;

internal Relocation(RelocationBlock relocBlock, ushort relocValue)
{
block = relocBlock;

int reloc_type = relocValue >> 12;
int reloc_offset = relocValue & 0xFFF;

type = (RelocationType)reloc_type;
offset = Convert.ToUInt16(reloc_offset);
value = relocValue;
computed_rva = block.PageRVA;

switch (type)
{
case RelocationType.Absolute:
break;
case RelocationType.HighLow:
computed_rva += offset;
break;
case RelocationType.Dir64:
computed_rva += offset;
break;
case RelocationType.High:
case RelocationType.Low:
default:
computed_rva = 0;
break;
}
}

#region Methods

public override string ToString()
{
return String.Format("Type: {0}, Computed RVA: 0x{1:X8}",type,computed_rva);
}

#endregion

#region Properties

public RelocationBlock Block
{
get
{
return block;
}
}

public RelocationType Type
{
get
{
return type;
}
}

public ushort Offset
{
get
{
return offset;
}
}

public ushort Value
{
get
{
return value;
}
}

public uint ComputedRVA
{
get
{
return computed_rva;
}
}

#endregion

}

}
129 changes: 129 additions & 0 deletions Src/Workshell.PE/Content/Relocation/RelocationBlock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Workshell.PE
{

public sealed class RelocationBlock : IEnumerable<Relocation>, IReadOnlyCollection<Relocation>, ISupportsLocation, ISupportsBytes
{

private RelocationBlocks blocks;
private Location location;
private uint page_rva;
private uint block_size;
private Section reloc_section;
private List<Relocation> relocations;

internal RelocationBlock(RelocationBlocks relocBlocks, Location blockLocation, uint pageRVA, uint blockSize, IEnumerable<ushort> relocs)
{
LocationCalculator calc = relocBlocks.Content.DataDirectory.Directories.Reader.GetCalculator();

blocks = relocBlocks;
location = blockLocation;
page_rva = pageRVA;
block_size = blockSize;
reloc_section = calc.RVAToSection(pageRVA);
relocations = new List<Relocation>();

foreach(ushort reloc_offset in relocs)
{
Relocation reloc = new Relocation(this,reloc_offset);

relocations.Add(reloc);
}
}

#region Methods

public IEnumerator<Relocation> GetEnumerator()
{
return relocations.GetEnumerator();
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public override string ToString()
{
return String.Format("Page RVA: 0x{0:X8}, Block Size: {1}, Relocations: {2}",page_rva,block_size,relocations.Count);
}

public byte[] GetBytes()
{
Stream stream = blocks.Content.DataDirectory.Directories.Reader.GetStream();
byte[] buffer = Utils.ReadBytes(stream,location);

return buffer;
}

#endregion

#region Properties

public RelocationBlocks Blocks
{
get
{
return blocks;
}
}

public Location Location
{
get
{
return location;
}
}

public uint PageRVA
{
get
{
return page_rva;
}
}

public uint BlockSize
{
get
{
return block_size;
}
}

public Section RelocationSection
{
get
{
return reloc_section;
}
}

public int Count
{
get
{
return relocations.Count;
}
}

public Relocation this[int index]
{
get
{
return relocations[index];
}
}

#endregion

}

}
107 changes: 107 additions & 0 deletions Src/Workshell.PE/Content/Relocation/RelocationBlocks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Workshell.PE
{

public sealed class RelocationBlocks : IEnumerable<RelocationBlock>, IReadOnlyCollection<RelocationBlock>
{

private RelocationTableContent content;
private Location location;
private Section section;
private List<RelocationBlock> blocks;

internal RelocationBlocks(RelocationTableContent relocContent, Location relocLocation, Section relocSection, List<Tuple<ulong,uint,uint,ushort[]>> relocBlocks, ulong imageBase)
{
content = relocContent;
location = relocLocation;
section = relocSection;
blocks = new List<RelocationBlock>();

Load(relocBlocks,imageBase);
}

#region Methods

public IEnumerator<RelocationBlock> GetEnumerator()
{
return blocks.GetEnumerator();
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

private void Load(List<Tuple<ulong,uint,uint,ushort[]>> relocBlocks, ulong imageBase)
{
LocationCalculator calc = content.DataDirectory.Directories.Reader.GetCalculator();

foreach(Tuple<ulong,uint,uint,ushort[]> tuple in relocBlocks)
{
ulong offset = tuple.Item1;
uint rva = calc.OffsetToRVA(section,offset);
ulong va = imageBase + rva;
uint size = tuple.Item2;
uint page_rva = tuple.Item3;
ushort[] relocs = tuple.Item4;
Location block_location = new Location(offset,rva,va,size,size);
RelocationBlock block = new RelocationBlock(this,block_location,page_rva,size,relocs);

blocks.Add(block);
}
}

#endregion

#region Properties

public RelocationTableContent Content
{
get
{
return content;
}
}

public Location Location
{
get
{
return location;
}
}

public Section Section
{
get
{
return section;
}
}

public int Count
{
get
{
return blocks.Count;
}
}

public RelocationBlock this[int index]
{
get
{
return blocks[index];
}
}

#endregion

}

}
Loading

0 comments on commit 10a229e

Please sign in to comment.