Esempio n. 1
0
        public static void Create(Xbox box, Thread thread)
        {
            var copy    = box.Tls.TlsEnd - box.Tls.TlsStart;
            var tlsAddr = box.MemoryAllocator.Allocate(copy + box.Tls.TlsZerofill + 0xF) + 4;

            while ((tlsAddr & 0xF) != 0)
            {
                tlsAddr++;
            }
            tlsAddr -= 4;
            Console.WriteLine($"TLS is at {tlsAddr:X}-{tlsAddr + copy + box.Tls.TlsZerofill:X}");
            var tls  = new GuestMemory <byte>(tlsAddr);
            var gtls = new GuestMemory <byte>(box.Tls.TlsStart);

            for (var i = 0; i < copy; ++i)
            {
                tls[i] = gtls[i];
            }
            for (var i = 0; i < box.Tls.TlsZerofill; ++i)
            {
                tls[(int)copy + i] = 0;
            }

            var ethread =
                box.New(new Ethread {
                UniqueThread = thread.Id, Kthread = new Kthread {
                    TlsData = tlsAddr
                }
            });
            var tib = box.New <Kpcr>();

            tib.Value = new Kpcr {
                NtTib = new NtTib {
                    StackBase = tlsAddr, Self = tib
                },
                Self     = tib,
                Prcb     = tib + 0x28,
                PrcbData = new Kprcb {
                    CurrentThread = ethread
                }
            };
            Debug.Assert(tib.Value.NtTib.Self == tib);

            guest <uint>(box.Tls.TlsIndexAddr).Value = 0;            // XXX: HUGE HACK

            thread.Tib = tib;
        }
Esempio n. 2
0
        public (uint EntryPoint, uint TlsStart, uint TlsEnd, uint TlsZerofill, uint TlsIndexAddr) Load(CpuCore cpu)
        {
            var highest = new[] { Header.Base + (uint)Data.Length }.Concat(Sections.Select(x => x.VAddr + x.VSize)).Aggregate(Math.Max);
            var lowest = new[] { Header.Base + (uint)Data.Length }.Concat(Sections.Select(x => x.VAddr)).Aggregate(Math.Min);

            if ((highest & 0xFFF) != 0)
            {
                highest = (highest & 0xFFFFF000) + 0x1000;
            }

            var tmp    = Header.Oep ^ 0xA8FC57ABU;
            var retail = tmp >= Header.Base && tmp < highest;

            var pages = (int)(highest / 4096);
            var phys  = PageManager.Instance.AllocPhysPages(pages);
            var virt  = PageManager.Instance.AllocVirtPages(pages, at: Header.Base);

            cpu.MapPages(virt, phys, pages, true);
            WriteLine($"Physical at {phys:X} virt at {virt:X}");
            PageManager.Instance.Write(Header.Base, Data.Take((int)(lowest - Header.Base)).ToArray());
            WriteLine($"File at {Header.Base:X} - {Header.Base + Data.Length:X}");
            WriteLine($"Actual virtual top is {highest:X}");
            foreach (var section in Sections)
            {
                var name = Encoding.ASCII.GetString(Data, (int)(section.NameAddr - Header.Base), 24).Split('\0')[0];
                WriteLine($"- {name} {section.VAddr:X} {section.VSize:X} -- {section.RAddr:X} {section.RSize:X}");
                PageManager.Instance.Write(section.VAddr, Data.Skip((int)section.RAddr).Take((int)section.RSize).ToArray());
            }

            var thunk = Header.Thunk ^ (retail ? 0x5B6D40B6U : 0xEFB1F152U);

            for (var i = 0U; i < 400; ++i)
            {
                var addr = new GuestMemory <uint>(thunk + i * 4);
                var cur  = addr.Value;
                if (cur == 0)
                {
                    break;
                }
                addr.Value = Xbox.KernelCallsBase + (cur & 0x1FF) * 4;
            }

            return(Header.Oep ^ (retail ? 0xA8FC57ABU : 0x94859D4B), Tls.DataStart, Tls.DataEnd, Tls.ZeroFill, Tls.Index);
        }