Пример #1
0
        public static void GetEmbeddedModule(ModuleReader reader)
        {
            // Read the MZ signature.
            if (reader.ReadByte() != 'M' || reader.ReadByte() != 'Z')
            {
                throw new ModuleException("Invalid PE signature.");
            }

            // Read the PE offset.
            reader.SetPosition(0x3c);
            uint peOffset = reader.ReadUInt();

            // Read the PE\0\0 sinature
            reader.SetPosition(peOffset);
            if (reader.ReadByte() != 'P' || reader.ReadByte() != 'E' ||
                reader.ReadByte() != 0 || reader.ReadByte() != 0)
            {
                throw new ModuleException("Unsupported MS DOS programs.");
            }

            // Read the COFF header.
            CoffHeader header = new CoffHeader();

            header.Read(reader);

            // Ignore the optional header.
            reader.Skip(header.optionalHeaderSize);

            // Read the sections until finding the .cbm section.
            CoffSectionHeader sectionHeader = new CoffSectionHeader();

            for (int i = 0; i < header.numSections; ++i)
            {
                // Read the section header.
                sectionHeader.Read(reader);

                // If this is the .cbm section, done.
                if (sectionHeader.name == ".cbm")
                {
                    reader.SetPosition(sectionHeader.rawDataPointer);
                    return;
                }
            }

            // Couldn't find embedded module.
            throw new ModuleException("Couldn't find embedded Chela module.");
        }
Пример #2
0
        public static void GetEmbeddedModule(ModuleReader reader)
        {
            // Read the MZ signature.
            if(reader.ReadByte() != 'M' || reader.ReadByte() != 'Z')
                throw new ModuleException("Invalid PE signature.");

            // Read the PE offset.
            reader.SetPosition(0x3c);
            uint peOffset = reader.ReadUInt();

            // Read the PE\0\0 sinature
            reader.SetPosition(peOffset);
            if(reader.ReadByte() != 'P' || reader.ReadByte() != 'E' ||
                reader.ReadByte() != 0 || reader.ReadByte() != 0)
                throw new ModuleException("Unsupported MS DOS programs.");

            // Read the COFF header.
            CoffHeader header = new CoffHeader();
            header.Read(reader);

            // Ignore the optional header.
            reader.Skip(header.optionalHeaderSize);

            // Read the sections until finding the .cbm section.
            CoffSectionHeader sectionHeader = new CoffSectionHeader();
            for(int i = 0; i < header.numSections; ++i)
            {
                // Read the section header.
                sectionHeader.Read(reader);

                // If this is the .cbm section, done.
                if(sectionHeader.name == ".cbm")
                {
                    reader.SetPosition(sectionHeader.rawDataPointer);
                    return;
                }
            }

            // Couldn't find embedded module.
            throw new ModuleException("Couldn't find embedded Chela module.");
        }
Пример #3
0
        private static void GetEmbeddedModule64(ModuleReader reader, byte[] ident)
        {
            // Read the endiannes.
            bool big = ident[(int)ElfIdent.EI_DATA] == (int)ElfData.ELFDATA2MSB;

            // Read the header.
            Elf64_Ehdr header = new Elf64_Ehdr();

            header.Read(reader, big);

            // Reject files without section names.
            if (header.e_shstrndex == (int)ElfSectionNumber.SHN_UNDEF)
            {
                throw new ModuleException("Unsupported elfs without section names");
            }

            // Read the "section names" section.
            reader.SetPosition(header.e_shoff + (ulong)header.e_shstrndex * header.e_shentsize);
            Elf64_Shdr namesHeader = new Elf64_Shdr();

            namesHeader.Read(reader, big);

            // Reject files without real section names.
            if (namesHeader.sh_size == 0)
            {
                throw new ModuleException("This elf doesn't have section names.");
            }

            // Read the name table.
            byte[] nameTable;
            reader.SetPosition(namesHeader.sh_offset);
            reader.Read(out nameTable, (int)namesHeader.sh_size);

            // Move to the section header table.
            reader.SetPosition(header.e_shoff);

            // Read the section until hit '.cbm'.
            Elf64_Shdr    sectionHeader = new Elf64_Shdr();
            bool          found         = false;
            StringBuilder builder       = new StringBuilder();

            for (int i = 0; i < header.e_shnum; ++i)
            {
                // Read the section header.
                sectionHeader.Read(reader, big);

                // Check the section name.
                if (sectionHeader.sh_name >= nameTable.Length)
                {
                    throw new ModuleException("Invalid section name.");
                }

                // Build the section name.
                builder.Length = 0;
                int pos = (int)sectionHeader.sh_name;
                while (nameTable[pos] != 0)
                {
                    builder.Append((char)nameTable[pos++]);
                }
                string sectionName = builder.ToString();

                // Compare the section name.
                if (sectionName == ".cbm")
                {
                    found = true;
                    break;
                }

                // Skip the extra data.
                reader.Skip(header.e_shentsize - Elf64_Shdr.Size);
            }

            // Make sure the section was found.
            if (!found)
            {
                throw new ModuleException("The elf doesn't have a chela module.");
            }

            // Make sure the section type is PROGBITS.
            if (sectionHeader.sh_type != (int)ElfSectionType.SHT_PROGBITS)
            {
                throw new ModuleException("The elf section that can have the module is not supported.");
            }

            // Move to the section offset.
            reader.SetPosition(sectionHeader.sh_offset);
        }
