예제 #1
0
        internal ulong FindCodeRegistrationUsingMscorlib()
        {
            //Works only on >=24.2
            var searchBytes              = Encoding.ASCII.GetBytes("mscorlib.dll\0");
            var mscorlibs                = _pe.raw.Search(searchBytes).Select(idx => _pe.MapRawAddressToVirtual(idx));
            var usagesOfMscorlib         = FindAllMappedWords(mscorlibs);                //CodeGenModule address will be in here
            var codeGenModulesStructAddr = FindAllMappedWords(usagesOfMscorlib);         //CodeGenModules list address will be in here
            var endOfCodeGenRegAddr      = FindAllMappedWords(codeGenModulesStructAddr); //The end of the CodeRegistration object will be in here.

            if (!_pe.is32Bit)
            {
                var codeGenAddr     = endOfCodeGenRegAddr.First();
                var textSection     = _pe.sections.First(s => s.Name == ".text");
                var toDisasm        = _pe.raw.SubArray((int)textSection.PointerToRawData, (int)textSection.SizeOfRawData);
                var allInstructions = LibCpp2ILUtils.DisassembleBytesNew(_pe.is32Bit, toDisasm, textSection.VirtualAddress + _pe.imageBase);

                var allSensibleInstructions = allInstructions.Where(i =>
                                                                    i.Mnemonic == Mnemonic.Lea &&
                                                                    i.OpCount == 2 &&
                                                                    i.Op0Kind == OpKind.Register &&
                                                                    i.Op1Kind == OpKind.Memory &&
                                                                    i.Op0Register == Register.RCX).ToList();

                var sanity = 0;
                while (sanity++ < 500)
                {
                    var instruction = allSensibleInstructions.FirstOrDefault(i =>
                                                                             i.GetRipBasedInstructionMemoryAddress() == codeGenAddr
                                                                             );

                    if (instruction != default)
                    {
                        return(codeGenAddr);
                    }

                    codeGenAddr -= 8; //Always 64-bit here so IntPtr is 8
                }

                return(0);
            }
            else
            {
                IEnumerable <ulong>?codeRegVas = null;
                var sanity = 0;
                while ((codeRegVas?.Count() ?? 0) != 1)
                {
                    if (sanity++ > 500)
                    {
                        break;
                    }

                    endOfCodeGenRegAddr = endOfCodeGenRegAddr.Select(va => va - 4);
                    codeRegVas          = FindAllMappedWords(endOfCodeGenRegAddr);
                }

                if (endOfCodeGenRegAddr.Count() != 1)
                {
                    return(0ul);
                }

                return(endOfCodeGenRegAddr.First());
            }
        }
예제 #2
0
        internal ulong FindCodeRegistrationUsingMscorlib()
        {
            //Works only on >=24.2
            var searchBytes            = Encoding.ASCII.GetBytes("mscorlib.dll\0");
            var mscorlibs              = _pe.raw.Search(searchBytes).Select(idx => _pe.MapRawAddressToVirtual(idx));
            var pMscorlibCodegenModule = FindAllMappedWords(mscorlibs);                                 //CodeGenModule address will be in here
            var pMscorlibCodegenEntryInCodegenModulesList = FindAllMappedWords(pMscorlibCodegenModule); //CodeGenModules list address will be in here

            IEnumerable <ulong>?pCodegenModules = null;

            if (!(LibCpp2IlMain.MetadataVersion >= 27f))
            {
                //Pre-v27, mscorlib is the first codegen module, so *MscorlibCodegenEntryInCodegenModulesList == g_CodegenModules, so we can just find a pointer to this.
                var intermediate = pMscorlibCodegenEntryInCodegenModulesList;
                pCodegenModules = FindAllMappedWords(intermediate);
            }
            else
            {
                //but in v27 it's close to the LAST codegen module (winrt.dll is an exception), so we need to work back until we find an xref.
                var sanityCheckNumberOfModules = 200;
                var pSomewhereInCodegenModules = pMscorlibCodegenEntryInCodegenModulesList;
                var ptrSize = (_pe.is32Bit ? 4u : 8u);
                for (var backtrack = 0; backtrack < sanityCheckNumberOfModules && (pCodegenModules?.Count() ?? 0) != 1; backtrack++)
                {
                    pCodegenModules = FindAllMappedWords(pSomewhereInCodegenModules);

                    //Sanity check the count, which is one pointer back
                    if (pCodegenModules.Count() == 1)
                    {
                        var moduleCount = _pe.ReadClassAtVirtualAddress <int>(pCodegenModules.First() - ptrSize);

                        if (moduleCount < 0 || moduleCount > sanityCheckNumberOfModules)
                        {
                            pCodegenModules = Enumerable.Empty <ulong>();
                        }
                    }

                    pSomewhereInCodegenModules = pSomewhereInCodegenModules.Select(va => va - ptrSize);
                }

                if (!pCodegenModules.Any())
                {
                    throw new Exception("Failed to find pCodegenModules");
                }

                if (pCodegenModules.Count() > 1)
                {
                    throw new Exception("Found more than 1 pointer as pCodegenModules");
                }
            }

            if (!_pe.is32Bit)
            {
                var codeGenAddr     = pCodegenModules.First();
                var textSection     = _pe.sections.First(s => s.Name == ".text");
                var toDisasm        = _pe.raw.SubArray((int)textSection.PointerToRawData, (int)textSection.SizeOfRawData);
                var allInstructions = LibCpp2ILUtils.DisassembleBytesNew(_pe.is32Bit, toDisasm, textSection.VirtualAddress + _pe.imageBase);

                var allSensibleInstructions = allInstructions.Where(i =>
                                                                    i.Mnemonic == Mnemonic.Lea &&
                                                                    i.OpCount == 2 &&
                                                                    i.Op0Kind == OpKind.Register &&
                                                                    i.Op1Kind == OpKind.Memory
                                                                    /*&& i.Op0Register == Register.RCX*/).ToList();

                var sanity = 0;
                while (sanity++ < 500)
                {
                    var instruction = allSensibleInstructions.FirstOrDefault(i =>
                                                                             i.GetRipBasedInstructionMemoryAddress() == codeGenAddr
                                                                             );

                    if (instruction != default)
                    {
                        return(codeGenAddr);
                    }

                    codeGenAddr -= 8; //Always 64-bit here so IntPtr is 8
                }

                return(0);
            }
            else
            {
                IEnumerable <ulong>?codeRegVas = null;
                var sanity = 0;
                while ((codeRegVas?.Count() ?? 0) != 1)
                {
                    if (sanity++ > 500)
                    {
                        break;
                    }

                    pCodegenModules = pCodegenModules.Select(va => va - 4);
                    codeRegVas      = FindAllMappedWords(pCodegenModules).AsParallel().ToList();
                }

                if (pCodegenModules.Count() != 1)
                {
                    return(0ul);
                }

                return(pCodegenModules.First());
            }
        }