コード例 #1
0
        public CodePatternContext(MiniDumpMemoryReader dump, PEHeaderReader pe)
        {
            Dump = dump;
            _pe  = pe;

            Text      = new Range(Dump.ImageBase, _pe.ImageSectionHeaders.First(s => new string(s.Name).StartsWith(".text")));
            Data      = new Range(Dump.ImageBase, _pe.ImageSectionHeaders.First(s => new string(s.Name).StartsWith(".data")));
            Resources = new Range(Dump.ImageBase, _pe.ImageSectionHeaders.First(s => new string(s.Name).StartsWith(".rdata")));

            TextBuffer      = Dump.ReadBytes(Text.Start, (int)Text.Size);
            DataBuffer      = Dump.ReadBytes(Data.Start, (int)Data.Size);
            ResourcesBuffer = Dump.ReadBytes(Resources.Start, (int)Resources.Size);
        }
コード例 #2
0
        private static byte[] AddSignatureToFile(byte[] signature, byte[] dataToSign)
        {
            PEHeaderReader reader = new PEHeaderReader("myDllFileLocation");

            if (reader.Is32BitHeader)
            {
                PEHeaderReader.IMAGE_OPTIONAL_HEADER32 header32 = reader.OptionalHeader32;
                header32.
            }
            else
            {
                PEHeaderReader.IMAGE_OPTIONAL_HEADER64 header64 = reader.OptionalHeader64;
            }
        }
コード例 #3
0
        private static uint GetStatic_LevelArea(byte[] data, SymbolMap symbols)
        {
            const string key = "LevelArea";

            var match = symbols.BestMatch(key);

            if (match != 0)
            {
                return(match);
            }

            if (Engine.Current == null)
            {
                return(0);
            }

            try
            {
                var pe    = new PEHeaderReader(data);
                var rdata = pe.ImageSectionHeaders.FirstOrDefault(h => h.Section.TrimEnd('\0') == ".rdata");
                var text  = pe.ImageSectionHeaders.FirstOrDefault(h => h.Section.TrimEnd('\0') == ".text");

                uint offset = rdata.VirtualAddress - rdata.PointerToRawData + pe.OptionalHeader32.ImageBase;

                var pName = (uint)(offset + new BinaryPattern(Encoding.ASCII.GetBytes("UIMinimapToggle")).NextMatch(data, (int)rdata.PointerToRawData, (int)rdata.SizeOfRawData));

                var pMethod = BitConverter.ToUInt32(data, BinaryPattern.Parse(
                                                        $"68{pName.ToPattern()}" +
                                                        "A3........" +
                                                        "C705................" +
                                                        "C705................" +
                                                        "E8........" +
                                                        "68........" +
                                                        "A3........" +
                                                        "C705........|........|").NextMatch(data, (int)text.PointerToRawData, (int)text.SizeOfRawData) + 51);

                if (Engine.Current.Memory.Reader.Read <byte>(pMethod + 0x00) == 0x8B &&
                    Engine.Current.Memory.Reader.Read <byte>(pMethod + 0x01) == 0x0D)
                {
                    var address = Engine.Current.Memory.Reader.Read <uint>(pMethod + 0x02);
                    symbols.Override(key, address);
                    return(address);
                }
            }
            catch { }

            return(0);
        }
コード例 #4
0
        public static void Run()
        {
            var path = Environment.ExpandEnvironmentVariables(@"%TEMP%\Diablo III.DMP");
            var dump = new MiniDumpMemoryReader(path);
            var pe   = new PEHeaderReader(dump.ReadBytes(dump.ImageBase, 1024));

            _ctx = new CodePatternContext(dump, pe);

            _symbols                     = new SymbolTable();
            _symbols.Version             = dump.MainModuleVersion;
            _symbols.DataSegment.Address = _ctx.Data.Start;

            FindObjectManager();
            FindActors();
            FindACDs();
            FindSNOs();
            FindAttributeDescriptors();
            FindApplicationCore();
            FindLevelArea();
            FindPreferences();
            FindMapActId();
            FindContainerManager();
            FindMessageDescriptors();
            FindPlayerData();

            var dir = new DirectoryInfo("enigma-d3-memory-" + new Version(_symbols.Version.ToString()));

            dir.Create();
            WriteObjectPtrFile(dir);
            WriteGlobalsFile(dir);

            var project = new SharedProject("862a67ee-9ceb-42fe-9406-d7feafc55b00", "Enigma.D3.Memory");

            project.AddCompileFile(Path.Combine(dir.FullName, "Globals.cs"));
            //project.AddCompileFile(Path.Combine(dir.FullName, "MethodPtr.cs"));
            project.AddCompileFile(Path.Combine(dir.FullName, "ObjectPtr.cs"));
            project.Save(Path.Combine(dir.FullName, "Enigma.D3.Memory.Generated.*"));

            if (Program.DeployGeneratedCode)
            {
                project.Deploy(
                    dir,
                    Program.SolutionDirectory.CreateSubdirectory(project.RootNamespace + ".Generated"));
            }
        }
