Esempio n. 1
0
        private static bool TryGetSimilarSymbol(ImportedSymbol symbol, IImportedModule module, out ImportedSymbol existingSymbol)
        {
            for (int i = 0; i < module.Symbols.Count; i++)
            {
                var s = module.Symbols[i];
                if (symbol.IsImportByName != s.IsImportByName)
                {
                    continue;
                }

                if (symbol.IsImportByName)
                {
                    if (symbol.Name == s.Name)
                    {
                        existingSymbol = s;
                        return(true);
                    }
                }
                else // if (symbol.IsImportByOrdinal)
                {
                    if (symbol.Ordinal == s.Ordinal)
                    {
                        existingSymbol = s;
                        return(true);
                    }
                }
            }

            existingSymbol = null;
            return(false);
        }
Esempio n. 2
0
        public void DuplicateImportedSymbolsShouldResultInSameImportInImage()
        {
            // Create native body.
            var body = CreateDummyBody(true, false);

            body.Code = new byte[]
            {
                /* 00: */ 0x48, 0x83, 0xEC, 0x28,                     // sub rsp, 0x28
                /* 04: */ 0x48, 0x8D, 0x0D, 0x18, 0x00, 0x00, 0x00,   // lea rcx, [rel str]
                /* 0B: */ 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00,         // call [rel puts]
                /* 11: */ 0x48, 0x8D, 0x0D, 0x0B, 0x00, 0x00, 0x00,   // lea rcx, [rel str]
                /* 18: */ 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00,         // call [rel puts]
                /* 24: */ 0xC3,                                       // ret

                // str:
                0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x66,   // "Hello f"
                0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65,   // "rom the"
                0x20, 0x75, 0x6e, 0x6d, 0x61, 0x6e, 0x61,   // "unmanag"
                0x67, 0x65, 0x64, 0x20, 0x77, 0x6f, 0x72,   // "ed worl"
                0x6c, 0x64, 0x21, 0x00                      // "d!"
            };

            // Add reference to ucrtbased.dll!puts at offset 0xD.
            var ucrtbased1 = new ImportedModule("ucrtbased.dll");
            var puts1      = new ImportedSymbol(0x4fc, "puts");

            ucrtbased1.Symbols.Add(puts1);
            body.AddressFixups.Add(new AddressFixup(
                                       0xD, AddressFixupType.Relative32BitAddress, puts1
                                       ));

            // Add second (duplicated) reference to ucrtbased.dll!puts at offset 0x20.
            var ucrtbased2 = new ImportedModule("ucrtbased.dll");
            var puts2      = new ImportedSymbol(0x4fc, "puts");

            ucrtbased2.Symbols.Add(puts2);
            body.AddressFixups.Add(new AddressFixup(
                                       0x20, AddressFixupType.Relative32BitAddress, puts2
                                       ));

            // Serialize module to PE image.
            var module = body.Owner.Module;
            var image  = module.ToPEImage();

            // Verify import is added to PE image.
            var importedModule = Assert.Single(image.Imports);

            Assert.NotNull(importedModule);
            Assert.Equal(ucrtbased1.Name, importedModule.Name);
            var importedSymbol = Assert.Single(importedModule.Symbols);

            Assert.NotNull(importedSymbol);
            Assert.Equal(puts1.Name, importedSymbol.Name);
        }
        public void NativeBodyWithCall()
        {
            Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), NonWindowsPlatform);
            Skip.IfNot(Environment.Is64BitOperatingSystem, Non64BitPlatform);

            // Read image
            var image = PEImage.FromBytes(Properties.Resources.TheAnswer_NetFx);

            var module = new ImportedModule("api-ms-win-crt-stdio-l1-1-0.dll");

            image.Imports.Add(module);

            var function = new ImportedSymbol(0x4fc, "puts");

            module.Symbols.Add(function);

            var body = new CodeSegment(image.ImageBase, new byte[]
            {
                /* 00: */ 0x48, 0x83, 0xEC, 0x28,                     // sub rsp, 0x28
                /* 04: */ 0x48, 0x8D, 0x0D, 0x10, 0x00, 0x00, 0x00,   // lea rcx, qword [rel str]
                /* 0B: */ 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00,         // call qword [rel puts]
                /* 11: */ 0xB8, 0x37, 0x13, 0x00, 0x00,               // mov eax, 0x1337
                /* 16: */ 0x48, 0x83, 0xC4, 0x28,                     // add rsp, 0x28
                /* 1A: */ 0xC3,                                       // ret

                // str:
                0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x66,   // "Hello f"
                0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65,   // "rom the"
                0x20, 0x75, 0x6e, 0x6d, 0x61, 0x6e, 0x61,   // " unmana"
                0x67, 0x65, 0x64, 0x20, 0x77, 0x6f, 0x72,   // "ged wor"
                0x6c, 0x64, 0x21, 0x00                      // "ld!"
            });

            // Fixup puts call.
            body.AddressFixups.Add(new AddressFixup(
                                       0xD, AddressFixupType.Relative32BitAddress, function
                                       ));

            // Replace body.
            ReplaceBodyWithNativeCode(image, body, false);

            // Rebuild
            var builder = new ManagedPEFileBuilder();
            var peFile  = builder.CreateFile(image);

            // Verify
            string expectedOutput = "Hello from the unmanaged world!\r\nThe answer to life, universe and everything is 4919\r\n";

            _fixture
            .GetRunner <FrameworkPERunner>()
            .RebuildAndRun(peFile, "TheAnswer", expectedOutput);
        }
        public void NativeBodyWithCallX86()
        {
            Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), NonWindowsPlatform);

            // Read image
            var image = PEImage.FromBytes(Properties.Resources.TheAnswer_NetFx);

            var module = new ImportedModule("api-ms-win-crt-stdio-l1-1-0.dll");

            image.Imports.Add(module);

            var function = new ImportedSymbol(0x4fc, "puts");

            module.Symbols.Add(function);

            var body = new CodeSegment(image.ImageBase, new byte[]
            {
                /* 00: */ 0x55,                                  // push ebp
                /* 01: */ 0x89, 0xE5,                            // mov ebp,esp
                /* 03: */ 0x6A, 0x6F,                            // push byte +0x6f         ; H
                /* 05: */ 0x68, 0x48, 0x65, 0x6C, 0x6C,          // push dword 0x6c6c6548   ; ello
                /* 0A: */ 0x54,                                  // push esp
                /* 0B: */ 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00,    // call [dword puts]
                /* 11: */ 0x83, 0xC4, 0x0C,                      // add esp,byte +0xc
                /* 14: */ 0xB8, 0x37, 0x13, 0x00, 0x00,          // mov eax,0x1337
                /* 19: */ 0x5D,                                  // pop ebp
                /* 1A: */ 0xC3,                                  // ret
            });

            // Fix up puts call.
            body.AddressFixups.Add(new AddressFixup(
                                       0xD, AddressFixupType.Absolute32BitAddress, function
                                       ));
            image.Relocations.Clear();
            image.Relocations.Add(new BaseRelocation(RelocationType.HighLow, new RelativeReference(body, 0xD)));

            // Replace body.
            ReplaceBodyWithNativeCode(image, body, true);

            // Rebuild
            var builder = new ManagedPEFileBuilder();
            var peFile  = builder.CreateFile(image);

            // Verify
            string expectedOutput = "Hello\r\nThe answer to life, universe and everything is 4919\r\n";

            _fixture
            .GetRunner <FrameworkPERunner>()
            .RebuildAndRun(peFile, "TheAnswer", expectedOutput);
        }
