-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for the Relocation Table (also fixed a bug from other branch).
- Loading branch information
Lloyd Kinsella
committed
Jul 25, 2018
1 parent
97ef57a
commit ed71f02
Showing
7 changed files
with
437 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Workshell.PE.Annotations; | ||
using Workshell.PE.Extensions; | ||
|
||
namespace Workshell.PE.Content | ||
{ | ||
public enum RelocationType : byte | ||
{ | ||
[EnumAnnotation("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 | ||
{ | ||
internal Relocation(RelocationBlock relocBlock, ushort relocValue) | ||
{ | ||
Block = relocBlock; | ||
|
||
var relocType = relocValue >> 12; | ||
var relocOffset = relocValue & 0xFFF; | ||
|
||
Type = (RelocationType)relocType; | ||
Offset = relocOffset.ToUInt16(); | ||
Value = relocValue; | ||
ComputedRVA = Block.PageRVA; | ||
|
||
switch (Type) | ||
{ | ||
case RelocationType.Absolute: | ||
break; | ||
case RelocationType.HighLow: | ||
ComputedRVA += Offset; | ||
break; | ||
case RelocationType.Dir64: | ||
ComputedRVA += Offset; | ||
break; | ||
case RelocationType.High: | ||
case RelocationType.Low: | ||
default: | ||
ComputedRVA = 0; | ||
break; | ||
} | ||
} | ||
|
||
#region Methods | ||
|
||
public override string ToString() | ||
{ | ||
return $"Type: {Type}, Computed RVA: 0x{ComputedRVA:X8}"; | ||
} | ||
|
||
#endregion | ||
|
||
#region Properties | ||
|
||
public RelocationBlock Block { get; } | ||
public RelocationType Type { get; } | ||
public ushort Offset { get; } | ||
public ushort Value { get; } | ||
public uint ComputedRVA { get; } | ||
|
||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Workshell.PE.Extensions; | ||
|
||
namespace Workshell.PE.Content | ||
{ | ||
public sealed class RelocationBlock : IEnumerable<Relocation>, ISupportsLocation, ISupportsBytes | ||
{ | ||
private readonly PortableExecutableImage _image; | ||
private readonly Relocation[] _relocations; | ||
|
||
internal RelocationBlock(PortableExecutableImage image, Location location, uint pageRVA, uint blockSize, ushort[] relocations) | ||
{ | ||
_image = image; | ||
_relocations = new Relocation[relocations.Length]; | ||
|
||
Location = location; | ||
PageRVA = pageRVA; | ||
BlockSize = blockSize; | ||
Section = GetSection(pageRVA); | ||
Count = relocations.Length; | ||
|
||
for (var i = 0; i < relocations.Length; i++) | ||
_relocations[i] = new Relocation(this, relocations[i]); | ||
} | ||
|
||
#region Methods | ||
|
||
public override string ToString() | ||
{ | ||
return $"Page RVA: 0x{PageRVA:X8}, Block Size: {BlockSize}, Relocations: {_relocations.Length}"; | ||
} | ||
|
||
public IEnumerator<Relocation> GetEnumerator() | ||
{ | ||
foreach (var relocation in _relocations) | ||
yield return relocation; | ||
} | ||
|
||
IEnumerator IEnumerable.GetEnumerator() | ||
{ | ||
return GetEnumerator(); | ||
} | ||
|
||
public byte[] GetBytes() | ||
{ | ||
return GetBytesAsync().GetAwaiter().GetResult(); | ||
} | ||
|
||
public async Task<byte[]> GetBytesAsync() | ||
{ | ||
var stream = _image.GetStream(); | ||
var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); | ||
|
||
return buffer; | ||
} | ||
|
||
private Section GetSection(uint pageRVA) | ||
{ | ||
var calc = _image.GetCalculator(); | ||
var section = calc.RVAToSection(pageRVA); | ||
|
||
return section; | ||
} | ||
|
||
#endregion | ||
|
||
#region Properties | ||
|
||
public Location Location { get; } | ||
public uint PageRVA { get; } | ||
public uint BlockSize { get; } | ||
public Section Section { get; } | ||
public int Count { get; } | ||
public Relocation this[int index] => _relocations[index]; | ||
|
||
#endregion | ||
} | ||
} |
Oops, something went wrong.