From ced049c5e8b9e4e2620a8ed7b7ab4d26f3d0441d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Mon, 22 May 2017 10:58:27 +0200 Subject: [PATCH 1/3] IOS/ES: Prevent usage of ES_DiVerifyWithView for the PPC ES_DiVerifyWithView (0x3b) is another private ioctlv that can only be used from DI. Calling it from anywhere else returns -1017. --- Source/Core/Core/IOS/ES/ES.cpp | 2 +- Source/Core/Core/IOS/ES/ES.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index 6fcf884578..28635605c0 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -417,6 +417,7 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request) case IOCTL_ES_SETUID: return SetUID(context->uid, request); case IOCTL_ES_DIVERIFY: + case IOCTL_ES_DIVERIFY_WITH_VIEW: return DIVerify(request); case IOCTL_ES_GETOWNEDTITLECNT: @@ -512,7 +513,6 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request) return GetTicketFromView(request); case IOCTL_ES_VERIFYSIGN: - case IOCTL_ES_UNKNOWN_3B: case IOCTL_ES_UNKNOWN_3C: case IOCTL_ES_UNKNOWN_3D: case IOCTL_ES_UNKNOWN_3E: diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index a55297e760..4cce356fc3 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -181,7 +181,7 @@ private: IOCTL_ES_DELETESHAREDCONTENT = 0x38, IOCTL_ES_DIGETTMDSIZE = 0x39, IOCTL_ES_DIGETTMD = 0x3A, - IOCTL_ES_UNKNOWN_3B = 0x3B, + IOCTL_ES_DIVERIFY_WITH_VIEW = 0x3B, IOCTL_ES_UNKNOWN_3C = 0x3C, IOCTL_ES_UNKNOWN_3D = 0x3D, IOCTL_ES_UNKNOWN_3E = 0x3E, From 90d590d1f30c52777a124ba8ca9a821bf7e0bf2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Mon, 22 May 2017 11:17:41 +0200 Subject: [PATCH 2/3] IOS/ES: Implement ES_DeleteContent (0x3e) --- Source/Core/Core/IOS/ES/ES.cpp | 3 +- Source/Core/Core/IOS/ES/ES.h | 4 ++- Source/Core/Core/IOS/ES/TitleManagement.cpp | 33 +++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index 28635605c0..9cf77b3487 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -474,6 +474,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request) return DeleteTitleContent(request); case IOCTL_ES_DELETESHAREDCONTENT: return DeleteSharedContent(request); + case IOCTL_ES_DELETE_CONTENT: + return DeleteContent(request); case IOCTL_ES_GETSTOREDTMDSIZE: return GetStoredTMDSize(request); case IOCTL_ES_GETSTOREDTMD: @@ -515,7 +517,6 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request) case IOCTL_ES_VERIFYSIGN: case IOCTL_ES_UNKNOWN_3C: case IOCTL_ES_UNKNOWN_3D: - case IOCTL_ES_UNKNOWN_3E: case IOCTL_ES_UNKNOWN_41: case IOCTL_ES_UNKNOWN_42: PanicAlert("IOS-ES: Unimplemented ioctlv 0x%x (%zu in vectors, %zu io vectors)", diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index 4cce356fc3..543768c144 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -115,6 +115,7 @@ public: ReturnCode DeleteTitleContent(u64 title_id) const; ReturnCode DeleteTicket(const u8* ticket_view); ReturnCode DeleteSharedContent(const std::array& sha1) const; + ReturnCode DeleteContent(u64 title_id, u32 content_id) const; // Views ReturnCode GetV0TicketFromView(const u8* ticket_view, u8* ticket) const; @@ -184,7 +185,7 @@ private: IOCTL_ES_DIVERIFY_WITH_VIEW = 0x3B, IOCTL_ES_UNKNOWN_3C = 0x3C, IOCTL_ES_UNKNOWN_3D = 0x3D, - IOCTL_ES_UNKNOWN_3E = 0x3E, + IOCTL_ES_DELETE_CONTENT = 0x3E, IOCTL_ES_INVALID_3F = 0x3F, IOCTL_ES_GET_V0_TICKET_FROM_VIEW = 0x40, IOCTL_ES_UNKNOWN_41 = 0x41, @@ -215,6 +216,7 @@ private: IPCCommandResult DeleteTitleContent(const IOCtlVRequest& request); IPCCommandResult DeleteTicket(const IOCtlVRequest& request); IPCCommandResult DeleteSharedContent(const IOCtlVRequest& request); + IPCCommandResult DeleteContent(const IOCtlVRequest& request); // Device identity and encryption IPCCommandResult GetConsoleID(const IOCtlVRequest& request); diff --git a/Source/Core/Core/IOS/ES/TitleManagement.cpp b/Source/Core/Core/IOS/ES/TitleManagement.cpp index a8e326d371..79b625ce59 100644 --- a/Source/Core/Core/IOS/ES/TitleManagement.cpp +++ b/Source/Core/Core/IOS/ES/TitleManagement.cpp @@ -440,6 +440,39 @@ IPCCommandResult ES::DeleteTitleContent(const IOCtlVRequest& request) return GetDefaultReply(DeleteTitleContent(Memory::Read_U64(request.in_vectors[0].address))); } +ReturnCode ES::DeleteContent(u64 title_id, u32 content_id) const +{ + if (!CanDeleteTitle(title_id)) + return ES_EINVAL; + + const auto tmd = IOS::ES::FindInstalledTMD(title_id); + if (!tmd.IsValid()) + return FS_ENOENT; + + IOS::ES::Content content; + if (!tmd.FindContentById(content_id, &content)) + return ES_EINVAL; + + if (!File::Delete(Common::GetTitleContentPath(title_id, Common::FROM_SESSION_ROOT) + + StringFromFormat("%08x.app", content_id))) + { + return FS_ENOENT; + } + + return IPC_SUCCESS; +} + +IPCCommandResult ES::DeleteContent(const IOCtlVRequest& request) +{ + if (!request.HasNumberOfValidVectors(2, 0) || request.in_vectors[0].size != sizeof(u64) || + request.in_vectors[1].size != sizeof(u32)) + { + return GetDefaultReply(ES_EINVAL); + } + return GetDefaultReply(DeleteContent(Memory::Read_U64(request.in_vectors[0].address), + Memory::Read_U32(request.in_vectors[1].address))); +} + ReturnCode ES::ExportTitleInit(Context& context, u64 title_id, u8* tmd_bytes, u32 tmd_size) { // No concurrent title import/export is allowed. From 57ce091ef580c7ba3032d803687aff4241e8ff36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Mon, 22 May 2017 11:22:53 +0200 Subject: [PATCH 3/3] IOS/ES: Implement ES_DeleteStreamKey (0x3d) --- Source/Core/Core/IOS/ES/ES.cpp | 13 ++++++++++++- Source/Core/Core/IOS/ES/ES.h | 3 ++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index 9cf77b3487..4dcb0e9ff6 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -514,9 +514,11 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request) case IOCTL_ES_GET_TICKET_FROM_VIEW: return GetTicketFromView(request); + case IOCTL_ES_DELETE_STREAM_KEY: + return DeleteStreamKey(request); + case IOCTL_ES_VERIFYSIGN: case IOCTL_ES_UNKNOWN_3C: - case IOCTL_ES_UNKNOWN_3D: case IOCTL_ES_UNKNOWN_41: case IOCTL_ES_UNKNOWN_42: PanicAlert("IOS-ES: Unimplemented ioctlv 0x%x (%zu in vectors, %zu io vectors)", @@ -643,6 +645,15 @@ s32 ES::DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& tic return IPC_SUCCESS; } + +IPCCommandResult ES::DeleteStreamKey(const IOCtlVRequest& request) +{ + if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sizeof(u32)) + return GetDefaultReply(ES_EINVAL); + + const u32 handle = Memory::Read_U32(request.in_vectors[0].address); + return GetDefaultReply(m_ios.GetIOSC().DeleteObject(handle, PID_ES)); +} } // namespace Device } // namespace HLE } // namespace IOS diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index 543768c144..a918a72d49 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -184,7 +184,7 @@ private: IOCTL_ES_DIGETTMD = 0x3A, IOCTL_ES_DIVERIFY_WITH_VIEW = 0x3B, IOCTL_ES_UNKNOWN_3C = 0x3C, - IOCTL_ES_UNKNOWN_3D = 0x3D, + IOCTL_ES_DELETE_STREAM_KEY = 0x3D, IOCTL_ES_DELETE_CONTENT = 0x3E, IOCTL_ES_INVALID_3F = 0x3F, IOCTL_ES_GET_V0_TICKET_FROM_VIEW = 0x40, @@ -234,6 +234,7 @@ private: IPCCommandResult Launch(const IOCtlVRequest& request); IPCCommandResult LaunchBC(const IOCtlVRequest& request); IPCCommandResult DIVerify(const IOCtlVRequest& request); + IPCCommandResult DeleteStreamKey(const IOCtlVRequest& request); // Title contents IPCCommandResult OpenTitleContent(u32 uid, const IOCtlVRequest& request);