Esempio n. 5
0
        /// <summary>
        /// Creates a thunk for the specified member, and adds it to the table.
        /// </summary>
        /// <param name="entry">The member to add.</param>
        public void AddMember(ImportedSymbol entry)
        {
            uint relativeOffset = _length - ThunkSize;

            if (_isIat)
            {
                entry.AddressTableEntry = new RelativeReference(this, (int)relativeOffset);
            }

            _memberOffsets.Add(entry, relativeOffset);
            _members.Add(entry);

            _length += ThunkSize;
        }
Esempio n. 6
0
        public TypeScriptVariableReference AddDefaultSymbolImport(string localName, string path)
        {
            var importedSymbol = new ImportedSymbol("default", localName, path);

            if (!symbolImports.ContainsKey(importedSymbol))
            {
                symbolImports.Add(importedSymbol, new TypeScriptImportDefaultFromPathStatement
                {
                    TypeName    = localName,
                    CurrentUnit = this,
                    PathToUnit  = path,
                });
            }
            return(new TypeScriptVariableReference(localName));
        }
Esempio n. 7
0
        public void Native32BitMethodShouldResultInBaseRelocation()
        {
            // Create native body.
            var body = CreateDummyBody(false, true);

            body.Code = new byte[]
            {
                /* 00: */ 0x55,                                  // push ebp
                /* 01: */ 0x89, 0xE5,                            // mov ebp,esp
                /* 03: */ 0x6A, 0x6F,                            // push byte +0x6f         ; H
                /* 05: */ 0x68, 0x48, 0x65, 0x6C, 0x6C,          // push dword 0x6c6c6548   ; ello
                /* 0A: */ 0x54,                                  // push esp
                /* 0B: */ 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00,    // call [dword puts]
                /* 11: */ 0x83, 0xC4, 0x0C,                      // add esp,byte +0xc
                /* 14: */ 0xB8, 0x37, 0x13, 0x00, 0x00,          // mov eax,0x1337
                /* 19: */ 0x5D,                                  // pop ebp
                /* 1A: */ 0xC3,                                  // ret
            };

            // Fix up reference to ucrtbased.dll!puts
            var ucrtbased = new ImportedModule("ucrtbased.dll");
            var puts      = new ImportedSymbol(0x4fc, "puts");

            ucrtbased.Symbols.Add(puts);

            body.AddressFixups.Add(new AddressFixup(
                                       0xD, AddressFixupType.Absolute32BitAddress, puts
                                       ));

            // Serialize module to PE image.
            var module = body.Owner.Module;
            var image  = module.ToPEImage();

            // Verify import is added to PE image.
            Assert.Contains(image.Imports, m =>
                            m.Name == ucrtbased.Name && m.Symbols.Any(s => s.Name == puts.Name));

            // Verify relocation is added.
            var segment = GetNewCodeSegment(image);

            Assert.Contains(image.Relocations, r =>
                            r.Location is RelativeReference relativeRef &&
                            relativeRef.Base == segment &&
                            relativeRef.Offset == 0xD);
        }