コード例 #5
0
        public PEFile Read(Stream stream)
        {
            var dosHeader = DosHeaderReader.Read(stream);

            uint fillingByteCount = dosHeader.lfanew - DosHeaderReader.DosHeaderSize;

            byte[] fillingBytes = fillingByteCount > 0 ? new byte[fillingByteCount] : null;
            stream.CheckedReadBytes(fillingBytes, "seeking to PE header");

            stream.CheckedExpect(
                (byte)'P', (byte)'E',
                0, 0,
                "reading PE singature");

            var peHeader = PEHeaderReader.Read(stream);

            var optionalHeader = OptionalHeaderReader.Read(
                stream,
                peHeader.SizeOfOptionalHeader);

            Section[] sections;
            if (peHeader.NumberOfSections > 0)
            {
                sections = new Section[peHeader.NumberOfSections];

                for (int i = 0; i < sections.Length; i++)
                {
                    sections[i] = SectionHeaderReader.Read(stream);
                }
            }
            else
            {
                sections = null;
            }

            return(new PEFile
            {
                DosHeader = dosHeader,
                Header = peHeader,
                OptionalHeader = optionalHeader,
                Sections = sections
            });
        }
コード例 #6
0
        internal static void Run()
        {
            var exe     = Program.GetExeFile();
            var data    = File.ReadAllBytes(exe.FullName);
            var mem     = new BufferMemoryReader(data);
            var version = FileVersionInfo.GetVersionInfo(exe.FullName).FileVersion;

            PE = new PEHeaderReader(data);

            var  symbols = SymbolLocator.FindAll(data, mem);
            uint containerManager;

            var dir = new DirectoryInfo("enigma-d3-memory-" + new Version(version.Replace(", ", ".")));

            dir.Create();

            var objPtrs = new Dictionary <string, uint>();

            objPtrs.Add("SNOGroups", symbols.BestMatch("SnoGroups"));
            objPtrs.Add("SNOGroupsByCode", symbols.BestMatch("SnoGroupsByCode"));
            objPtrs.Add("AttributeDescriptors", symbols.BestMatch("AttributeDescriptors"));
            objPtrs.Add("MessageDescriptor", symbols.BestMatch("MessageDescriptor"));
            objPtrs.Add("LocalData", symbols.BestMatch("LocalData"));
            objPtrs.Add("ContainerManager", containerManager = symbols.BestMatch("ContainerManager"));
            objPtrs.Add("ApplicationLoopCount", symbols.BestMatch("ApplicationLoopCount"));
            objPtrs.Add("ObjectManager", symbols.BestMatch("ObjectManager"));
            objPtrs.Add("ObjectManagerPristine", symbols.BestMatch("ObjectManagerPristine"));
            objPtrs.Add("MapActId", symbols.BestMatch("MapActId"));
            objPtrs.Add("VideoPreferences", symbols.BestMatch("VideoPreferences"));
            objPtrs.Add("SoundPreferences", symbols.BestMatch("SoundPreferences"));
            objPtrs.Add("GameplayPreferences", symbols.BestMatch("GameplayPreferences"));
            objPtrs.Add("SocialPreferences", symbols.BestMatch("SocialPreferences"));
            objPtrs.Add("ChatPreferences", symbols.BestMatch("ChatPreferences"));
            objPtrs.Add("HotkeyPreferences", objPtrs["SoundPreferences"] == 0 ? 0 : objPtrs["SoundPreferences"] + 0x50);
            objPtrs.Add("LevelArea", GetStatic_LevelArea(data, symbols));
            objPtrs.Add("LevelAreaName", GetStatic_LevelAreaName(data, symbols));
            WriteObjectPtrFile(Path.Combine(dir.FullName, "ObjectPtr.cs"), objPtrs);

            var methodPtrs = new Dictionary <string, uint>();

            methodPtrs.Add("SNOGroups_Initialize", TranslateToVA(symbols.BestMatch("CSnoGroups::Initialize")));
            methodPtrs.Add("GameMessage_GetHandlerInfo", TranslateToVA(symbols.BestMatch("CGameMessage::GetHandlerInfo")));
            WriteMethodPtrFile(Path.Combine(dir.FullName, "MethodPtr.cs"), methodPtrs);

            var globals = new Dictionary <string, string>();

            globals.Add("static readonly Version SupportedVersion", $"new Version({version})");
            globals.Add("const int SNOGroupsCount", "60");                   // TODO: Don't hardcode.
            globals.Add("const int AttributeDescriptorsCount", GetAttributeDescriptorsCount(symbols).ToString());
            var sizeof_playerdata = symbols.BestMatch("sizeof(PlayerData)"); // ((symbols.BestMatch("sizeof(PlayerDataManager)") - 0x038) / 8);

            globals.Add("const int SizeOf_PlayerData", sizeof_playerdata.ToHex());
            if (Engine.Current?.ProcessVersion == Engine.SupportedVersion)
            {
                globals.Add("const int Offset_PlayerData_HeroName", GetOffset_PlayerData_HeroName(sizeof_playerdata).ToHex());
                globals.Add("const int Offset_PlayerData_LifePercentage", GetOffset_PlayerData_LifePercentage(sizeof_playerdata).ToHex());
            }
            else
            {
                globals.Add("const int Offset_PlayerData_HeroName", "0; // Run [CodeGen -memory -deploy] again");
                globals.Add("const int Offset_PlayerData_LifePercentage", "0; // Run [CodeGen -memory -deploy] again");
            }
            // TODO: globals.Add("const int SizeOf_LevelArea", symbols.BestMatch("sizeof(LevelArea)").ToHex());
            WriteGlobalsFile(Path.Combine(dir.FullName, "Globals.cs"), globals);

            var project = new SharedProject("862a67ee-9ceb-42fe-9406-d7feafc55b00", "Enigma.D3.Memory");

            project.AddCompileFile(Path.Combine(dir.FullName, "Globals.cs"));
            project.AddCompileFile(Path.Combine(dir.FullName, "MethodPtr.cs"));
            project.AddCompileFile(Path.Combine(dir.FullName, "ObjectPtr.cs"));
            project.Save(Path.Combine(dir.FullName, "Enigma.D3.Memory.Generated.*"));

            if (Program.DeployGeneratedCode)
            {
                project.Deploy(
                    dir,
                    Program.SolutionDirectory.CreateSubdirectory(project.RootNamespace + ".Generated"));
            }
        }
