Use proper multi lib support, adding debug api calls & work on library manager.
This commit is contained in:
+7
-8
@@ -1,12 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
// Genreall IPC ADDRS should follow the GeneralIPC#<ProcessName> pattern.
|
||||
#define GENERAL_IPC_ADDR "/system_tmp/GeneralIPC#%s"
|
||||
#define GENERAL_IPC_ADDR "/system_tmp/GeneralIPC-%d"
|
||||
|
||||
enum GeneralIPCCommands
|
||||
{
|
||||
GIPC_INFO,
|
||||
GIPC_LIB_LIST,
|
||||
GIPC_LIB_LOAD,
|
||||
GIPC_LIB_UNLOAD,
|
||||
GIPC_JAILBREAK,
|
||||
GIPC_JAIL,
|
||||
GIPC_RW,
|
||||
@@ -19,10 +20,8 @@ enum GeneralIPCResult
|
||||
GIPC_OK,
|
||||
};
|
||||
|
||||
struct ExtProccesInfoPacket
|
||||
struct LibPacket
|
||||
{
|
||||
char Path[64];
|
||||
char TitleId[16];
|
||||
char ContentId[64];
|
||||
char Version[6];
|
||||
};
|
||||
char Path[100];
|
||||
int Handle;
|
||||
};
|
||||
|
||||
@@ -58,10 +58,10 @@ enum APICommands
|
||||
API_DBG_SET_DBGREG,
|
||||
|
||||
/* Remote Library functions */
|
||||
API_DBG_LOAD_SPRX,
|
||||
API_DBG_UNLOAD_SPRX,
|
||||
API_DBG_RELOAD_SPRX,
|
||||
API_DBG_MODULE_LIST,
|
||||
API_DBG_LOAD_LIBRARY,
|
||||
API_DBG_UNLOAD_LIBRARY,
|
||||
API_DBG_RELOAD_LIBRARY,
|
||||
API_DBG_LIBRARY_LIST,
|
||||
|
||||
/* Thread Management */
|
||||
API_DBG_THREAD_LIST,
|
||||
@@ -194,7 +194,7 @@ struct LibraryPacket
|
||||
int64_t Handle;
|
||||
char Path[256];
|
||||
int32_t SegmentCount;
|
||||
OrbisKernelModuleInfo Segments[4];
|
||||
OrbisKernelModuleSegmentInfo Segments[4];
|
||||
};
|
||||
|
||||
struct DbgRWPacket
|
||||
@@ -205,13 +205,11 @@ struct DbgRWPacket
|
||||
|
||||
struct DbgSPRXPacket
|
||||
{
|
||||
char Name[256];
|
||||
char Path[256];
|
||||
int ModuleHandle;
|
||||
int Flags;
|
||||
int Handle;
|
||||
};
|
||||
|
||||
struct ProcBreakpointPacket
|
||||
struct DbgBreakpointPacket
|
||||
{
|
||||
int Index;
|
||||
uint64_t Address;
|
||||
|
||||
@@ -177,7 +177,7 @@ void Apps::StartApp(OrbisNetId Sock, const char* TitleId)
|
||||
return;
|
||||
}
|
||||
|
||||
auto res = LncUtil::sceLncUtilLaunchApp(TitleId, nullptr, &appParam);
|
||||
auto res = sceLncUtilLaunchApp(TitleId, nullptr, &appParam);
|
||||
if (res <= 0)
|
||||
{
|
||||
klog("sceLncUtilLaunchApp() : Failed with error % llX\n", res);
|
||||
@@ -207,7 +207,7 @@ void Apps::SuspendApp(OrbisNetId Sock, const char* TitleId)
|
||||
{
|
||||
auto appId = GetAppId(TitleId);
|
||||
|
||||
if (appId > 0 && LncUtil::sceLncUtilSuspendApp(appId, 0) == 0)
|
||||
if (appId > 0 && sceLncUtilSuspendApp(appId, 0) == 0)
|
||||
{
|
||||
Sockets::SendInt(Sock, 1);
|
||||
}
|
||||
@@ -221,7 +221,7 @@ void Apps::ResumeApp(OrbisNetId Sock, const char* TitleId)
|
||||
{
|
||||
auto appId = GetAppId(TitleId);
|
||||
|
||||
if (appId > 0 && LncUtil::sceLncUtilResumeApp(appId, 0) == 0 && sceApplicationSetApplicationFocus(appId) == 0)
|
||||
if (appId > 0 && sceLncUtilResumeApp(appId, 0) == 0 && sceLncUtilSetAppFocus(appId, 0) == 0)
|
||||
{
|
||||
Sockets::SendInt(Sock, 1);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include <orbis/Sysmodule.h>
|
||||
#include <orbis/AppInstUtil.h>
|
||||
#include <orbis/SysCore.h>
|
||||
#include <orbis/LncUtil.h>
|
||||
#include <orbis/ShellCoreUtil.h>
|
||||
#include <orbis/SystemStateMgr.h>
|
||||
|
||||
#include "SocketListener.h"
|
||||
#include "Utilities.h"
|
||||
@@ -33,11 +36,5 @@
|
||||
#include "Sockets.h"
|
||||
#include "System.h"
|
||||
#include "Flash.h"
|
||||
|
||||
#include "APIPackets.h"
|
||||
#include "LncUtil.h"
|
||||
#include "ShellCoreUtil.h"
|
||||
#include "SystemMonitor.h"
|
||||
|
||||
//#define FIRMWARE_505
|
||||
#define FIRMWARE_900
|
||||
@@ -1,11 +1,19 @@
|
||||
#include "Common.h"
|
||||
#include "Debug.h"
|
||||
#include "APIHelper.h"
|
||||
#include "GeneralIPC.h"
|
||||
|
||||
#include <sys/ptrace.h>
|
||||
|
||||
#define HelperPrxPath "/data/Orbis Suite/OrbisLibGeneralHelper.sprx"
|
||||
|
||||
void Debug::HandleAPI(OrbisNetId Sock, APIPacket* Packet)
|
||||
{
|
||||
if (Packet->Command > API_DBG_GET_CURRENT)
|
||||
{
|
||||
Sockets::SendInt(Sock, IsDebugging ? 1 : 0);
|
||||
}
|
||||
|
||||
switch (Packet->Command)
|
||||
{
|
||||
default:
|
||||
@@ -13,10 +21,58 @@ void Debug::HandleAPI(OrbisNetId Sock, APIPacket* Packet)
|
||||
|
||||
case API_DBG_ATTACH:
|
||||
|
||||
Attach(Sock);
|
||||
|
||||
break;
|
||||
|
||||
case API_DBG_DETACH:
|
||||
|
||||
Detach(Sock);
|
||||
|
||||
break;
|
||||
|
||||
case API_DBG_GET_CURRENT:
|
||||
|
||||
Sockets::SendInt(Sock, CurrentPID);
|
||||
|
||||
break;
|
||||
|
||||
case API_DBG_READ:
|
||||
|
||||
break;
|
||||
|
||||
case API_DBG_WRITE:
|
||||
|
||||
break;
|
||||
|
||||
case API_DBG_KILL:
|
||||
|
||||
break;
|
||||
|
||||
//...
|
||||
|
||||
case API_DBG_LOAD_LIBRARY:
|
||||
|
||||
LoadLibrary(Sock);
|
||||
|
||||
break;
|
||||
|
||||
case API_DBG_UNLOAD_LIBRARY:
|
||||
|
||||
UnloadLibrary(Sock);
|
||||
|
||||
break;
|
||||
|
||||
case API_DBG_RELOAD_LIBRARY:
|
||||
|
||||
ReloadLibrary(Sock);
|
||||
|
||||
break;
|
||||
|
||||
case API_DBG_LIBRARY_LIST:
|
||||
|
||||
GetLibraryList(Sock);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -40,7 +96,7 @@ bool Debug::TryDetach(int pid)
|
||||
// TODO: Kill the watching thread and Remove any Watchpoints / Breakpoints now.
|
||||
|
||||
IsDebugging = false;
|
||||
CurrentPID = 0;
|
||||
CurrentPID = -1;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -49,6 +105,12 @@ void Debug::Attach(OrbisNetId Sock)
|
||||
{
|
||||
auto pid = RecieveInt(Sock);
|
||||
|
||||
// Get Process name.
|
||||
char processName[32];
|
||||
sceKernelGetProcessName(pid, processName);
|
||||
|
||||
klog("Attempting to attach to %s (%d)\n", processName, pid);
|
||||
|
||||
// If we are currently debugging another process lets detach from it.
|
||||
if (!TryDetach(pid))
|
||||
{
|
||||
@@ -66,8 +128,10 @@ void Debug::Attach(OrbisNetId Sock)
|
||||
return;
|
||||
}
|
||||
|
||||
sceKernelUsleep(500);
|
||||
|
||||
// Attaching by default will stop execution of the remote process. Lets continue it now.
|
||||
res = ptrace(PT_CONTINUE, pid, nullptr, 0);
|
||||
res = ptrace(PT_CONTINUE, pid, (void*)1, 0);
|
||||
if (res != 0)
|
||||
{
|
||||
klog("Attach(): ptrace(PT_CONTINUE) failed with error %llX\n", res);
|
||||
@@ -78,19 +142,154 @@ void Debug::Attach(OrbisNetId Sock)
|
||||
IsDebugging = true;
|
||||
CurrentPID = pid;
|
||||
|
||||
klog("Attached to %s(%d)\n", processName, pid);
|
||||
|
||||
SendStatus(Sock, 1);
|
||||
|
||||
if (strcmp(processName, "SceShellCore"))
|
||||
{
|
||||
// Get app info.
|
||||
OrbisAppInfo appInfo;
|
||||
sceKernelGetAppInfo(pid, &appInfo);
|
||||
|
||||
// Get sandbox path.
|
||||
char sandBoxPath[PATH_MAX];
|
||||
snprintf(sandBoxPath, sizeof(sandBoxPath), "/mnt/sandbox/%s_000/data", appInfo.TitleId);
|
||||
|
||||
// Mount data into sandbox
|
||||
LinkDir("/data/", sandBoxPath);
|
||||
}
|
||||
|
||||
// Load the helper library.
|
||||
int handle = sys_sdk_proc_prx_load(processName, HelperPrxPath);
|
||||
klog("Helper handle = %llX\n", handle);
|
||||
}
|
||||
|
||||
void Debug::Detach(OrbisNetId Sock)
|
||||
{
|
||||
auto pid = RecieveInt(Sock);
|
||||
auto result = TryDetach(pid);
|
||||
bool result = false;
|
||||
if (IsDebugging)
|
||||
result = TryDetach(CurrentPID);
|
||||
SendStatus(Sock, result ? 1 : 0);
|
||||
}
|
||||
|
||||
void Debug::LoadLibrary(OrbisNetId Sock)
|
||||
{
|
||||
if (!IsDebugging || CurrentPID == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get next packet.
|
||||
auto Packet = (DbgSPRXPacket*)malloc(sizeof(DbgSPRXPacket));
|
||||
sceNetRecv(Sock, Packet, sizeof(DbgSPRXPacket), 0);
|
||||
|
||||
// Load the library.
|
||||
int handle = 0;
|
||||
GeneralIPC::LoadLibrary(CurrentPID, Packet->Path, &handle);
|
||||
|
||||
// Send the result.
|
||||
Sockets::SendInt(Sock, handle);
|
||||
|
||||
free(Packet);
|
||||
}
|
||||
|
||||
void Debug::UnloadLibrary(OrbisNetId Sock)
|
||||
{
|
||||
if (!IsDebugging || CurrentPID == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get next packet.
|
||||
auto Packet = (DbgSPRXPacket*)malloc(sizeof(DbgSPRXPacket));
|
||||
sceNetRecv(Sock, Packet, sizeof(DbgSPRXPacket), 0);
|
||||
|
||||
// Unload the library.
|
||||
auto result = GeneralIPC::UnLoadLibrary(CurrentPID, Packet->Handle);
|
||||
|
||||
// Send the result.
|
||||
Sockets::SendInt(Sock, result);
|
||||
|
||||
free(Packet);
|
||||
}
|
||||
|
||||
void Debug::ReloadLibrary(OrbisNetId Sock)
|
||||
{
|
||||
if (!IsDebugging || CurrentPID == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get next packet.
|
||||
auto Packet = (DbgSPRXPacket*)malloc(sizeof(DbgSPRXPacket));
|
||||
sceNetRecv(Sock, Packet, sizeof(DbgSPRXPacket), 0);
|
||||
|
||||
// Unload the library.
|
||||
auto result = GeneralIPC::UnLoadLibrary(CurrentPID, Packet->Handle);
|
||||
if (result != 0)
|
||||
{
|
||||
klog("Failed to unload %d\n", Packet->Handle);
|
||||
|
||||
Sockets::SendInt(Sock, result);
|
||||
|
||||
free(Packet);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait a second.
|
||||
sceKernelSleep(1);
|
||||
|
||||
// Load the library again.
|
||||
int handle = 0;
|
||||
GeneralIPC::LoadLibrary(CurrentPID, Packet->Path, &handle);
|
||||
|
||||
// Send the result.
|
||||
Sockets::SendInt(Sock, handle);
|
||||
|
||||
free(Packet);
|
||||
}
|
||||
|
||||
void Debug::GetLibraryList(OrbisNetId Sock)
|
||||
{
|
||||
if (!IsDebugging || CurrentPID == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the library list with path.
|
||||
std::vector<LibraryInfo> klibraryList;
|
||||
GeneralIPC::GetLibraryList(CurrentPID, klibraryList);
|
||||
|
||||
// Parse the library list.
|
||||
std::vector<LibraryPacket> libraryList;
|
||||
for (const auto& i : klibraryList)
|
||||
{
|
||||
OrbisKernelModuleInfo moduleInfo;
|
||||
moduleInfo.size = sizeof(OrbisKernelModuleInfo);
|
||||
sceKernelGetModuleInfo(i.ModuleHandle, &moduleInfo);
|
||||
|
||||
LibraryPacket temp;
|
||||
temp.Handle = i.ModuleHandle;
|
||||
strcpy(temp.Path, i.Path);
|
||||
temp.SegmentCount = moduleInfo.segmentCount;
|
||||
memcpy(&temp.Segments, &moduleInfo.segmentInfo, sizeof(OrbisKernelModuleSegmentInfo) * 4);
|
||||
|
||||
libraryList.push_back(temp);
|
||||
}
|
||||
|
||||
// Send the data size.
|
||||
Sockets::SendInt(Sock, libraryList.size());
|
||||
|
||||
// Send the list to host.
|
||||
Sockets::SendLargeData(Sock, (unsigned char*)libraryList.data(), libraryList.size() * sizeof(LibraryPacket));
|
||||
}
|
||||
|
||||
Debug::Debug()
|
||||
{
|
||||
|
||||
IsDebugging = false;
|
||||
CurrentPID = -1;
|
||||
}
|
||||
|
||||
Debug::~Debug()
|
||||
|
||||
@@ -15,4 +15,8 @@ private:
|
||||
void Attach(OrbisNetId Sock);
|
||||
void Detach(OrbisNetId Sock);
|
||||
|
||||
void LoadLibrary(OrbisNetId Sock);
|
||||
void UnloadLibrary(OrbisNetId Sock);
|
||||
void ReloadLibrary(OrbisNetId Sock);
|
||||
void GetLibraryList(OrbisNetId Sock);
|
||||
};
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
#include "GeneralIPC.h"
|
||||
#include <sys/un.h>
|
||||
|
||||
OrbisNetId GeneralIPC::Connect(const char* ProcessName)
|
||||
OrbisNetId GeneralIPC::Connect(int pid)
|
||||
{
|
||||
char fullPath[0x200];
|
||||
snprintf(fullPath, sizeof(fullPath), GENERAL_IPC_ADDR, ProcessName);
|
||||
snprintf(fullPath, sizeof(fullPath), GENERAL_IPC_ADDR, pid);
|
||||
|
||||
OrbisNetSockaddrUn addr = { 0 };
|
||||
addr.sun_family = ORBIS_NET_AF_LOCAL;
|
||||
@@ -42,21 +42,193 @@ bool GeneralIPC::SendCommand(OrbisNetId Sock, int Command)
|
||||
return Status == GIPC_OK;
|
||||
}
|
||||
|
||||
bool GeneralIPC::GetExtProcessInfo(const char* ProcessName, ExtProccesInfoPacket* info)
|
||||
bool GeneralIPC::GetLibraryList(int pid, std::vector<LibraryInfo>& Libraries)
|
||||
{
|
||||
auto Sock = Connect(ProcessName);
|
||||
|
||||
if (!Sock)
|
||||
// Open a new local socket connection for the process.
|
||||
auto sock = Connect(pid);
|
||||
if (!sock)
|
||||
{
|
||||
klog("[GeneralIPC] Failed to connect to socket.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SendCommand(Sock, GIPC_INFO))
|
||||
// Send the command.
|
||||
if (!SendCommand(sock, GIPC_LIB_LIST))
|
||||
{
|
||||
klog("[GeneralIPC] Failed to send command.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return sceNetRecv(Sock, (void*)info, sizeof(ExtProccesInfoPacket), 0) == 0;
|
||||
// Get the library count.
|
||||
int LibraryCount = 0;
|
||||
if (!Sockets::RecvInt(sock, &LibraryCount))
|
||||
{
|
||||
klog("[GeneralIPC] Failed to recv library count.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Resize the vector to accept the data.
|
||||
Libraries.resize(LibraryCount);
|
||||
|
||||
if (!Sockets::RecvLargeData(sock, (unsigned char*)Libraries.data(), LibraryCount * sizeof(LibraryInfo)))
|
||||
{
|
||||
klog("[GeneralIPC] Failed to recv library data.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeneralIPC::LoadLibrary(int pid, const char* Path, int* HandleOut)
|
||||
{
|
||||
// Open a new local socket connection for the process.
|
||||
auto sock = Connect(pid);
|
||||
if (!sock)
|
||||
{
|
||||
klog("[GeneralIPC] Failed to connect to socket.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the command.
|
||||
if (!SendCommand(sock, GIPC_LIB_LOAD))
|
||||
{
|
||||
klog("[GeneralIPC] Failed to send command.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Jailbreak the process.
|
||||
Jailbreak(pid);
|
||||
|
||||
// Create next packet.
|
||||
auto Packet = (LibPacket*)malloc(sizeof(LibPacket));
|
||||
strcpy(Packet->Path, Path);
|
||||
|
||||
// Send the packet.
|
||||
if (sceNetSend(sock, Packet, sizeof(LibPacket), 0) < 0)
|
||||
{
|
||||
klog("[GeneralIPC] Failed to send LibPacket.\n");
|
||||
|
||||
// Restore the jail.
|
||||
Jail(pid);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Recieve the result.
|
||||
if (!Sockets::RecvInt(sock, HandleOut))
|
||||
{
|
||||
klog("[GeneralIPC] Failed to recv handle.\n");
|
||||
|
||||
// Restore the jail.
|
||||
Jail(pid);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check to see if it was loaded successfully.
|
||||
if (*HandleOut <= 0)
|
||||
{
|
||||
klog("[GeneralIPC] Failed to load PRX '%s' (0x%llX).\n", *HandleOut);
|
||||
|
||||
// Restore the jail.
|
||||
Jail(pid);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Restore the jail.
|
||||
Jail(pid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeneralIPC::UnLoadLibrary(int pid, int Handle)
|
||||
{
|
||||
// Open a new local socket connection for the process.
|
||||
auto sock = Connect(pid);
|
||||
if (!sock)
|
||||
{
|
||||
klog("[GeneralIPC] Failed to connect to socket.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the command.
|
||||
if (!SendCommand(sock, GIPC_LIB_UNLOAD))
|
||||
{
|
||||
klog("[GeneralIPC] Failed to send command.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Recieve the result.
|
||||
int result = 0;
|
||||
if (!Sockets::RecvInt(sock, &result))
|
||||
{
|
||||
klog("[GeneralIPC] Failed to recv result.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check to see if it was unloaded successfully.
|
||||
if (result != 0)
|
||||
{
|
||||
klog("[GeneralIPC] Failed to un load PRX '%s' (0x%llX).\n", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeneralIPC::Jailbreak(int pid)
|
||||
{
|
||||
// Open a new local socket connection for the process.
|
||||
auto sock = Connect(pid);
|
||||
if (!sock)
|
||||
{
|
||||
klog("[GeneralIPC] Failed to connect to socket.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the command.
|
||||
if (!SendCommand(sock, GIPC_JAILBREAK))
|
||||
{
|
||||
klog("[GeneralIPC] Failed to send command.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Recieve the result.
|
||||
int result = 0;
|
||||
if (!Sockets::RecvInt(sock, &result))
|
||||
{
|
||||
klog("[GeneralIPC] Failed to recv result.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return result == 1;
|
||||
}
|
||||
|
||||
bool GeneralIPC::Jail(int pid)
|
||||
{
|
||||
// Open a new local socket connection for the process.
|
||||
auto sock = Connect(pid);
|
||||
if (!sock)
|
||||
{
|
||||
klog("[GeneralIPC] Failed to connect to socket.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the command.
|
||||
if (!SendCommand(sock, GIPC_JAIL))
|
||||
{
|
||||
klog("[GeneralIPC] Failed to send command.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Recieve the result.
|
||||
int result = 0;
|
||||
if (!Sockets::RecvInt(sock, &result))
|
||||
{
|
||||
klog("[GeneralIPC] Failed to recv result.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return result == 1;
|
||||
}
|
||||
@@ -4,9 +4,13 @@
|
||||
class GeneralIPC
|
||||
{
|
||||
private:
|
||||
static OrbisNetId Connect(const char* ProcessName);
|
||||
static OrbisNetId Connect(int pid);
|
||||
static bool SendCommand(OrbisNetId Sock, int Command);
|
||||
|
||||
public:
|
||||
static bool GetExtProcessInfo(const char* ProcessName, ExtProccesInfoPacket* info);
|
||||
static bool GetLibraryList(int pid, std::vector<LibraryInfo>& Libraries);
|
||||
static bool LoadLibrary(int pid, const char* Path, int* HandleOut);
|
||||
static bool UnLoadLibrary(int pid, int Handle);
|
||||
static bool Jailbreak(int pid);
|
||||
static bool Jail(int pid);
|
||||
};
|
||||
@@ -1,120 +0,0 @@
|
||||
#include "Common.h"
|
||||
#include "LncUtil.h"
|
||||
|
||||
uint64_t LncUtil::LibraryBaseAddress = 0;
|
||||
int(*LncUtil::_sceLncUtilGetAppId)(const char*);
|
||||
int(*LncUtil::_sceLncUtilLaunchApp)(const char* titleId, char* args, LaunchAppParam* appParam);
|
||||
int(*LncUtil::_sceLncUtilSuspendApp)(int AppId, int Flag);
|
||||
int(*LncUtil::_sceLncUtilResumeApp)(int AppId, int Flag);
|
||||
|
||||
#ifdef FIRMWARE_505
|
||||
#define sceLncUtilInitializeOffset 0x4BF0
|
||||
#define sceLncUtilGetAppIdOffset 0x4E10
|
||||
#define sceLncUtilLaunchAppOffset 0x4C10
|
||||
#define sceLncUtilSuspendAppOffset 0x4F20
|
||||
#define sceLncUtilResumeAppOffset 0x4F40
|
||||
#endif
|
||||
|
||||
#ifdef FIRMWARE_900
|
||||
#define sceLncUtilInitializeOffset 0x5580
|
||||
#define sceLncUtilGetAppIdOffset 0x5770
|
||||
#define sceLncUtilLaunchAppOffset 0x55A0
|
||||
#define sceLncUtilSuspendAppOffset 0x5880
|
||||
#define sceLncUtilResumeAppOffset 0x58A0
|
||||
#endif
|
||||
|
||||
int LncUtil::Init()
|
||||
{
|
||||
// Load the prx or get its module handle.
|
||||
int libHandle = sceKernelLoadStartModule("/system/common/lib/libSceSystemService.sprx", 0, nullptr, 0, nullptr, nullptr);
|
||||
if (libHandle == 0) {
|
||||
klog("Failed to load libSceSystemService Library.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get module info so we can find the base address.
|
||||
OrbisKernelModuleInfo moduleInfo;
|
||||
moduleInfo.size = sizeof(OrbisKernelModuleInfo);
|
||||
if (sceKernelGetModuleInfo(libHandle, &moduleInfo) != 0)
|
||||
{
|
||||
klog("Failed to get libSceSystemService module info.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Save base address for later.
|
||||
LibraryBaseAddress = (uint64_t)moduleInfo.segmentInfo[0].address;
|
||||
|
||||
if (LibraryBaseAddress <= 0)
|
||||
{
|
||||
klog("Failed to get libSceSystemService base address.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Init the lnc util library.
|
||||
auto sceLncUtilInitialize = (int(*)())(LibraryBaseAddress + sceLncUtilInitializeOffset);
|
||||
if (sceLncUtilInitialize() != 0)
|
||||
{
|
||||
klog("Failed to call sceLncUtilInitialize().\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set up Functions.
|
||||
_sceLncUtilGetAppId = (decltype(_sceLncUtilGetAppId))(LibraryBaseAddress + sceLncUtilGetAppIdOffset);
|
||||
_sceLncUtilLaunchApp = (decltype(_sceLncUtilLaunchApp))(LibraryBaseAddress + sceLncUtilLaunchAppOffset);
|
||||
_sceLncUtilSuspendApp = (decltype(_sceLncUtilSuspendApp))(LibraryBaseAddress + sceLncUtilSuspendAppOffset);
|
||||
_sceLncUtilResumeApp = (decltype(_sceLncUtilResumeApp))(LibraryBaseAddress + sceLncUtilResumeAppOffset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LncUtil::sceLncUtilGetAppId(const char* TitleId)
|
||||
{
|
||||
if ((uint64_t)_sceLncUtilGetAppId > sceLncUtilGetAppIdOffset)
|
||||
{
|
||||
return _sceLncUtilGetAppId(TitleId);
|
||||
}
|
||||
else
|
||||
{
|
||||
klog("failed to resolve sceLncUtilGetAppId\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int LncUtil::sceLncUtilLaunchApp(const char* titleId, char* args, LaunchAppParam* appParam)
|
||||
{
|
||||
if ((uint64_t)_sceLncUtilLaunchApp > sceLncUtilLaunchAppOffset)
|
||||
{
|
||||
return _sceLncUtilLaunchApp(titleId, args, appParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
klog("failed to resolve sceLncUtilLaunchApp\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int LncUtil::sceLncUtilSuspendApp(int AppId, int Flag)
|
||||
{
|
||||
if ((uint64_t)_sceLncUtilSuspendApp > sceLncUtilSuspendAppOffset)
|
||||
{
|
||||
return _sceLncUtilSuspendApp(AppId, Flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
klog("failed to resolve sceLncUtilSuspendApp\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int LncUtil::sceLncUtilResumeApp(int AppId, int Flag)
|
||||
{
|
||||
if ((uint64_t)_sceLncUtilResumeApp > sceLncUtilResumeAppOffset)
|
||||
{
|
||||
return _sceLncUtilResumeApp(AppId, Flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
klog("failed to resolve sceLncUtilResumeApp\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
enum AppType
|
||||
{
|
||||
AppTypeInvalid = -1,
|
||||
Unknown,
|
||||
ShellUI,
|
||||
Daemon,
|
||||
CDLG,
|
||||
MiniApp,
|
||||
BigApp,
|
||||
ShellCore,
|
||||
ShellApp
|
||||
};
|
||||
|
||||
struct AppStatus
|
||||
{
|
||||
int AppId;
|
||||
int LaunchRequestAppId;
|
||||
char AppType;
|
||||
};
|
||||
|
||||
enum Flag
|
||||
{
|
||||
Flag_None = 0,
|
||||
SkipLaunchCheck = 1,
|
||||
SkipResumeCheck = 1,
|
||||
SkipSystemUpdateCheck = 2,
|
||||
RebootPatchInstall = 4,
|
||||
VRMode = 8,
|
||||
NonVRMode = 16
|
||||
};
|
||||
|
||||
struct LaunchAppParam
|
||||
{
|
||||
unsigned int size; //0x00
|
||||
int userId; //0x04
|
||||
int appAttr; //0x08
|
||||
int enableCrashReport; //0x0C
|
||||
uint64_t checkFlag; //0x10
|
||||
};
|
||||
|
||||
class LncUtil
|
||||
{
|
||||
public:
|
||||
static int Init();
|
||||
static int sceLncUtilGetAppId(const char* TitleId);
|
||||
static int sceLncUtilLaunchApp(const char* titleId, char* args, LaunchAppParam* appParam);
|
||||
static int sceLncUtilSuspendApp(int AppId, int Flag);
|
||||
static int sceLncUtilResumeApp(int AppId, int Flag);
|
||||
|
||||
private:
|
||||
static uint64_t LibraryBaseAddress;
|
||||
static int(*_sceLncUtilGetAppId)(const char* titleId);
|
||||
static int(*_sceLncUtilLaunchApp)(const char* titleId, char* args, LaunchAppParam* appParam);
|
||||
static int(*_sceLncUtilSuspendApp)(int AppId, int Flag);
|
||||
static int(*_sceLncUtilResumeApp)(int AppId, int Flag);
|
||||
};
|
||||
@@ -69,11 +69,9 @@ del /s /q /f $(IntDir)\*.oelf</NMakeCleanCommandLine>
|
||||
<ClCompile Include="Debug.cpp" />
|
||||
<ClCompile Include="Flash.cpp" />
|
||||
<ClCompile Include="GeneralIPC.cpp" />
|
||||
<ClCompile Include="LncUtil.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="build.bat" />
|
||||
<ClCompile Include="Proc.cpp" />
|
||||
<ClCompile Include="ShellCoreUtil.cpp" />
|
||||
<ClCompile Include="ShellUIIPC.cpp" />
|
||||
<ClCompile Include="SocketListener.cpp" />
|
||||
<ClCompile Include="Sockets.cpp" />
|
||||
@@ -95,9 +93,7 @@ del /s /q /f $(IntDir)\*.oelf</NMakeCleanCommandLine>
|
||||
<ClInclude Include="Debug.h" />
|
||||
<ClInclude Include="Flash.h" />
|
||||
<ClInclude Include="GeneralIPC.h" />
|
||||
<ClInclude Include="LncUtil.h" />
|
||||
<ClInclude Include="Proc.h" />
|
||||
<ClInclude Include="ShellCoreUtil.h" />
|
||||
<ClInclude Include="ShellUIIPC.h" />
|
||||
<ClInclude Include="SocketListener.h" />
|
||||
<ClInclude Include="Sockets.h" />
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Utilities">
|
||||
<UniqueIdentifier>{2695a710-ecaf-42db-80bb-c904ec4dfb8f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -88,12 +84,6 @@
|
||||
<ClCompile Include="GeneralIPC.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LncUtil.cpp">
|
||||
<Filter>Source Files\Utilities\PS Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ShellCoreUtil.cpp">
|
||||
<Filter>Source Files\Utilities\PS Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SystemMonitor.cpp">
|
||||
<Filter>Source Files\Utilities\PS Utils</Filter>
|
||||
</ClCompile>
|
||||
@@ -156,12 +146,6 @@
|
||||
<ClInclude Include="GeneralIPC.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LncUtil.h">
|
||||
<Filter>Header Files\Utilities\PS Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ShellCoreUtil.h">
|
||||
<Filter>Header Files\Utilities\PS Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SystemMonitor.h">
|
||||
<Filter>Header Files\Utilities\PS Utils</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
#include "Common.h"
|
||||
#include "ShellCoreUtil.h"
|
||||
|
||||
uint64_t ShellCoreUtil::LibraryBaseAddress = 0;
|
||||
int(*ShellCoreUtil::_sceShellCoreUtilGetFreeSizeOfUserPartition)(uint64_t* free, uint64_t* total);
|
||||
|
||||
#ifdef FIRMWARE_505
|
||||
#define sceShellCoreUtilGetFreeSizeOfUserPartitionOffset 0x105A0
|
||||
#endif
|
||||
|
||||
#ifdef FIRMWARE_900
|
||||
#define sceShellCoreUtilGetFreeSizeOfUserPartitionOffset 0x10B40
|
||||
#endif
|
||||
|
||||
int ShellCoreUtil::Init()
|
||||
{
|
||||
// Load the prx or get its module handle.
|
||||
int libHandle = sceKernelLoadStartModule("/system/common/lib/libSceSystemService.sprx", 0, nullptr, 0, nullptr, nullptr);
|
||||
if (libHandle == 0) {
|
||||
klog("Failed to load libSceSystemService Library.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get module info so we can find the base address.
|
||||
OrbisKernelModuleInfo moduleInfo;
|
||||
moduleInfo.size = sizeof(OrbisKernelModuleInfo);
|
||||
if (sceKernelGetModuleInfo(libHandle, &moduleInfo) != 0)
|
||||
{
|
||||
klog("Failed to get libSceSystemService module info.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Save base address for later.
|
||||
LibraryBaseAddress = (uint64_t)moduleInfo.segmentInfo[0].address;
|
||||
|
||||
if (LibraryBaseAddress <= 0)
|
||||
{
|
||||
klog("Failed to get libSceSystemService base address.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set up Functions.
|
||||
_sceShellCoreUtilGetFreeSizeOfUserPartition = (decltype(_sceShellCoreUtilGetFreeSizeOfUserPartition))(LibraryBaseAddress + sceShellCoreUtilGetFreeSizeOfUserPartitionOffset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ShellCoreUtil::sceShellCoreUtilGetFreeSizeOfUserPartition(uint64_t* free, uint64_t* total)
|
||||
{
|
||||
if ((uint64_t)_sceShellCoreUtilGetFreeSizeOfUserPartition > sceShellCoreUtilGetFreeSizeOfUserPartitionOffset)
|
||||
{
|
||||
return _sceShellCoreUtilGetFreeSizeOfUserPartition(free, total);
|
||||
}
|
||||
else
|
||||
{
|
||||
klog("failed to resolve sceShellCoreUtilGetFreeSizeOfUserPartition\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class ShellCoreUtil
|
||||
{
|
||||
public:
|
||||
static int Init();
|
||||
static int sceShellCoreUtilGetFreeSizeOfUserPartition(uint64_t* free, uint64_t* total);
|
||||
|
||||
private:
|
||||
static uint64_t LibraryBaseAddress;
|
||||
static int(*_sceShellCoreUtilGetFreeSizeOfUserPartition)(uint64_t* free, uint64_t* total);
|
||||
};
|
||||
@@ -3,12 +3,28 @@
|
||||
|
||||
bool Sockets::SendInt(OrbisNetId Sock, int val)
|
||||
{
|
||||
return !(sceNetSend(Sock, &val, sizeof(int), 0) < 0);
|
||||
auto res = sceNetSend(Sock, &val, sizeof(int), 0);
|
||||
if (res <= 0)
|
||||
{
|
||||
klog("SendInt(): Failed to send %llX\n", res);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sockets::RecvInt(OrbisNetId Sock, int* val)
|
||||
{
|
||||
return !(sceNetRecv(Sock, val, sizeof(int), 0) < 0);
|
||||
auto res = sceNetRecv(Sock, val, sizeof(int), 0);
|
||||
if (res <= 0)
|
||||
{
|
||||
klog("RecvInt(): Failed to send %llX\n", res);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sockets::SendLargeData(OrbisNetId Sock, unsigned char* data, size_t dataLen)
|
||||
@@ -25,6 +41,7 @@ bool Sockets::SendLargeData(OrbisNetId Sock, unsigned char* data, size_t dataLen
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
klog("SendLargeData() Error: %llX\n", res);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -32,5 +49,28 @@ bool Sockets::SendLargeData(OrbisNetId Sock, unsigned char* data, size_t dataLen
|
||||
CurrentPosition += res;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sockets::RecvLargeData(OrbisNetId Sock, unsigned char* data, size_t dataLen)
|
||||
{
|
||||
size_t DataLeft = dataLen;
|
||||
int Received = 0;
|
||||
int res = 0;
|
||||
|
||||
while (DataLeft > 0)
|
||||
{
|
||||
size_t DataChunkSize = std::min((size_t)8192, DataLeft);
|
||||
res = sceNetRecv(Sock, data + Received, DataChunkSize, 0);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Received += res;
|
||||
DataLeft -= res;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -6,7 +6,7 @@ public:
|
||||
static bool SendInt(OrbisNetId Sock, int val);
|
||||
static bool RecvInt(OrbisNetId Sock, int* val);
|
||||
static bool SendLargeData(OrbisNetId Sock, unsigned char* data, size_t dataLen);
|
||||
|
||||
static bool RecvLargeData(OrbisNetId Sock, unsigned char* data, size_t dataLen);
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
@@ -139,7 +139,7 @@ void Target::SendTargetInfo(OrbisNetId Sock)
|
||||
sceUserServiceGetForegroundUser(&Packet->ForegroundAccountId);
|
||||
|
||||
// Storage Stats.
|
||||
auto res = ShellCoreUtil::sceShellCoreUtilGetFreeSizeOfUserPartition(&Packet->FreeSpace, &Packet->TotalSpace);
|
||||
auto res = sceShellCoreUtilGetFreeSizeOfUserPartition(&Packet->FreeSpace, &Packet->TotalSpace);
|
||||
|
||||
// Perf Stats. TODO: Move from toolbox
|
||||
/*Packet->ThreadCount = SystemMonitor::Thread_Count;
|
||||
|
||||
@@ -78,18 +78,10 @@ bool LoadModules()
|
||||
}
|
||||
|
||||
// Init temporary wrapper for lncutils.
|
||||
res = LncUtil::Init();
|
||||
res = sceLncUtilInitialize();
|
||||
if (res != 0)
|
||||
{
|
||||
klog("LoadModules(): LncUtil::Init failed (%llX)\n", res);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Init temporary wrapper for shellcoreutils.
|
||||
res = ShellCoreUtil::Init();
|
||||
if (res != 0)
|
||||
{
|
||||
klog("LoadModules(): ShellCoreUtil::Init failed (%llX)\n", res);
|
||||
klog("LoadModules(): sceLncUtilInitialize failed (%llX)\n", res);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -289,4 +281,70 @@ int GetProcessList(std::vector<kinfo_proc>& ProcessList)
|
||||
}), ProcessList.end());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void build_iovec(iovec** iov, int* iovlen, const char* name, const void* val, size_t len) {
|
||||
int i;
|
||||
|
||||
if (*iovlen < 0)
|
||||
return;
|
||||
|
||||
i = *iovlen;
|
||||
*iov = (iovec*)realloc(*iov, sizeof * *iov * (i + 2));
|
||||
if (*iov == NULL) {
|
||||
*iovlen = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
(*iov)[i].iov_base = strdup(name);
|
||||
(*iov)[i].iov_len = strlen(name) + 1;
|
||||
++i;
|
||||
|
||||
(*iov)[i].iov_base = (void*)val;
|
||||
if (len == (size_t)-1) {
|
||||
if (val != NULL)
|
||||
len = strlen((const char*)val) + 1;
|
||||
else
|
||||
len = 0;
|
||||
}
|
||||
(*iov)[i].iov_len = (int)len;
|
||||
|
||||
*iovlen = ++i;
|
||||
}
|
||||
|
||||
int nmount(struct iovec* iov, unsigned int niov, int flags)
|
||||
{
|
||||
return syscall(378, iov, niov, flags);
|
||||
}
|
||||
|
||||
bool LinkDir(const char* Dir, const char* LinkedDir)
|
||||
{
|
||||
auto res = sceKernelMkdir(LinkedDir, 0777);
|
||||
if (res != 0)
|
||||
{
|
||||
if (res == 0x80020011)
|
||||
{
|
||||
klog("Directory '%s' already exists!\n", LinkedDir);
|
||||
return true;
|
||||
}
|
||||
|
||||
klog("Failed to make dir '%s' err: %llX\n", LinkedDir, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct iovec* iov = NULL;
|
||||
int iovlen = 0;
|
||||
|
||||
build_iovec(&iov, &iovlen, "fstype", "nullfs", -1);
|
||||
build_iovec(&iov, &iovlen, "fspath", LinkedDir, -1);
|
||||
build_iovec(&iov, &iovlen, "target", Dir, -1);
|
||||
|
||||
if (nmount(iov, iovlen, 0))
|
||||
{
|
||||
klog("nmount failed\n");
|
||||
sceKernelRmdir(LinkedDir);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -35,3 +35,4 @@ struct kinfo_proc {
|
||||
|
||||
void hexdump(void* ptr, int buflen);
|
||||
int GetProcessList(std::vector<kinfo_proc>& ProcessList);
|
||||
bool LinkDir(const char* Dir, const char* LinkedDir);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
#define ORBISLIB_MAJOR 3
|
||||
#define ORBISLIB_MINOR 0
|
||||
#define ORBISLIB_BUILDVERSION 874
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
#if defined(_DEBUG)
|
||||
#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Dev Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#else
|
||||
#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#endif
|
||||
#pragma once
|
||||
#define ORBISLIB_MAJOR 3
|
||||
#define ORBISLIB_MINOR 0
|
||||
#define ORBISLIB_BUILDVERSION 933
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
#if defined(_DEBUG)
|
||||
#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Dev Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#else
|
||||
#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SETLOCAL EnableDelayedExpansion
|
||||
|
||||
Rem Libraries to link in
|
||||
set libraries=-lc++ -lc -lSceSysmodule -lkernel -lSceVideoOut -lSceSystemService -lSceSysCore -lSceSystemStateMgr -lSceNet -lScePad -lSceUserService -lSceRegMgr -lSceFreeType -lSceMsgDialog -lSceCommonDialog -lGoldHEN_Hook -lSQLite -lSceAppInstUtil
|
||||
set libraries=-lc++ -lc -lSceSysmodule -lkernel -lSceVideoOut -lSceSystemService -lSceSysCore -lSceSystemStateMgr -lSceNet -lScePad -lSceUserService -lSceRegMgr -lSceFreeType -lSceMsgDialog -lSceCommonDialog -lGoldHEN_Hook -lSQLite -lSceAppInstUtil -lSceLncUtil -lSceShellCoreUtil
|
||||
|
||||
Rem Read the script arguments into local vars
|
||||
set intdir=%1
|
||||
@@ -31,7 +31,7 @@ copy "eboot.bin" %outputPath%\Playstation\Build\pkg\Daemons\ORBS30000\eboot.bin
|
||||
del "eboot.bin"
|
||||
|
||||
REM Generate the script. Will overwrite any existing temp.txt
|
||||
echo open 1.1.0.14 2121> temp.txt
|
||||
echo open 1.1.0.15 2121> temp.txt
|
||||
echo anonymous>> temp.txt
|
||||
echo anonymous>> temp.txt
|
||||
echo cd "/system/vsh/app/ORBS30000/">> temp.txt
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
#include "API.h"
|
||||
#include "GoldHEN.h"
|
||||
|
||||
#include "AppDatabase.h"
|
||||
|
||||
#include "GeneralIPC.h"
|
||||
|
||||
void exiting()
|
||||
{
|
||||
klog("Good bye friends! :)\n");
|
||||
@@ -67,9 +63,9 @@ int main()
|
||||
}
|
||||
#endif
|
||||
|
||||
//#define KILLSHELLUI
|
||||
// #define KILLSHELLUI
|
||||
#ifdef KILLSHELLUI
|
||||
sceSystemServiceKillApp(LncUtil::sceLncUtilGetAppId("NPXS20001"), -1, 0, 0);
|
||||
sceSystemServiceKillApp(sceLncUtilGetAppId("NPXS20001"), -1, 0, 0);
|
||||
#endif
|
||||
|
||||
sceSystemServiceLoadExec("exit", 0);
|
||||
|
||||
@@ -22,5 +22,6 @@
|
||||
#include "../../Misc/libjbc.h"
|
||||
#include "Utilities.h"
|
||||
#include "LocalSocketListener.h"
|
||||
#include "Sockets.h"
|
||||
|
||||
extern LocalSocketListener* LocalListener;
|
||||
@@ -20,6 +20,8 @@ void* LocalSocketListener::ClientThread(void* tdParam)
|
||||
|
||||
void* LocalSocketListener::DoWork()
|
||||
{
|
||||
Jailbreak();
|
||||
|
||||
OrbisNetSockaddrUn addr = { 0 };
|
||||
addr.sun_family = ORBIS_NET_AF_LOCAL;
|
||||
strncpy(addr.sun_path, this->ServerAddress, sizeof(addr.sun_path));
|
||||
@@ -44,6 +46,8 @@ void* LocalSocketListener::DoWork()
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
RestoreJail();
|
||||
|
||||
if (sceNetListen(this->Socket, 100) != 0)
|
||||
{
|
||||
klog("Failed to start listening on Socket.\n");
|
||||
@@ -86,6 +90,7 @@ void* LocalSocketListener::DoWork()
|
||||
|
||||
int optval = 1;
|
||||
sceNetSetsockopt(ClientSocket, ORBIS_NET_SOL_SOCKET, ORBIS_NET_SO_NOSIGPIPE, &optval, sizeof(optval));
|
||||
|
||||
// Set up thread params.
|
||||
ClientThreadParams* Params = new ClientThreadParams();
|
||||
Params->LocalSocketListener = this;
|
||||
@@ -105,9 +110,9 @@ void* LocalSocketListener::DoWork()
|
||||
Cleanup:
|
||||
klog("Listener Thread Exiting!\n");
|
||||
|
||||
|
||||
// Clean up.
|
||||
sceNetSocketClose(this->Socket);
|
||||
sceKernelUnlink(this->ServerAddress);
|
||||
|
||||
// Kill our thread and exit.
|
||||
scePthreadExit(NULL);
|
||||
|
||||
@@ -5,37 +5,59 @@ LocalSocketListener* LocalListener = nullptr;
|
||||
|
||||
void SendLibraryList(OrbisNetId Sock)
|
||||
{
|
||||
int MaxOutput = 0;
|
||||
if (!SockRecvInt(Sock, &MaxOutput))
|
||||
{
|
||||
klog("Failed to recv int.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the libraries.
|
||||
LibraryInfo* LibraryList = (LibraryInfo*)malloc(MaxOutput * sizeof(LibraryInfo));
|
||||
int RealLibCount = jbc_get_proc_libraries(LibraryList, MaxOutput);
|
||||
|
||||
// Make sure not to overflow the sender.
|
||||
if (RealLibCount > MaxOutput)
|
||||
{
|
||||
klog("Warning: SendLibraryList MaxOutput too small.");
|
||||
RealLibCount = MaxOutput;
|
||||
}
|
||||
LibraryInfo* LibraryList = (LibraryInfo*)malloc(200 * sizeof(LibraryInfo));
|
||||
int RealLibCount = jbc_get_proc_libraries(LibraryList, 200);
|
||||
|
||||
// Send the Count
|
||||
SockSendInt(Sock, RealLibCount);
|
||||
Sockets::SendInt(Sock, RealLibCount);
|
||||
|
||||
// Ship it.
|
||||
sceNetSend(Sock, (void*)LibraryList, RealLibCount * sizeof(LibraryInfo), 0);
|
||||
Sockets::SendLargeData(Sock, (unsigned char*)LibraryList, RealLibCount * sizeof(LibraryInfo));
|
||||
|
||||
// Clean up!
|
||||
free(LibraryList);
|
||||
}
|
||||
|
||||
void LoadUnloadLib(int Command, OrbisNetId Sock)
|
||||
{
|
||||
auto Packet = (LibPacket*)malloc(sizeof(LibPacket));
|
||||
sceNetRecv(Sock, Packet, sizeof(LibPacket), 0);
|
||||
|
||||
if (Command == GIPC_LIB_LOAD)
|
||||
{
|
||||
int res = sceKernelLoadStartModule(Packet->Path, 0, 0, 0, 0, 0);
|
||||
|
||||
// Send the result.
|
||||
Sockets::SendInt(Sock, res);
|
||||
}
|
||||
else
|
||||
{
|
||||
int res = sceKernelStopUnloadModule(Packet->Handle, 0, 0, 0, 0, 0);
|
||||
|
||||
// Send the result.
|
||||
Sockets::SendInt(Sock, res);
|
||||
}
|
||||
|
||||
free(Packet);
|
||||
}
|
||||
|
||||
void ListenerClientThread(void* tdParam, OrbisNetId Sock)
|
||||
{
|
||||
int Command = RecieveInt(Sock);
|
||||
int Command = 0;
|
||||
|
||||
if (!Sockets::RecvInt(Sock, &Command))
|
||||
{
|
||||
klog("Failed to recv Command.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Sockets::SendInt(Sock, GIPC_OK))
|
||||
{
|
||||
klog("Failed to send confirm command.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command != -1)
|
||||
{
|
||||
switch (Command)
|
||||
@@ -48,14 +70,27 @@ void ListenerClientThread(void* tdParam, OrbisNetId Sock)
|
||||
SendLibraryList(Sock); // Really Only needed for the path.
|
||||
break;
|
||||
|
||||
case GIPC_LIB_LOAD:
|
||||
case GIPC_LIB_UNLOAD:
|
||||
|
||||
LoadUnloadLib(Command, Sock);
|
||||
|
||||
break;
|
||||
|
||||
case GIPC_JAILBREAK:
|
||||
//sys_sdk_jailbreak(&JailBackup); // Could just use libjbc
|
||||
SockSendInt(Sock, GIPC_OK);
|
||||
|
||||
Jailbreak();
|
||||
|
||||
Sockets::SendInt(Sock, GIPC_OK);
|
||||
|
||||
break;
|
||||
|
||||
case GIPC_JAIL:
|
||||
//sys_sdk_unjailbreak(&JailBackup); // Could just use libjbc
|
||||
SockSendInt(Sock, GIPC_OK);
|
||||
|
||||
RestoreJail();
|
||||
|
||||
Sockets::SendInt(Sock, GIPC_OK);
|
||||
|
||||
break;
|
||||
|
||||
case GIPC_RW:
|
||||
@@ -75,16 +110,15 @@ extern "C"
|
||||
{
|
||||
klog("Hello from Helper!\n");
|
||||
|
||||
char ProcName[0x20];
|
||||
sceKernelGetProcessName(getpid(), ProcName);
|
||||
|
||||
klog("Helping with %s\n", ProcName);
|
||||
klog("Helping with %d\n", getpid());
|
||||
|
||||
char serverAddress[0x200];
|
||||
snprintf(serverAddress, sizeof(serverAddress), GENERAL_IPC_ADDR, ProcName);
|
||||
snprintf(serverAddress, sizeof(serverAddress), GENERAL_IPC_ADDR, getpid());
|
||||
|
||||
LocalListener = new LocalSocketListener(ListenerClientThread, nullptr, serverAddress);
|
||||
|
||||
klog("Helper Init Complete.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ del /s /q /f $(IntDir)\*.oelf</NMakeCleanCommandLine>
|
||||
<ClCompile Include="hde64.cpp" />
|
||||
<ClCompile Include="LocalSocketListener.cpp" />
|
||||
<ClCompile Include="OrbisLibGeneralHelper.cpp" />
|
||||
<ClCompile Include="Socket.cpp" />
|
||||
<ClCompile Include="Utilities.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -75,6 +76,7 @@ del /s /q /f $(IntDir)\*.oelf</NMakeCleanCommandLine>
|
||||
<ClInclude Include="Detour.h" />
|
||||
<ClInclude Include="hde64.h" />
|
||||
<ClInclude Include="LocalSocketListener.h" />
|
||||
<ClInclude Include="Sockets.h" />
|
||||
<ClInclude Include="table64.h" />
|
||||
<ClInclude Include="Utilities.h" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -9,26 +9,31 @@
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
<Filter Include="Source Files\Utilities">
|
||||
<UniqueIdentifier>{c3adf471-ac5e-4e6e-a359-e08060b8cec1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\Utilities">
|
||||
<UniqueIdentifier>{9efcd69e-6e69-4ace-a1dd-36024540ec2a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="OrbisLibGeneralHelper.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LocalSocketListener.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utilities.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Detour.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
<ClCompile Include="LocalSocketListener.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hde64.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Detour.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Socket.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -38,20 +43,23 @@
|
||||
<ClInclude Include="Common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LocalSocketListener.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utilities.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Detour.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hde64.h">
|
||||
<Filter>Header Files</Filter>
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="table64.h">
|
||||
<Filter>Header Files</Filter>
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LocalSocketListener.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hde64.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Detour.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Sockets.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "Common.h"
|
||||
#include "Sockets.h"
|
||||
|
||||
bool Sockets::SendInt(OrbisNetId Sock, int val)
|
||||
{
|
||||
return !(sceNetSend(Sock, &val, sizeof(int), 0) < 0);
|
||||
}
|
||||
|
||||
bool Sockets::RecvInt(OrbisNetId Sock, int* val)
|
||||
{
|
||||
return !(sceNetRecv(Sock, val, sizeof(int), 0) < 0);
|
||||
}
|
||||
|
||||
bool Sockets::SendLargeData(OrbisNetId Sock, unsigned char* data, size_t dataLen)
|
||||
{
|
||||
unsigned char* CurrentPosition = data;
|
||||
size_t DataLeft = dataLen;
|
||||
int res = 0;
|
||||
|
||||
while (DataLeft > 0)
|
||||
{
|
||||
size_t DataChunkSize = std::min((size_t)8192, DataLeft);
|
||||
|
||||
res = sceNetSend(Sock, CurrentPosition, DataChunkSize, 0);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DataLeft -= res;
|
||||
CurrentPosition += res;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
class Sockets
|
||||
{
|
||||
public:
|
||||
static bool SendInt(OrbisNetId Sock, int val);
|
||||
static bool RecvInt(OrbisNetId Sock, int* val);
|
||||
static bool SendLargeData(OrbisNetId Sock, unsigned char* data, size_t dataLen);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
@@ -19,25 +19,30 @@ void klog(const char* fmt, ...)
|
||||
sceKernelDebugOutText(0, Buffer2);
|
||||
}
|
||||
|
||||
bool SockSendInt(OrbisNetId Sock, int val)
|
||||
{
|
||||
return !(sceNetSend(Sock, &val, sizeof(int), 0) < 0);
|
||||
}
|
||||
jbc_cred BackupCred;
|
||||
bool Jailbroken = false;
|
||||
|
||||
bool SockRecvInt(OrbisNetId Sock, int* val)
|
||||
void Jailbreak()
|
||||
{
|
||||
return !(sceNetRecv(Sock, val, sizeof(int), 0) < 0);
|
||||
}
|
||||
|
||||
int RecieveInt(OrbisNetId Sock)
|
||||
{
|
||||
int Int = 0;
|
||||
if (sceNetRecv(Sock, &Int, sizeof(int), 0) < 0)
|
||||
if (!Jailbroken)
|
||||
{
|
||||
SockSendInt(Sock, GIPC_FAIL);
|
||||
return 0;
|
||||
}
|
||||
jbc_get_cred(&BackupCred);
|
||||
|
||||
SockSendInt(Sock, GIPC_OK);
|
||||
return Int;
|
||||
jbc_cred jbCred;
|
||||
jbc_get_cred(&jbCred);
|
||||
|
||||
jbc_jailbreak_cred(&jbCred);
|
||||
|
||||
jbc_set_cred(&jbCred);
|
||||
|
||||
Jailbroken = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreJail()
|
||||
{
|
||||
if (Jailbroken)
|
||||
{
|
||||
jbc_set_cred(&BackupCred);
|
||||
}
|
||||
}
|
||||
@@ -2,24 +2,5 @@
|
||||
|
||||
// Misc
|
||||
void klog(const char* fmt, ...);
|
||||
|
||||
// Networking
|
||||
bool SockSendInt(OrbisNetId Sock, int val);
|
||||
bool SockRecvInt(OrbisNetId Sock, int* val);
|
||||
int RecieveInt(OrbisNetId Sock);
|
||||
|
||||
template<class T> T* RecievePacket(OrbisNetId Sock)
|
||||
{
|
||||
auto Packet = (T*)malloc(sizeof(T));
|
||||
|
||||
if (sceNetRecv(Sock, Packet, sizeof(T), 0) < 0)
|
||||
{
|
||||
SockSendInt(Sock, GIPC_FAIL);
|
||||
free(Packet);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SockSendInt(Sock, GIPC_OK);
|
||||
|
||||
return Packet;
|
||||
}
|
||||
void Jailbreak();
|
||||
void RestoreJail();
|
||||
@@ -48,7 +48,7 @@ copy "%outputPrx%" "%outputPath%\Playstation\Build\pkg\Orbis Suite\%targetname%.
|
||||
del "%outputPrx%"
|
||||
|
||||
REM Generate the script. Will overwrite any existing temp.txt
|
||||
echo open 1.1.0.13 2121> temp.txt
|
||||
echo open 1.1.0.15 2121> temp.txt
|
||||
echo anonymous>> temp.txt
|
||||
echo anonymous>> temp.txt
|
||||
echo cd "/data/Orbis Suite/">> temp.txt
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
#define ORBIS_TOOLBOX_MAJOR 2
|
||||
#define ORBIS_TOOLBOX_MINOR 0
|
||||
#define ORBIS_TOOLBOX_BUILDVERSION 324
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
#if defined(ORBIS_TOOLBOX_DEBUG)
|
||||
#define ORBIS_TOOLBOX_BUILDSTRING ("[Orbis Toolbox " stringify(ORBIS_TOOLBOX_MAJOR) "." stringify(ORBIS_TOOLBOX_MINOR) "] Dev Build " stringify(ORBIS_TOOLBOX_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#else
|
||||
#define ORBIS_TOOLBOX_BUILDSTRING ("[Orbis Toolbox " stringify(ORBIS_TOOLBOX_MAJOR) "." stringify(ORBIS_TOOLBOX_MINOR) "] Build " stringify(ORBIS_TOOLBOX_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#endif
|
||||
#pragma once
|
||||
#define ORBIS_TOOLBOX_MAJOR 2
|
||||
#define ORBIS_TOOLBOX_MINOR 0
|
||||
#define ORBIS_TOOLBOX_BUILDVERSION 325
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
#if defined(ORBIS_TOOLBOX_DEBUG)
|
||||
#define ORBIS_TOOLBOX_BUILDSTRING ("[Orbis Toolbox " stringify(ORBIS_TOOLBOX_MAJOR) "." stringify(ORBIS_TOOLBOX_MINOR) "] Dev Build " stringify(ORBIS_TOOLBOX_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#else
|
||||
#define ORBIS_TOOLBOX_BUILDSTRING ("[Orbis Toolbox " stringify(ORBIS_TOOLBOX_MAJOR) "." stringify(ORBIS_TOOLBOX_MINOR) "] Build " stringify(ORBIS_TOOLBOX_BUILDVERSION) " " __DATE__ " " __TIME__)
|
||||
#endif
|
||||
|
||||
@@ -48,7 +48,7 @@ copy "%outputPrx%" "%outputPath%\Playstation\Build\pkg\Orbis Toolbox\%targetname
|
||||
del "%outputPrx%"
|
||||
|
||||
REM Generate the script. Will overwrite any existing temp.txt
|
||||
echo open 1.1.0.79 2121> temp.txt
|
||||
echo open 1.1.0.15 2121> temp.txt
|
||||
echo anonymous>> temp.txt
|
||||
echo anonymous>> temp.txt
|
||||
echo cd "/data/Orbis Toolbox/">> temp.txt
|
||||
|
||||
@@ -55,10 +55,10 @@ namespace OrbisLib2.Common.API
|
||||
API_DBG_SET_DBGREG,
|
||||
|
||||
/* Remote Library functions */
|
||||
API_DBG_LOAD_SPRX,
|
||||
API_DBG_UNLOAD_SPRX,
|
||||
API_DBG_RELOAD_SPRX,
|
||||
API_DBG_MODULE_LIST,
|
||||
API_DBG_LOAD_LIBRARY,
|
||||
API_DBG_UNLOAD_LIBRARY,
|
||||
API_DBG_RELOAD_LIBRARY,
|
||||
API_DBG_LIBRARY_LIST,
|
||||
|
||||
/* Thread Management */
|
||||
API_DBG_THREAD_LIST,
|
||||
@@ -191,35 +191,41 @@ namespace OrbisLib2.Common.API
|
||||
#region Debug
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public struct SegmentInfo
|
||||
{
|
||||
public ulong baseAddr;
|
||||
public uint size;
|
||||
public int prot;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Ansi)]
|
||||
public struct LibraryPacket
|
||||
{
|
||||
public Int64 Handle;
|
||||
public long Handle;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string Path;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
|
||||
public int SegmentCount;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public SegmentInfo[] Segments;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public struct ProcRWPacket
|
||||
public struct DbgRWPacket
|
||||
{
|
||||
public UInt64 Address;
|
||||
public UInt64 Length;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public struct ProcSPRXPacket
|
||||
public struct DbgSPRXPacket
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string Name;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string Path;
|
||||
public int ModuleHandle;
|
||||
public int Flags;
|
||||
public int Handle;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public struct ProcBreakpointPacket
|
||||
public struct DbgBreakpointPacket
|
||||
{
|
||||
public int Index;
|
||||
public UInt64 Address;
|
||||
@@ -234,14 +240,6 @@ namespace OrbisLib2.Common.API
|
||||
|
||||
#region Target
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public struct SegmentInfo
|
||||
{
|
||||
public UInt64 baseAddr;
|
||||
public uint size;
|
||||
public int prot;
|
||||
}
|
||||
|
||||
public enum ConsoleTypes
|
||||
{
|
||||
UNK,
|
||||
|
||||
@@ -13,16 +13,23 @@ namespace OrbisLib2.Common.Helpers
|
||||
/// <param name="data">The data to be recieved.</param>
|
||||
public static void RecvLarge(this Socket s, byte[] data)
|
||||
{
|
||||
int Left = data.Length;
|
||||
int Received = 0;
|
||||
|
||||
while (Left > 0)
|
||||
try
|
||||
{
|
||||
var chunkSize = Math.Min(s.ReceiveBufferSize, Left);
|
||||
var res = s.Receive(data, Received, chunkSize, 0);
|
||||
int Left = data.Length;
|
||||
int Received = 0;
|
||||
|
||||
Received += res;
|
||||
Left -= res;
|
||||
while (Left > 0)
|
||||
{
|
||||
var chunkSize = Math.Min(s.ReceiveBufferSize, Left);
|
||||
var res = s.Receive(data, Received, chunkSize, 0);
|
||||
|
||||
Received += res;
|
||||
Left -= res;
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,7 @@ namespace OrbisLib2.Dialog
|
||||
var selectedProc = (ProcInfo)dlg.ProcessList.SelectedItem;
|
||||
if(selectedProc != null)
|
||||
{
|
||||
// TODO: Handle Attach here.
|
||||
Console.WriteLine($"Attaching to {selectedProc.Name}");
|
||||
TargetManager.SelectedTarget.Debug.Attach(selectedProc.ProcessId);
|
||||
}
|
||||
|
||||
return dlg.Result;
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
using OrbisLib2.Common.API;
|
||||
using OrbisLib2.Common.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity.Core.Metadata.Edm;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static SQLite.SQLite3;
|
||||
|
||||
namespace OrbisLib2.Targets
|
||||
{
|
||||
public record SegmentInfo(ulong Address, uint Size, int Protection);
|
||||
|
||||
public record LibraryInfo(long Handle, string Path, SegmentInfo[] Segments);
|
||||
|
||||
public class Debug
|
||||
{
|
||||
private Target Target;
|
||||
|
||||
public Debug(Target Target)
|
||||
{
|
||||
this.Target = Target;
|
||||
}
|
||||
|
||||
public bool IsDebugging
|
||||
{
|
||||
get { return GetCurrentProcessId() != -1; }
|
||||
}
|
||||
|
||||
public bool Attach(int pid)
|
||||
{
|
||||
var result = API.SendCommand(Target, 3, APICommands.API_DBG_ATTACH, (Socket Sock, APIResults Result) =>
|
||||
{
|
||||
Sock.SendInt32(pid);
|
||||
|
||||
var res = Sock.RecvInt32();
|
||||
|
||||
if (res == 1)
|
||||
Result = APIResults.API_OK;
|
||||
else
|
||||
Result = APIResults.API_ERROR_GENERAL;
|
||||
});
|
||||
|
||||
return result == APIResults.API_OK;
|
||||
}
|
||||
|
||||
// TODO: We probably want to detach when our program is exiting.
|
||||
public bool Detach()
|
||||
{
|
||||
if(!IsDebugging)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var result = API.SendCommand(Target, 3, APICommands.API_DBG_DETACH, (Socket Sock, APIResults Result) =>
|
||||
{
|
||||
var res = Sock.RecvInt32();
|
||||
|
||||
if (res == 1)
|
||||
Result = APIResults.API_OK;
|
||||
else
|
||||
Result = APIResults.API_ERROR_GENERAL;
|
||||
});
|
||||
|
||||
return result == APIResults.API_OK;
|
||||
}
|
||||
|
||||
public int GetCurrentProcessId()
|
||||
{
|
||||
var currentPid = -1;
|
||||
var result = API.SendCommand(Target, 3, APICommands.API_DBG_GET_CURRENT, (Socket Sock, APIResults Result) =>
|
||||
{
|
||||
currentPid = Sock.RecvInt32();
|
||||
});
|
||||
|
||||
return result == APIResults.API_OK ? currentPid : -1;
|
||||
}
|
||||
|
||||
public int LoadLibrary(string Path)
|
||||
{
|
||||
int loadResult = 0;
|
||||
var result = API.SendCommand(Target, 3, APICommands.API_DBG_LOAD_LIBRARY, (Socket Sock, APIResults Result) =>
|
||||
{
|
||||
var isDebugging = Sock.RecvInt32();
|
||||
if(isDebugging == 1)
|
||||
{
|
||||
var Packet = new DbgSPRXPacket();
|
||||
Packet.Path = Path;
|
||||
Sock.Send(Helper.StructToBytes(Packet));
|
||||
|
||||
loadResult = Sock.RecvInt32();
|
||||
}
|
||||
});
|
||||
|
||||
return result == APIResults.API_OK ? loadResult : -1;
|
||||
}
|
||||
|
||||
public bool UnloadLibrary(int Handle)
|
||||
{
|
||||
if (!IsDebugging)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int loadResult = 0;
|
||||
var result = API.SendCommand(Target, 3, APICommands.API_DBG_UNLOAD_LIBRARY, (Socket Sock, APIResults Result) =>
|
||||
{
|
||||
var isDebugging = Sock.RecvInt32();
|
||||
if (isDebugging == 1)
|
||||
{
|
||||
var Packet = new DbgSPRXPacket();
|
||||
Packet.Handle = Handle;
|
||||
Sock.Send(Helper.StructToBytes(Packet));
|
||||
|
||||
loadResult = Sock.RecvInt32();
|
||||
}
|
||||
});
|
||||
|
||||
return result == APIResults.API_OK ? (loadResult == 0) : false;
|
||||
}
|
||||
|
||||
public int ReloadLibrary(int Handle, string Path)
|
||||
{
|
||||
if (!IsDebugging)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int loadResult = 0;
|
||||
var result = API.SendCommand(Target, 3, APICommands.API_DBG_RELOAD_LIBRARY, (Socket Sock, APIResults Result) =>
|
||||
{
|
||||
var isDebugging = Sock.RecvInt32();
|
||||
if (isDebugging == 1)
|
||||
{
|
||||
var Packet = new DbgSPRXPacket();
|
||||
Packet.Handle = Handle;
|
||||
Packet.Path = Path;
|
||||
Sock.Send(Helper.StructToBytes(Packet));
|
||||
|
||||
loadResult = Sock.RecvInt32();
|
||||
}
|
||||
});
|
||||
|
||||
return result == APIResults.API_OK ? loadResult : -1;
|
||||
}
|
||||
|
||||
public List<LibraryInfo> GetLibraries()
|
||||
{
|
||||
var libraryList = new List<LibraryInfo>();
|
||||
|
||||
if (!IsDebugging)
|
||||
{
|
||||
return libraryList;
|
||||
}
|
||||
|
||||
var result = API.SendCommand(Target, 6, APICommands.API_DBG_LIBRARY_LIST, (Socket Sock, APIResults Result) =>
|
||||
{
|
||||
var isDebugging = Sock.RecvInt32();
|
||||
if (isDebugging == 1)
|
||||
{
|
||||
var libraryCount = Sock.RecvInt32();
|
||||
|
||||
// Recieve all of the arrary as one large packet.
|
||||
var dataSize = libraryCount * Marshal.SizeOf(typeof(LibraryPacket));
|
||||
var data = new byte[dataSize];
|
||||
Sock.RecvLarge(data);
|
||||
|
||||
// Allocate and copy the packet to begin marshaling it.
|
||||
IntPtr ptr = Marshal.AllocHGlobal(dataSize);
|
||||
Marshal.Copy(data, 0, ptr, dataSize);
|
||||
|
||||
for (int i = 0; i < libraryCount; i++)
|
||||
{
|
||||
// Marshal each part of the buffer to a struct.
|
||||
var Packet = new LibraryPacket();
|
||||
Packet = (LibraryPacket)Marshal.PtrToStructure(IntPtr.Add(ptr, i * Marshal.SizeOf(typeof(LibraryPacket))), typeof(LibraryPacket));
|
||||
|
||||
if (Packet.SegmentCount > 4 || Packet.SegmentCount < 0)
|
||||
Packet.SegmentCount = 4;
|
||||
|
||||
var segments = new SegmentInfo[Packet.SegmentCount];
|
||||
for (int j = 0; j < Packet.SegmentCount; j++)
|
||||
{
|
||||
segments[j] = new SegmentInfo(Packet.Segments[j].baseAddr, Packet.Segments[j].size, Packet.Segments[j].prot);
|
||||
}
|
||||
|
||||
libraryList.Add(new LibraryInfo(Packet.Handle, Packet.Path, segments));
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
});
|
||||
|
||||
return libraryList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ namespace OrbisLib2.Targets
|
||||
}
|
||||
|
||||
public TargetEvents Events;
|
||||
// public Debug Debug;
|
||||
public Debug Debug;
|
||||
public Payload Payload;
|
||||
public Process Process;
|
||||
public FTP FTP;
|
||||
@@ -92,7 +92,7 @@ namespace OrbisLib2.Targets
|
||||
_SavedTargetId = SavedTarget.Id;
|
||||
|
||||
Events = new TargetEvents(this);
|
||||
// Debug = new Debug(this);
|
||||
Debug = new Debug(this);
|
||||
Payload = new Payload(this);
|
||||
Process = new Process(this);
|
||||
FTP = new FTP(this);
|
||||
|
||||
@@ -6,12 +6,18 @@
|
||||
xmlns:local="clr-namespace:OrbisLibraryManager"
|
||||
xmlns:simpleControls="clr-namespace:SimpleUI.Controls;assembly=SimpleUI"
|
||||
xmlns:controls="clr-namespace:OrbisLibraryManager.Controls"
|
||||
xmlns:valueConverters="clr-namespace:OrbisLibraryManager.ValueConverters"
|
||||
mc:Ignorable="d"
|
||||
Title="LibraryManager" Height="640" Width="980"
|
||||
MinHeight="640" MinWidth="980"
|
||||
MaxHeight="640" MaxWidth="980"
|
||||
ResizeMode="CanMinimize">
|
||||
|
||||
<simpleControls:SimpleWindow.Resources>
|
||||
<valueConverters:PathNameConverter x:Key="PathNameConverter"/>
|
||||
<valueConverters:SegmentConverter x:Key="SegmentConverter"/>
|
||||
</simpleControls:SimpleWindow.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3*"/>
|
||||
@@ -118,7 +124,8 @@
|
||||
Height="25"
|
||||
ToolTip="Detach the current attached process"
|
||||
ImageSource="/OrbisLibraryManager;component/Images/Detached.png"
|
||||
ImageMargin="2"/>
|
||||
ImageMargin="2"
|
||||
Click="DetachProcess_Click"/>
|
||||
|
||||
<controls:ImageButton x:Name="Send"
|
||||
Grid.Column="4"
|
||||
@@ -172,15 +179,15 @@
|
||||
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="Handle" Width="60" DisplayMemberBinding="{Binding [0]}"/>
|
||||
<GridViewColumn Header="Name" Width="180" DisplayMemberBinding="{Binding [1]}"/>
|
||||
<GridViewColumn Header="Segments" Width="Auto" DisplayMemberBinding="{Binding [2]}"/>
|
||||
<GridViewColumn Header="Handle" Width="60" DisplayMemberBinding="{Binding Path=Handle}"/>
|
||||
<GridViewColumn Header="Name" Width="180" DisplayMemberBinding="{Binding Path=Path, Converter={StaticResource PathNameConverter}}"/>
|
||||
<GridViewColumn Header="Segments" Width="Auto" DisplayMemberBinding="{Binding Path=Segments, Converter={StaticResource SegmentConverter}}"/>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
|
||||
<ListView.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Refresh" />
|
||||
<MenuItem Header="Refresh" Click="Refresh_Click"/>
|
||||
</ContextMenu>
|
||||
</ListView.ContextMenu>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using OrbisLib2.Common.Dispatcher;
|
||||
using OrbisLib2.Targets;
|
||||
using SimpleUI.Controls;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace OrbisLibraryManager
|
||||
@@ -16,9 +17,43 @@ namespace OrbisLibraryManager
|
||||
DispatcherClient.Subscribe();
|
||||
}
|
||||
|
||||
private void RefreshLibraryList()
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
var libraryList = TargetManager.SelectedTarget.Debug.GetLibraries();
|
||||
|
||||
if (libraryList != null && libraryList.Count > 0)
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
LibraryList.ItemsSource = libraryList;
|
||||
LibraryList.Items.Refresh();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
LibraryList.ItemsSource = null;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void AttachProcess_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OrbisLib2.Dialog.SelectProcess.ShowDialog(GetWindow(this));
|
||||
}
|
||||
|
||||
private void DetachProcess_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
TargetManager.SelectedTarget.Debug.Detach();
|
||||
}
|
||||
|
||||
private void Refresh_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
RefreshLibraryList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace OrbisLibraryManager.ValueConverters
|
||||
{
|
||||
public class PathNameConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (string.IsNullOrEmpty((string)value))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return Path.GetFileName((string)value);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return (string)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using OrbisLib2.Targets;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace OrbisLibraryManager.ValueConverters
|
||||
{
|
||||
public class SegmentConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var outputStr = string.Empty;
|
||||
var segments = value as SegmentInfo[];
|
||||
if(segments != null)
|
||||
{
|
||||
foreach (var segment in segments)
|
||||
{
|
||||
if(segment.Address > 0 && segment.Size > 0)
|
||||
{
|
||||
outputStr += $"0x{segment.Address.ToString("X")}({segment.Size}) ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return string.IsNullOrEmpty(outputStr) ? "-" : outputStr;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return new SegmentInfo[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
2227
|
||||
2313
|
||||
|
||||
@@ -1 +1 @@
|
||||
Version 3.0.2227 Debug Build Sunday January 01 2023 9:57 PM
|
||||
Version 3.0.2313 Debug Build Wednesday January 04 2023 8:32 PM
|
||||
|
||||
Reference in New Issue
Block a user