Пример #4
0
        public static ChelaModule LoadModule(ModuleReader reader, bool fullLoad)
        {
            // Try to guess the file type.
            uint moduleStart = reader.GetPosition();
            byte[] signature;
            reader.Read(out signature, 8);

            // Check for elf file type.
            bool isElf = true;
            for(int i = 0; i < 4; ++i)
            {
                if(signature[i] != ElfFormat.ElfMagic[i])
                {
                    isElf = false;
                    break;
                }
            }

            // Check for PE.
            bool isPE = signature[0] == 'M' && signature[1] == 'Z';

            // Find the module content.
            reader.SetPosition(moduleStart);
            if(isElf)
            {
                // Move to the embedded module.
                ElfFormat.GetEmbeddedModule(reader);
                reader.FixBase();
            }
            else if(isPE)
            {
                // Move to the embedded module.
                PEFormat.GetEmbeddedModule(reader);
                reader.FixBase();
            }

            // Read the module header.
            ModuleHeader header = new ModuleHeader();
            header.Read(reader);

            // Create the output module.
            ChelaModule result = new ChelaModule();

            // Read the string table.
            reader.SetPosition(header.stringTableOffset);
            for(uint i = 0; i < header.stringTableEntries; ++i)
            {
                uint id = i+1u;
                string s = reader.ReadString();
                result.stringTable.Add(s);
                result.registeredStrings.Add(s, id);
            }

            // Read myself data.
            ModuleReference modref = new ModuleReference();
            reader.SetPosition(header.moduleRefTableOffset);
            modref.Read(reader);
            result.SetName(result.GetString(modref.moduleName));

            // Read the module type.
            result.moduleType = (ModuleType)header.moduleType;

            // Read the referenced modules.
            for(uint i = 1; i < header.moduleRefTableEntries; ++i)
            {
                // Read the referenced module.
                modref.Read(reader);

                // Load it.
                ChelaModule referencedModule = LoadNamedModule(result.GetString(modref.moduleName));
                result.referencedModules.Add(referencedModule);
            }

            // Preload the members.
            reader.SetPosition(header.memberTableOffset);
            uint end = header.memberTableOffset + header.memberTableSize;
            MemberHeader mheader = new MemberHeader();
            while(reader.GetPosition() < end)
            {
                // Read the member header.
                mheader.Read(reader);

                // Skip the attributes.
                SkipAttributes(reader, mheader.memberAttributes);

                // Preload the member.
                MemberHeaderType mtype = (MemberHeaderType)mheader.memberType;
                switch(mtype)
                {
                case MemberHeaderType.Namespace:
                    Namespace.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Structure:
                    Structure.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Class:
                    Class.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Interface:
                    Interface.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Function:
                    Function.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Field:
                    FieldVariable.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.FunctionGroup:
                    FunctionGroup.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.TypeInstance:
                    StructureInstance.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Property:
                    PropertyVariable.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Event:
                    EventVariable.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.TypeName:
                    TypeNameMember.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.MemberInstance:
                case MemberHeaderType.FunctionInstance:
                    // Ignore the member instance.
                    result.memberTable.Add(null);
                    reader.Skip(mheader.memberSize);
                    break;
                case MemberHeaderType.TypeGroup:
                    TypeGroup.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Reference:
                    {
                        // Read the module id.
                        byte moduleId = reader.ReadByte();

                        // Get the referenced module.
                        ChelaModule refMod = result.GetReferenced(moduleId);

                        // Find the member there.
                        ScopeMember member = refMod.GetMember(result.GetString(mheader.memberName));
                        result.memberTable.Add(member);
                    }
                    break;
                default:
                    // Unknown member.
                    System.Console.WriteLine("add unknown member {0}", mtype);
                    result.memberTable.Add(null);
                    reader.Skip(mheader.memberSize);
                    break;
                }
            }

            // Read the type table.
            reader.SetPosition(header.typeTableOffset);
            for(uint i = 0; i < header.typeTableEntries; ++i)
            {
                // Read the type reference.
                TypeReference typeRef = new TypeReference();
                typeRef.Read(reader);

                // Try to load direct members.
                TypeKind kind = (ChelaModule.TypeKind)typeRef.typeKind;
                if(kind == TypeKind.Class || kind == TypeKind.Interface ||
                   kind == TypeKind.Structure || kind == TypeKind.Instance)
                {
                    // Store the actual type.
                    result.typeTable.Add(result.GetMember(typeRef.memberId));
                }
                else
                {
                    // Store the reference for delayed loading.
                    result.typeTable.Add(typeRef);
                }
            }

            // Read the anonymous types.
            reader.SetPosition(header.anonTypeTableOffset);
            end = header.anonTypeTableOffset + header.anonTypeTableSize;
            while(reader.GetPosition() < end)
            {
                // Read the anonymous type data.
                AnonTypeHeader anonType = new AnonTypeHeader();
                anonType.Read(reader);

                // Store it in the anonymous type table.
                result.anonymousTypes.Add(anonType);
            }

            // Now, read the actual members.
            reader.SetPosition(header.memberTableOffset);
            for(int i = 0; i < result.memberTable.Count; ++i)
            {
                // Get the preloaded member.
                ScopeMember member = result.memberTable[i];

                // Read his header.
                mheader.Read(reader);

                // Skip the attributes.
                SkipAttributes(reader, mheader.memberAttributes);

                // Read the member.
                if(member != null && mheader.memberType != (int)MemberHeaderType.Reference)
                    member.Read(reader, mheader);
                else
                    reader.Skip(mheader.memberSize); // Skip unknown members.
            }

            // The first member must be the global namespace.
            result.globalNamespace = (Namespace)result.GetMember(1);

            // Update the parent children relationship.
            result.globalNamespace.UpdateParent(null);

            // Now, perform second read pass, required by function groups.
            reader.SetPosition(header.memberTableOffset);
            for(int i = 0; i < result.memberTable.Count; ++i)
            {
                // Get the preloaded member.
                ScopeMember member = result.memberTable[i];

                // Read his header.
                mheader.Read(reader);

                // Skip the attributes.
                SkipAttributes(reader, mheader.memberAttributes);

                // Read the member.
                if(member != null && mheader.memberType != (int)MemberHeaderType.Reference)
                    member.Read2(reader, mheader);
                else
                    reader.Skip(mheader.memberSize); // Skip unknown members.
            }

            // Finish all of the loading.
            result.globalNamespace.FinishLoad();

            // Register the member names.
            for(int i = 0; i < result.memberTable.Count; ++i)
            {
                ScopeMember member = result.memberTable[i];
                if(member != null)
                    result.memberNameTable[member.GetFullName()] = member;
            }

            // Load the runtime classes.
            if(result.referencedModules.Count == 0)
                result.LoadRuntimeReferences(result);

            // Dump the readed module.
            //result.Dump();

            // Return the result module.
            return result;
        }