Esempio n. 8
0
        public void NativeMethodBodyImportedSymbolShouldEndUpInImportsDirectory()
        {
            // Create native body.
            var body = CreateDummyBody(false, false);

            body.Code = new byte[]
            {
                /* 00: */ 0x48, 0x83, 0xEC, 0x28,                     // sub rsp, 0x28
                /* 04: */ 0x48, 0x8D, 0x0D, 0x10, 0x00, 0x00, 0x00,   // lea rcx, [rel str]
                /* 0B: */ 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00,         // call [rel puts]
                /* 11: */ 0xB8, 0x37, 0x13, 0x00, 0x00,               // mov eax, 0x1337
                /* 16: */ 0x48, 0x83, 0xC4, 0x28,                     // add rsp, 0x28
                /* 1A: */ 0xC3,                                       // ret

                // str:
                0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x66,   // "Hello f"
                0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65,   // "rom the"
                0x20, 0x75, 0x6e, 0x6d, 0x61, 0x6e, 0x61,   // "unmanag"
                0x67, 0x65, 0x64, 0x20, 0x77, 0x6f, 0x72,   // "ed worl"
                0x6c, 0x64, 0x21, 0x00                      // "d!"
            };

            // Fix up reference to ucrtbased.dll!puts
            var ucrtbased = new ImportedModule("ucrtbased.dll");
            var puts      = new ImportedSymbol(0x4fc, "puts");

            ucrtbased.Symbols.Add(puts);

            body.AddressFixups.Add(new AddressFixup(
                                       0xD, AddressFixupType.Relative32BitAddress, puts
                                       ));

            // Serialize module to PE image.
            var module = body.Owner.Module;
            var image  = module.ToPEImage();

            // Verify import is added to PE image.
            Assert.Contains(image.Imports, m =>
                            m.Name == ucrtbased.Name && m.Symbols.Any(s => s.Name == puts.Name));
        }
Esempio n. 9
0
        private ImportedSymbol GetImportedSymbol(ImportedSymbol symbol)
        {
            if (symbol.DeclaringModule is null)
            {
                throw new ArgumentException($"Symbol {symbol} is not added to a module.");
            }

            // Find declaring module.
            var module = GetModuleByName(symbol.DeclaringModule.Name);

            // See if we have already imported this symbol before.
            if (TryGetSimilarSymbol(symbol, module, out var existing))
            {
                return(existing);
            }

            // If not, create a copy of the symbol and register it.
            var newSymbol = symbol.IsImportByName
                ? new ImportedSymbol(symbol.Hint, symbol.Name)
                : new ImportedSymbol(symbol.Ordinal);

            module.Symbols.Add(newSymbol);
            return(newSymbol);
        }
 /// <summary>
 /// Obtains the relative virtual address of the thunk associated to an imported member in the thunk table.
 /// </summary>
 /// <param name="member">The member to get the thunk entry RVA for.</param>
 /// <returns>The virtual address</returns>
 /// <remarks>
 /// This method should only be used after the thunk table has been relocated to the right location in the
 /// PE file.
 /// </remarks>
 public uint GetMemberThunkRva(ImportedSymbol member) => Rva + _memberOffsets[member];
 /// <summary>
 /// Creates a thunk for the specified member, and adds it to the table.
 /// </summary>
 /// <param name="entry">The member to add.</param>
 public void AddMember(ImportedSymbol entry)
 {
     _memberOffsets.Add(entry, _length - ThunkSize);
     _members.Add(entry);
     _length += ThunkSize;
 }
Esempio n. 12
0
 private bool Equals(ImportedSymbol other)
 {
     return(string.Equals(SourceName, other.SourceName) && string.Equals(LocalName, other.LocalName) && string.Equals(Path, other.Path));
 }
 /// <summary>
 /// Gets the virtual address to the beginning of the hint-name pair associated to an imported member.
 /// </summary>
 /// <param name="member">The member to obtain the hint-name RVA for.</param>
 /// <returns>The virtual address.</returns>
 /// <remarks>
 /// This method should only be used after the hint-name table has been relocated to the right location in the
 /// PE file.
 /// </remarks>
 public uint GetHintNameRva(ImportedSymbol member) => Rva + _hintNameOffsets[member];