Example #1
0
        public static void Dump(uint specificOpcode = 0xBADD)
        {
            if (specificOpcode != 0xBADD)
            {
                Pattern[11] = (byte)((specificOpcode & 0xFF00) >> 8);
                Pattern[10] = (byte)(specificOpcode & 0x00FF);
                Console.WriteLine(BitConverter.ToString(Pattern).Replace('-', ' '));
            }

            var patternOffsets = Program.ClientBytes.FindPattern(Pattern, 0xFF);
            var callIndex      = (uint)(Array.IndexOf <byte>(Pattern, 0xE8) + 0x400C00);

            Logger.WriteLine();
            Logger.WriteLine("Dumping CMSG opcodes...");
            Logger.WriteLine("Found {0} CMSGs candidates. Dumping, this may take a while...", patternOffsets.Count);
            Logger.WriteLine("+---------------+------------+------------+------------+");
            Logger.WriteLine("|    Opcode     |   vTable   |   CliPut   | CONFIDENCE |");
            Logger.WriteLine("+---------------+------------+------------+------------+");

            foreach (var currPatternOffset in patternOffsets)
            {
                Program.BaseStream.Seek(currPatternOffset, SeekOrigin.Begin);
                var bytes = Program.ClientStream.ReadBytes(Pattern.Length);

                var callOffset = BitConverter.ToInt32(bytes, 15);

                // False positive check
                int PutUInt32 = 0;
                switch (Program.ClientBuild.BuildNumber)
                {
                case 19324:
                    PutUInt32 = 0x0040FD64;
                    break;

                case 19702:
                    PutUInt32 = 0x004110E6;
                    break;

                case 19802:
                    PutUInt32 = 0x004111B6;
                    break;

                case 19865:
                    PutUInt32 = 0x004111B6;
                    break;

                default:
                    PutUInt32 = 0x0;
                    break;
                }
                var subCall = (uint)(currPatternOffset + callIndex) + callOffset + 5;
                if (subCall != PutUInt32 && PutUInt32 != 0) // CDataStore::PutInt32
                {
                    continue;
                }

                var opcodeValue   = specificOpcode == 0xBADD ? BitConverter.ToUInt16(bytes, 10) : specificOpcode;
                var ptBytes       = BitConverter.GetBytes(currPatternOffset + 0x400C00);
                var vtablePattern = new byte[] {
                    0xFF, 0xFF, 0xFF, 0xFF,                         // Ctor
                    0xFF, 0xFF, 0xFF, 0xFF,                         // CliPut
                    ptBytes[0], ptBytes[1], ptBytes[2], ptBytes[3], // CliPutWithMsgId (where we are at)
                    0xFF, 0xFF, 0xFF, 0xFF                          // Dtor
                };

                var vtOffsets = Program.ClientBytes.FindPattern(vtablePattern, 0xFF).Where(t => (t - 0x400C00) < Program.ClientBytes.Length);
                foreach (var vtOffset in vtOffsets)
                {
                    Program.BaseStream.Seek(vtOffset + 4, SeekOrigin.Begin);
                    var cliPut        = Program.ClientStream.ReadUInt32();
                    var cliPutWithMsg = Program.ClientStream.ReadUInt32();
                    if (cliPutWithMsg != (currPatternOffset + 0x400C00))
                    {
                        continue;
                    }

                    List <uint> callerOffset;

                    if (Config.BinDiff != string.Empty)
                    {
                        var offBytes    = BitConverter.GetBytes(vtOffset + 0x400C00);
                        var ctorPattern = new byte[] {
                            0x8B, 0xC1,                                                         // mov     eax, ecx
                            0x83, 0x60, 0x0C, 0x00,                                             // and     dword ptr [eax+0Ch], 0
                            0xC7, 0x00, offBytes[0], offBytes[1], offBytes[2], offBytes[3]      // mov     dword ptr [eax], <vtable>
                        };

                        callerOffset = Program.ClientBytes.FindPattern(ctorPattern, 0xFF);
                    }
                    else
                    {
                        callerOffset = new List <uint>()
                        {
                            0
                        }
                    };

                    cmsgInfo.Add(new CMSGInfo(Opcodes.GetOpcodeNameForClient(opcodeValue,
                                                                             callerOffset.FirstOrDefault() + 0x400C00),
                                              opcodeValue,
                                              vtOffset + 0x400C00,
                                              cliPut,
                                              cliPutWithMsg,
                                              Program.FuncDiff != null ? Program.FuncDiff.getCertianty(callerOffset.FirstOrDefault() + 0x400C00) : 0));

                    Console.WriteLine(cmsgInfo.Last().getPrintString());

                    ++opcodeCount;

                    break;
                }
            }

            cmsgInfo = cmsgInfo.OrderBy(x => x.Name).ToList();
            foreach (CMSGInfo cmsg in cmsgInfo)
            {
                if (cmsg.Opcode != 0x0105) //OTHER UGLY HACK
                {
                    cmsg.FormatName();
                    Logger.WriteLine(cmsg.getPrintString());
                }
            }


            Logger.WriteLine("+---------------+------------+------------+------------+");
            Logger.WriteLine("Dumped {0} CMSG JAM opcodes.", opcodeCount);
        }