protected override ImportFunction[] ParseTarget() { if (_importDescriptors == null) { return(null); } var impFuncs = new List <ImportFunction>(); var sizeOfThunk = (uint)(_is64Bit ? 0x8 : 0x4); // Size of IMAGE_THUNK_DATA var ordinalBit = _is64Bit ? 0x8000000000000000 : 0x80000000; var ordinalMask = (ulong)(_is64Bit ? 0x7FFFFFFFFFFFFFFF : 0x7FFFFFFF); foreach (var idesc in _importDescriptors) { var dllAdr = idesc.Name.RVAtoFileMapping(_sectionHeaders); var dll = _buff.GetCString(dllAdr); if (IsModuleNameTooLong(dll)) { continue; } var tmpAdr = idesc.OriginalFirstThunk != 0 ? idesc.OriginalFirstThunk : idesc.FirstThunk; if (tmpAdr == 0) { continue; } var thunkAdr = tmpAdr.RVAtoFileMapping(_sectionHeaders); uint round = 0; while (true) { var t = new IMAGE_THUNK_DATA(_buff, thunkAdr + round * sizeOfThunk, _is64Bit); if (t.AddressOfData == 0) { break; } // Check if import by name or by ordinal. // If it is an import by ordinal, the most significant bit of "Ordinal" is "1" and the ordinal can // be extracted from the least significant bits. // Else it is an import by name and the link to the IMAGE_IMPORT_BY_NAME has to be followed if ((t.Ordinal & ordinalBit) == ordinalBit) // Import by ordinal { impFuncs.Add(new ImportFunction(null, dll, (ushort)(t.Ordinal & ordinalMask))); } else // Import by name { var ibn = new IMAGE_IMPORT_BY_NAME(_buff, ((uint)t.AddressOfData).RVAtoFileMapping(_sectionHeaders)); impFuncs.Add(new ImportFunction(ibn.Name, dll, ibn.Hint)); } round++; } } return(impFuncs.ToArray()); }
public void ImageThunkData64ConstructorWorks_Test() { var thunkData64 = new IMAGE_THUNK_DATA(RawStructures.RawThunkData64, 2, true); Assert.Equal((ulong)0x7766554433221100, thunkData64.AddressOfData); Assert.Equal((ulong)0x7766554433221100, thunkData64.ForwarderString); Assert.Equal((ulong)0x7766554433221100, thunkData64.Function); Assert.Equal((ulong)0x7766554433221100, thunkData64.Ordinal); }
public void ImageThunkData32ConstructorWorks_Test() { var thunkData32 = new IMAGE_THUNK_DATA(RawStructures.RawThunkData32, 2, false); Assert.Equal((ulong)0x33221100, thunkData32.AddressOfData); Assert.Equal((ulong)0x33221100, thunkData32.ForwarderString); Assert.Equal((ulong)0x33221100, thunkData32.Function); Assert.Equal((ulong)0x33221100, thunkData32.Ordinal); }
static IntPtr GetThunk(IntPtr ModuleHandle, string intermodName, string funcName) { IntPtr rval = IntPtr.Zero; IntPtr iidPtr = IntPtr.Zero; IMAGE_DOS_HEADER idh; idh = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(ModuleHandle, typeof(IMAGE_DOS_HEADER)); if (idh.isValid) { IMAGE_NT_HEADERS32 inh32; IMAGE_NT_HEADERS64 inh64; inh32 = (IMAGE_NT_HEADERS32)Marshal.PtrToStructure(IntPtr.Add(ModuleHandle, idh.e_lfanew), typeof(IMAGE_NT_HEADERS32)); inh64 = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(IntPtr.Add(ModuleHandle, idh.e_lfanew), typeof(IMAGE_NT_HEADERS64)); if (inh32.isValid && inh32.OptionalHeader.ImportTable.VirtualAddress != 0) { iidPtr = IntPtr.Add(ModuleHandle, (int)inh32.OptionalHeader.ImportTable.VirtualAddress); } else if (inh64.isValid && inh64.OptionalHeader.ImportTable.VirtualAddress != 0) { iidPtr = IntPtr.Add(ModuleHandle, (int)inh64.OptionalHeader.ImportTable.VirtualAddress); } } if (iidPtr != IntPtr.Zero) { IMAGE_IMPORT_DESCRIPTOR iid = (IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure(iidPtr, typeof(IMAGE_IMPORT_DESCRIPTOR)); while (iid.Name != 0) { string iidName = Marshal.PtrToStringAnsi(IntPtr.Add(ModuleHandle, (int)iid.Name)); if (string.Compare(iidName, intermodName, true) == 0) { // this probably won't work for 64-bit processes as the thunk data structure is different IntPtr itdPtr = IntPtr.Add(ModuleHandle, (int)iid.FirstThunk); IntPtr oitdPtr = IntPtr.Add(ModuleHandle, (int)iid.OriginalFirstThunk); while (itdPtr != IntPtr.Zero && oitdPtr != IntPtr.Zero) { IMAGE_THUNK_DATA itd = (IMAGE_THUNK_DATA)Marshal.PtrToStructure(itdPtr, typeof(IMAGE_THUNK_DATA)); IMAGE_THUNK_DATA oitd = (IMAGE_THUNK_DATA)Marshal.PtrToStructure(oitdPtr, typeof(IMAGE_THUNK_DATA)); IntPtr iibnPtr = IntPtr.Add(ModuleHandle, (int)oitd.AddressOfData); IMAGE_IMPORT_BY_NAME iibn = (IMAGE_IMPORT_BY_NAME)Marshal.PtrToStructure(iibnPtr, typeof(IMAGE_IMPORT_BY_NAME)); string iibnName = Marshal.PtrToStringAnsi(IntPtr.Add(iibnPtr, Marshal.OffsetOf(typeof(IMAGE_IMPORT_BY_NAME), "Name").ToInt32())); if (string.Compare(iibnName, funcName, true) == 0) { rval = new IntPtr(itd.Function); break; } itdPtr = IntPtr.Add(itdPtr, Marshal.SizeOf(typeof(IMAGE_THUNK_DATA))); oitdPtr = IntPtr.Add(oitdPtr, Marshal.SizeOf(typeof(IMAGE_THUNK_DATA))); } break; } iidPtr = IntPtr.Add(iidPtr, Marshal.SizeOf(typeof(IMAGE_IMPORT_DESCRIPTOR))); iid = (IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure(iidPtr, typeof(IMAGE_IMPORT_DESCRIPTOR)); } } return(rval); }