Beispiel #1
0
        private static readonly byte[] FeatureBytes2 = { 0x78, 0x44, 0x79, 0x44 }; //ADD R0, PC and ADD R1, PC


        public Macho(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
        {
            Is32Bit   = true;
            Position += 16; //skip magic, cputype, cpusubtype, filetype
            var ncmds = ReadUInt32();

            Position += 8; //skip sizeofcmds, flags
            for (var i = 0; i < ncmds; i++)
            {
                var pos     = Position;
                var cmd     = ReadUInt32();
                var cmdsize = ReadUInt32();
                if (cmd == 1)       //LC_SEGMENT
                {
                    Position += 40; //skip segname, vmaddr, vmsize, fileoff, filesize, maxprot, initprot
                    var nsects = ReadUInt32();
                    Position += 4;  //skip flags
                    for (var j = 0; j < nsects; j++)
                    {
                        var section = new MachoSection();
                        sections.Add(section);
                        section.sectname = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0');
                        Position        += 16; //skip segname
                        section.addr     = ReadUInt32();
                        section.size     = ReadUInt32();
                        section.offset   = ReadUInt32();
                        Position        += 12; //skip align, reloff, nreloc
                        section.flags    = ReadUInt32();
                        section.end      = section.addr + section.size;
                        Position        += 8; //skip reserved1, reserved2
                    }
                }
                Position = pos + cmdsize;//next
            }
        }
Beispiel #2
0
        public Macho(Stream stream, Action <string> reportProgressAction) : base(stream, reportProgressAction)
        {
            Is32Bit   = true;
            Position += 16; //skip magic, cputype, cpusubtype, filetype
            var ncmds = ReadUInt32();

            Position += 8; //skip sizeofcmds, flags
            for (var i = 0; i < ncmds; i++)
            {
                var pos     = Position;
                var cmd     = ReadUInt32();
                var cmdsize = ReadUInt32();
                switch (cmd)
                {
                case 1:                      //LC_SEGMENT
                    var segname = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0');
                    if (segname == "__TEXT") //__PAGEZERO
                    {
                        vmaddr = ReadUInt32();
                    }
                    else
                    {
                        Position += 4;
                    }
                    Position += 20;    //skip vmsize, fileoff, filesize, maxprot, initprot
                    var nsects = ReadUInt32();
                    Position += 4;     //skip flags
                    for (var j = 0; j < nsects; j++)
                    {
                        var section = new MachoSection();
                        sections.Add(section);
                        section.sectname = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0');
                        Position        += 16; //skip segname
                        section.addr     = ReadUInt32();
                        section.size     = ReadUInt32();
                        section.offset   = ReadUInt32();
                        Position        += 12; //skip align, reloff, nreloc
                        section.flags    = ReadUInt32();
                        section.end      = section.addr + section.size;
                        Position        += 8; //skip reserved1, reserved2
                    }
                    break;

                case 0x21:     //LC_ENCRYPTION_INFO
                    Position += 8;
                    var cryptID = ReadUInt32();
                    if (cryptID != 0)
                    {
                        reportProgressAction("ERROR: This Mach-O executable is encrypted and cannot be processed.");
                    }
                    break;
                }
                Position = pos + cmdsize;//next
            }
        }
Beispiel #3
0
        private uint FindReference(uint pointer, MachoSection search)
        {
            var searchend = search.offset + search.size;

            Position = search.offset;
            while (Position < searchend)
            {
                if (ReadUInt32() == pointer)
                {
                    return((uint)Position - search.offset + search.address);//MapRATV
                }
            }
            return(0);
        }
Beispiel #4
0
        private uint FindCodeRegistration(int count, MachoSection search, MachoSection search2, MachoSection range)
        {
            var searchend  = search.offset + search.size;
            var rangeend   = range.address + range.size;
            var search2end = search2 == null ? 0 : search2.offset + search2.size;

            Position = search.offset;
            while (Position < searchend)
            {
                var add = Position;
                if (ReadUInt32() == count)
                {
                    try
                    {
                        uint pointers = MapVATR(ReadUInt32());
                        if (pointers >= search.offset && pointers <= searchend)
                        {
                            var np   = Position;
                            var temp = ReadClassArray <uint>(pointers, count);
                            var r    = Array.FindIndex(temp, x => x <range.address || x> rangeend);
                            if (r == -1)
                            {
                                return((uint)add - search.offset + search.address);//MapRATV
                            }
                            Position = np;
                        }
                        else if (search2 != null && pointers >= search2.offset && pointers <= search2end)
                        {
                            var np   = Position;
                            var temp = ReadClassArray <uint>(pointers, count);
                            var r    = Array.FindIndex(temp, x => x <range.address || x> rangeend);
                            if (r == -1)
                            {
                                return((uint)add - search.offset + search.address);//MapRATV
                            }
                            Position = np;
                        }
                    }
                    catch
                    {
                        // ignored
                    }
                }
            }
            return(0);
        }
Beispiel #5
0
        private uint FindMetadataRegistration(int typeDefinitionsCount, MachoSection search, MachoSection search2, MachoSection range)
        {
            var searchend  = search.offset + search.size;
            var rangeend   = range.address + range.size;
            var search2end = search2 == null ? 0 : search2.offset + search2.size;

            Position = search.offset;
            while (Position < searchend)
            {
                var add = Position;
                if (ReadUInt32() == typeDefinitionsCount)
                {
                    try
                    {
                        var np = Position;
                        Position += 8;
                        uint pointers = MapVATR(ReadUInt32());
                        if (pointers >= search.offset && pointers <= searchend)
                        {
                            var temp = ReadClassArray <uint>(pointers, maxMetadataUsages);
                            var r    = Array.FindIndex(temp, x => x <range.address || x> rangeend);
                            if (r == -1)
                            {
                                return((uint)add - 48u - search.offset + search.address); //VirtualAddress
                            }
                        }
                        else if (search2 != null && pointers >= search2.offset && pointers <= search2end)
                        {
                            var temp = ReadClassArray <uint>(pointers, maxMetadataUsages);
                            var r    = Array.FindIndex(temp, x => x <range.address || x> rangeend);
                            if (r == -1)
                            {
                                return((uint)add - 48u - search.offset + search.address); //VirtualAddress
                            }
                        }
                        Position = np;
                    }
                    catch
                    {
                        // ignored
                    }
                }
            }
            return(0);
        }
Beispiel #6
0
        private uint FindPointersDesc(long readCount, MachoSection search, MachoSection range)
        {
            var add       = 0;
            var searchend = search.offset + search.size;
            var rangeend  = range.address + range.size;

            while (searchend + add > search.offset)
            {
                var temp = ReadClassArray <int>(searchend + add - 4 * readCount, readCount);
                var r    = Array.FindIndex(temp, x => x <range.address || x> rangeend);
                if (r != -1)
                {
                    add -= (int)((readCount - r) * 4);
                }
                else
                {
                    return((uint)(search.address + search.size + add - 4 * readCount));//MapRATV
                }
            }
            return(0);
        }
Beispiel #7
0
        private uint FindPointersAsc(long readCount, MachoSection search, MachoSection range)
        {
            var add       = 0;
            var searchend = search.offset + search.size;
            var rangeend  = range.address + range.size;

            while (search.offset + add < searchend)
            {
                var temp = ReadClassArray <int>(search.offset + add, readCount);
                var r    = Array.FindLastIndex(temp, x => x <range.address || x> rangeend);
                if (r != -1)
                {
                    add += ++r * 4;
                }
                else
                {
                    return(search.address + (uint)add);//MapRATV
                }
            }
            return(0);
        }