コード例 #7
0
        public MiniDumpMemoryReader(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentNullException("path");
            }

            _fileStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);

            var mem    = new FileMemoryReader(path);
            var header = mem.Read <MiniDump.Header>(0x00);
            var dirs   = mem.Read <MiniDump.Directory>(header.StreamDirectoryRva, (int)header.NumberOfStreams);

            var moduleList = dirs.SingleOrDefault(a => a.StreamType == MiniDump.StreamType.ModuleListStream);

            if (moduleList.StreamType != MiniDump.StreamType.ModuleListStream)
            {
                throw new InvalidOperationException("The minidump file does not contain a module list.");
            }
            var modules = mem.Read <MiniDump.List <MiniDump.Module> >(moduleList.Location.Rva).Items;

            var threadList = dirs.SingleOrDefault(x => x.StreamType == MiniDump.StreamType.ThreadListStream);

            if (threadList.StreamType == MiniDump.StreamType.ThreadListStream)
            {
                _threads = mem.Read <MiniDump.List <MiniDump.Thread> >(threadList.Location.Rva).Items;
            }

            var mainModule = modules.FirstOrDefault(a => a.VersionInfo.FileType == 1);

            MainModuleVersion = mainModule.VersionInfo.FileVersion;
            ImageBase         = mainModule.BaseOfImage;

            var memory64ListDir = dirs.SingleOrDefault(a => a.StreamType == MiniDump.StreamType.Memory64ListStream);

            if (memory64ListDir.StreamType != MiniDump.StreamType.Memory64ListStream)
            {
                throw new InvalidOperationException("The minidump file does not contain a full memory dump.");
            }
            var memory64List = mem.Read <MiniDump.Memory64List>(memory64ListDir.Location.Rva);

            var rva    = memory64List.BaseRva;
            var ranges = memory64List.MemoryRanges;
            var pages  = new List <Page>();

            for (int i = 0; i < ranges.Length; i++)
            {
                pages.Add(new Page
                {
                    StartOfMemoryRange = ranges[i].StartOfMemoryRange,
                    DataSize           = ranges[i].DataSize,
                    Rva = rva
                });
                rva += ranges[i].DataSize;
            }

            _pages           = pages;
            _pageStarts      = _pages.Select(a => a.StartOfMemoryRange).ToList();
            _minValidAddress = _pages[0].StartOfMemoryRange;
            _maxValidAddress = _pages[_pages.Count - 1].StartOfMemoryRange + _pages[_pages.Count - 1].DataSize;

            var pe = new PEHeaderReader(ReadBytes(ImageBase, 2048));

            _pointerSize = pe.Is32BitHeader ? 4 : 8;
        }