public void FindActorList() { Logger.WriteLine("FindActorList: loading stored memory regions..."); if (memoryScanner == null || !memoryScanner.LoadMemoryRegions()) { Logger.WriteLine(">> failed! Make sure to create snapshot first with [F11]"); return; } List<long> listEntryAddr = FindActorEntries(); if (listEntryAddr == null) { Logger.WriteLine(">> failed! Can't find actor entries, make sure you're in Inn Room"); return; } List<long> listLists = FindActorLists(listEntryAddr); Logger.WriteLine("Scanning for LEA opcodes..."); MemoryScanner.MemoryRegionInfo baseRegion = memoryScanner.FindMemoryRegion(memoryScanner.GetBaseAddress()); byte[] baseRegionMem = memoryScanner.ReadRegionMemory(baseRegion); foreach (long addr in listLists) { for (int idx = 0; idx < 3; idx++) { long useAddr = addr - (idx * 8); long relativeAddr = useAddr - memoryScanner.GetBaseAddress(); int opCodePos = FindLEA(relativeAddr, baseRegionMem); if (opCodePos >= 0) { string byteDesc = GetOpCodeDesc(baseRegionMem, opCodePos, 32); Logger.WriteLine(" 0x{0} (game+0x{1}) => {2}", useAddr.ToString("x"), relativeAddr.ToString("x"), opCodePos); Logger.WriteLine(" " + byteDesc); break; } } } Logger.WriteLine("Finished"); }
private long FindActorListHeader(long testAddr, long testEntryAddr, int maxListSize) { List<MemoryLayout.ActorData> actors = new List<MemoryLayout.ActorData>(); MemoryScanner.MemoryRegionInfo regInfoEntry = memoryScanner.FindMemoryRegion(testEntryAddr); if (!regInfoEntry.IsValid()) { return 0; } byte[] dataBeforeHeader = null; long listAddr = testAddr; for (int prevIdx = 1; prevIdx < maxListSize; prevIdx++) { long prevAddrPtr = testAddr - (prevIdx * 8); long prevEntryAddr = memoryScanner.ReadPointer(prevAddrPtr); if (regInfoEntry.IsInside(prevEntryAddr)) { byte[] buffer = memoryScanner.ReadBytes(prevEntryAddr, MemoryLayout.ActorConsts.Size); MemoryLayout.ActorData actorOb = new MemoryLayout.ActorData(); actorOb.Set(buffer); if (IsActorValid(actorOb)) { listAddr = prevAddrPtr; actors.Insert(0, actorOb); continue; } } else { dataBeforeHeader = memoryScanner.ReadBytes(prevAddrPtr - 8, 16); } break; } if (listAddr > 0) { for (int nextIdx = 0; nextIdx < maxListSize; nextIdx++) { long nextAddrPtr = testAddr - (nextIdx * 8); long nextEntryAddr = memoryScanner.ReadPointer(nextAddrPtr); if (regInfoEntry.IsInside(nextEntryAddr)) { byte[] buffer = memoryScanner.ReadBytes(nextEntryAddr, MemoryLayout.ActorConsts.Size); MemoryLayout.ActorData actorOb = new MemoryLayout.ActorData(); actorOb.Set(buffer); if (IsActorValid(actorOb)) { actors.Add(actorOb); continue; } } break; } Logger.WriteLine("Exploring actor list at 0x{0} (game+0x{1}): {2} actors", listAddr.ToString("x"), (listAddr - memoryScanner.GetBaseAddress()).ToString("x"), actors.Count); foreach (MemoryLayout.ActorData actorOb in actors) { Logger.WriteLine(" name:{0}, type:{1}:{2}, id:{3}, radius:{4}, pos:({5},{6},{7})", actorOb.Name, actorOb.Type, actorOb.SubType, actorOb.NpcId, actorOb.Radius, actorOb.Position.X, actorOb.Position.Y, actorOb.Position.Z); } string debugStr = ""; foreach (byte num in dataBeforeHeader) { if (debugStr.Length > 0) { debugStr += ", "; } debugStr += num.ToString("x"); } Logger.WriteLine(" before header: {0}, {1} uint64 | {2}, {3}, {4}, {5} int32 => ({6})", BitConverter.ToUInt64(dataBeforeHeader, 0).ToString("x"), BitConverter.ToUInt64(dataBeforeHeader, 8).ToString("x"), BitConverter.ToInt32(dataBeforeHeader, 0), BitConverter.ToInt32(dataBeforeHeader, 4), BitConverter.ToInt32(dataBeforeHeader, 8), BitConverter.ToInt32(dataBeforeHeader, 12), debugStr); } return listAddr; }