Example #1
0
        public void StartDump(uint addr, uint len, FileStream dump = null)
        {
            if (len == 0)
            {
                // dump all of ram
                len = 0xFFFFFFFF - addr;
            }
            long methid_copy = _vita.GetMethod(true, "System.Runtime.InteropServices.Marshal", "Copy", 4, new string[] { "IntPtr", "Byte[]", "Int32", "Int32" });

            if (methid_copy < 0)
            {
                Console.WriteLine("Cannot find Copy method.");
                return;
            }
            // weird address format for IntPtr on vita

            /* DEPRECATED BECAUSE GC WILL DELETE THESE
             * ValueImpl src = v.CreateIntPtr(UIntToVitaInt(addr));
             * ValueImpl dest = v.CreateArray("System.Byte", BLOCK_SIZE);
             */
            ValueImpl dest = _vita.GetField(false, "VitaDefilerClient.AppMain", "dest");

            dest.Type = ElementType.Object; // must be done
            ValueImpl src = _vita.GetField(false, "VitaDefilerClient.AppMain", "src");

            if (dest == null)
            {
                Console.WriteLine("Cannot find buffer to write to.");
                return;
            }
            if (src == null)
            {
                Console.WriteLine("Cannot find pointer to read from.");
                return;
            }
            src.Fields[0].Value = UIntToVitaInt(addr);
            byte[] block = new byte[BLOCK_SIZE];
            // error block will be written when block cannot be read
            byte[] error_block = new byte[BLOCK_SIZE];
            for (int i = 0; i < BLOCK_SIZE; i++)
            {
                error_block[i] = (byte)'X';
            }
            ValueImpl sti  = new ValueImpl();
            ValueImpl dlen = new ValueImpl();

            sti.Type   = ElementType.I4;
            dlen.Type  = ElementType.I4;
            sti.Value  = 0;
            dlen.Value = BLOCK_SIZE;
            _vita.Suspend();
            Console.WriteLine("Starting dump...");
            for (int d = 0; d *BLOCK_SIZE <= len; d++)
            {
                try
                {
                    if (dump != null)
                    {
                        dump.Flush();
                    }
                    Console.WriteLine("Dumping 0x{0:X}", src.Fields[0].Value);
                    ValueImpl ret = _vita.RunMethod(methid_copy, null, new ValueImpl[] { src, dest, sti, dlen }, true);
                    if (ret == null)
                    {
                        throw new TargetException("Method never returned.");
                    }
                    _vita.GetBuffer(dest.Objid, BLOCK_SIZE, ref block);
                    if (dump == null)
                    {
                        block.PrintHexDump((uint)BLOCK_SIZE, 16);
                    }
                    int num = BLOCK_SIZE;
                    if (d * BLOCK_SIZE + num > len)
                    {
                        num = (int)(len - d * BLOCK_SIZE);
                    }
                    if (dump != null)
                    {
                        dump.Write(block, 0, num);
                    }
                }
                catch (InvalidOperationException) // vm not suspended, retry
                {
                    Console.WriteLine("VM_NOT_SUSPENDED, retrying...");
                    d--;
                    continue;
                }
                catch (Vita.RunMethodException ex)
                {
                    Console.WriteLine("Error dumping 0x{0:X}: {1}", src.Fields[0].Value, ex.Message.ToString());
                    int num = BLOCK_SIZE;
                    if (d * BLOCK_SIZE + num > len)
                    {
                        num = (int)(len - d * BLOCK_SIZE);
                    }
                    if (dump != null)
                    {
                        dump.Write(error_block, 0, num);
                    }
                }
                // next block to dump
                src.Fields[0].Value = (Int64)src.Fields[0].Value + BLOCK_SIZE;
                if (d % 1000 == 0)
                {
                    // must be done or app will freeze
                    _vita.Resume();
                    _vita.Suspend();
                }
            }
            if (dump != null)
            {
                dump.Close();
            }
            _vita.Resume();
        }