Пример #5
0
        private static void GetEmbeddedModule64(ModuleReader reader, byte[] ident)
        {
            // Read the endiannes.
            bool big = ident[(int)ElfIdent.EI_DATA] == (int)ElfData.ELFDATA2MSB;

            // Read the header.
            Elf64_Ehdr header = new Elf64_Ehdr();
            header.Read(reader, big);

            // Reject files without section names.
            if(header.e_shstrndex == (int)ElfSectionNumber.SHN_UNDEF)
                throw new ModuleException("Unsupported elfs without section names");

            // Read the "section names" section.
            reader.SetPosition(header.e_shoff + (ulong)header.e_shstrndex*header.e_shentsize);
            Elf64_Shdr namesHeader = new Elf64_Shdr();
            namesHeader.Read(reader, big);

            // Reject files without real section names.
            if(namesHeader.sh_size == 0)
                throw new ModuleException("This elf doesn't have section names.");

            // Read the name table.
            byte[] nameTable;
            reader.SetPosition(namesHeader.sh_offset);
            reader.Read(out nameTable, (int)namesHeader.sh_size);

            // Move to the section header table.
            reader.SetPosition(header.e_shoff);

            // Read the section until hit '.cbm'.
            Elf64_Shdr sectionHeader = new Elf64_Shdr();
            bool found = false;
            StringBuilder builder = new StringBuilder();
            for(int i = 0; i < header.e_shnum; ++i)
            {
                // Read the section header.
                sectionHeader.Read(reader, big);

                // Check the section name.
                if(sectionHeader.sh_name >= nameTable.Length)
                    throw new ModuleException("Invalid section name.");

                // Build the section name.
                builder.Length = 0;
                int pos = (int)sectionHeader.sh_name;
                while(nameTable[pos] != 0)
                    builder.Append((char)nameTable[pos++]);
                string sectionName = builder.ToString();

                // Compare the section name.
                if(sectionName == ".cbm")
                {
                    found = true;
                    break;
                }

                // Skip the extra data.
                reader.Skip(header.e_shentsize - Elf64_Shdr.Size);
            }

            // Make sure the section was found.
            if(!found)
                throw new ModuleException("The elf doesn't have a chela module.");

            // Make sure the section type is PROGBITS.
            if(sectionHeader.sh_type != (int)ElfSectionType.SHT_PROGBITS)
                throw new ModuleException("The elf section that can have the module is not supported.");

            // Move to the section offset.
            reader.SetPosition(sectionHeader.sh_offset);
        }