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(); }