internal static VTableFixupEntry Load(IBinaryAccessor accessor, PEImage pe) { var fixup = new VTableFixupEntry(); // In this definition, RVA points to the location of the v-table slot containing the method token(s). uint rva = accessor.ReadUInt32(); // Indicating the number of v-table slots grouped into one entry because their flags are identical. // This grouping has no effect other than saving some space�you can emit a single slot per entry, // but then you�ll have to emit as many v-table fixups as there are slots. int count = accessor.ReadUInt16(); fixup._type = (VTableFixupType)accessor.ReadUInt16(); bool is32Bits = ((fixup.Type & VTableFixupType.SlotSize32Bit) == VTableFixupType.SlotSize32Bit); // Save position long position = accessor.Position; accessor.Position = pe.ResolvePositionToSectionData(rva); for (int i = 0; i < count; i++) { fixup._list.Add(accessor.ReadInt32()); if (!is32Bits) { accessor.ReadUInt32(); } } // Restore position accessor.Position = position; return(fixup); }
private void BuildAMD64(BuildEntry entry) { int methodRID = _state.MethodDefHash.IndexOf(entry.MethodSignature) + 1; // Add fixup entry var fixup = new VTableFixupEntry(); fixup.Type = VTableFixupType.SlotSize64Bit | VTableFixupType.FromUnmanaged; fixup.Add(MetadataToken.Get(MetadataTokenType.Method, methodRID)); _state.VTableFixupTable.Add(fixup); int pos = _codeBlob.Length; if (pos > 0) { pos = pos.Align(0x10); } PE.Fixups.Add(new AMD64Fixup(_codeBlob, pos, fixup)); // rex.w rex.b mov rax,[following address] _state.ExportTable.AddRVAEntry(entry.MethodName, _codeBlob, pos); _codeBlob.Write(ref pos, new byte[] { 0x48, 0xA1 }); // VA of method (through VTable) _state.RelocTable.Add(_codeBlob, pos, BaseRelocationType.DIR64); _codeBlob.Write(ref pos, (ulong)0); // jmp [rax] _codeBlob.Write(ref pos, new byte[] { 0xFF, 0xE0 }); }
private void BuildX86(BuildEntry entry) { int methodRID = _state.MethodDefHash.IndexOf(entry.MethodSignature) + 1; // Add fixup entry var fixup = new VTableFixupEntry(); fixup.Type = VTableFixupType.SlotSize32Bit | VTableFixupType.FromUnmanaged; fixup.Add(MetadataToken.Get(MetadataTokenType.Method, methodRID)); _state.VTableFixupTable.Add(fixup); int pos = _codeBlob.Length; if (pos > 0) { pos = pos.Align(0x10); } PE.Fixups.Add(new X86Fixup(_codeBlob, pos, fixup)); // jmp _state.ExportTable.AddRVAEntry(entry.MethodName, _codeBlob, pos); _codeBlob.Write(ref pos, new byte[] { 0xFF, 0x25 }); // VA of method (through VTable) _state.RelocTable.Add(_codeBlob, pos, BaseRelocationType.HIGHLOW); _codeBlob.Write(ref pos, (uint)0); }
public VTableFixupEntry Clone() { var copy = new VTableFixupEntry(); CopyTo(copy); return(copy); }
protected void CopyTo(VTableFixupEntry copy) { copy._type = _type; foreach (var childNode in _list) { copy._list.Add(childNode); } }
public int GetFixupOffset(VTableFixupEntry searchFixup) { int offset = 0; foreach (var fixup in _table) { if (object.ReferenceEquals(fixup, searchFixup)) { return(offset); } int size = ((fixup.Type & VTableFixupType.SlotSize32Bit) == VTableFixupType.SlotSize32Bit) ? 4 : 8; offset += (fixup.Count * size); } throw new InvalidOperationException(); }
private void BuildIA64(BuildEntry entry) { int methodRID = _state.MethodDefHash.IndexOf(entry.MethodSignature) + 1; // Add fixup entry var fixup = new VTableFixupEntry(); fixup.Type = VTableFixupType.SlotSize64Bit | VTableFixupType.FromUnmanaged; fixup.Add(MetadataToken.Get(MetadataTokenType.Method, methodRID)); _state.VTableFixupTable.Add(fixup); int pos = _codeBlob.Length; if (pos > 0) { pos = pos.Align(0x10); } PE.Fixups.Add(new IA64Fixup(_codeBlob, pos, fixup)); // IA64 stub // ld8 r9 = [gp] ;; // ld8 r10 = [r9],8 // nop.i ;; // ld8 gp = [r9] // mov b6 = r10 // br.cond.sptk.few b6 _codeBlob.Write(ref pos, new byte[] { 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40, 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50, 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00, }); // VA of IA64 stub _state.ExportTable.AddRVAEntry(entry.MethodName, _codeBlob, pos); _state.RelocTable.Add(_codeBlob, pos, BaseRelocationType.DIR64); _codeBlob.Write(ref pos, (ulong)0); // VA of method (through VTable) _state.RelocTable.Add(_codeBlob, pos, BaseRelocationType.DIR64); _codeBlob.Write(ref pos, (ulong)0); }
public AMD64Fixup(BuildBlob codeBlob, int codeBlobPos, VTableFixupEntry fixup) { _codeBlob = codeBlob; _codeBlobPos = codeBlobPos; _fixup = fixup; }