By default, retail consoles don't have a debug option, neither do they have a debug kernel which would allow us to keep track of errors. So team XeLove coded a network based debug assister for XDK programmers. Logging over LAN, Stop/Start XEX, and builtin FTP server.
Basics[]
XeDebug is made up three parts.
1: The Launcher
2: C++ Includes
3: The XeDebug Server
At anytime more information can be found at xboxhacker
[]
Install[]
[]
Simply edit ftpd.conf for your host's IP. Copy the folder XeDebug to the root of HDD1. And run either from XexMenu or build a GoD con.
NOTE** Copy xarialuni.ttf to XeDebug/media/
Debug XEX's are launched as HDD1:/XeDebug/Debug/ and can be FTP'ed username: xbox password: xbox
Sourcecode[]
XeDebug.cpp[]
#include <xtl.h> #include <fstream> #include <string> #include <vector> using namespace std; #define DEVICE_NAND_FLASH 0 #define DEVICE_MEMORY_UNIT0 1 #define DEVICE_MEMORY_UNIT1 2 #define DEVICE_CDROM0 3 #define DEVICE_HARDISK0_PART0 4 #define DEVICE_HARDISK0_PART1 5 #define DEVICE_HARDISK0_PART2 6 #define DEVICE_HARDISK0_PART3 7 #define DEVICE_USB0 8 #define DEVICE_USB1 9 #define DEVICE_USB2 10 DWORD dwLaunchDataSize = 0; DWORD dwStatus; bool IsDebugging = false; SOCKET _sClientSocket; struct CustomLaunchData { DWORD dwID; char chVersion[6]; char chHost[24]; int intPort; char DebuggerPath[100]; }; CustomLaunchData* pCustomData = NULL; typedef struct _STRING { USHORT Length; USHORT MaximumLength; PCHAR Buffer; } STRING; extern "C" int __stdcall ObCreateSymbolicLink( STRING*, STRING*); extern "C" int __stdcall ObDeleteSymbolicLink( STRING* ); DWORD WINAPI ThreadDebug(LPVOID lpParam); void debugLog(char* output); HRESULT Monter( int periphPhys, char* lettreLecteur ) { char lecteurCible[16]; sprintf_s( lecteurCible,"\\??\\%s", lettreLecteur ); char * periphOriginal; switch(periphPhys) { case DEVICE_NAND_FLASH: periphOriginal = "\\Device\\Flash"; break; case DEVICE_MEMORY_UNIT0: periphOriginal = "\\Device\\Mu0"; break; case DEVICE_MEMORY_UNIT1: periphOriginal = "\\Device\\Mu1"; break; case DEVICE_CDROM0: periphOriginal = "\\Device\\Cdrom0"; break; case DEVICE_HARDISK0_PART0: periphOriginal = "\\Device\\Harddisk0\\Partition0"; break; case DEVICE_HARDISK0_PART1: periphOriginal = "\\Device\\Harddisk0\\Partition1"; break; case DEVICE_HARDISK0_PART2: periphOriginal = "\\Device\\Harddisk0\\Partition2"; break; case DEVICE_HARDISK0_PART3: periphOriginal = "\\Device\\Harddisk0\\Partition3"; break; case DEVICE_USB0: periphOriginal = "\\Device\\Mass0"; break; case DEVICE_USB1: periphOriginal = "\\Device\\Mass1"; break; case DEVICE_USB2: periphOriginal = "\\Device\\Mass2"; break; } STRING PeriphOriginal = { (USHORT)strlen( periphOriginal ), (USHORT)strlen( periphOriginal ) + 1, periphOriginal }; STRING LienSymbolique = { (USHORT)strlen( lecteurCible ), (USHORT)strlen( lecteurCible ) + 1, lecteurCible }; return ( HRESULT ) ObCreateSymbolicLink( &LienSymbolique, &PeriphOriginal ); } bool StartDebugger() { dwLaunchDataSize = 0; dwStatus = XGetLaunchDataSize( &dwLaunchDataSize ); if( dwStatus == ERROR_SUCCESS ) { BYTE* pLaunchData = new BYTE [ dwLaunchDataSize ]; dwStatus = XGetLaunchData( pLaunchData, dwLaunchDataSize ); pCustomData = ( CustomLaunchData* )( pLaunchData ); // === Connect to XeDebug Server ================================ BOOL bBroadcast = TRUE; WSADATA _WSAData; DWORD dwStatus = XNetGetEthernetLinkStatus(); int m_bIsActive = (dwStatus & XNET_ETHERNET_LINK_ACTIVE) != 0; if(!m_bIsActive) { debugLog("No Ethernet Link Active"); return false; } debugLog("Ethernet Link Active"); XNetStartupParams _XNetStartupParams; memset(&_XNetStartupParams, 0, sizeof(_XNetStartupParams)); _XNetStartupParams.cfgSizeOfStruct = sizeof(XNetStartupParams); _XNetStartupParams.cfgSockDefaultRecvBufsizeInK = 128; _XNetStartupParams.cfgSockDefaultSendBufsizeInK = 128; _XNetStartupParams.cfgFlags = XNET_STARTUP_BYPASS_SECURITY; int iResult = XNetStartup( &_XNetStartupParams ); if (iResult != NO_ERROR) { debugLog("XNetStartup Failed"); return false; } iResult = WSAStartup( MAKEWORD(2,2), &_WSAData ); if (iResult != NO_ERROR) { debugLog("WSAStartup Failed"); return false; } sockaddr_in _sDestinationAddr; memset(&_sDestinationAddr, 0, sizeof(_sDestinationAddr)); _sDestinationAddr.sin_family = AF_INET; _sDestinationAddr.sin_addr.S_un.S_addr = inet_addr(pCustomData->chHost); _sDestinationAddr.sin_port = htons(pCustomData->intPort); _sClientSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (_sClientSocket == INVALID_SOCKET) { debugLog("Error While Creating The Socket"); return false; } if( setsockopt(_sClientSocket, SOL_SOCKET, 0x5802, (PCSTR)&bBroadcast, sizeof(BOOL)) != 0 ) { debugLog("Failed to set socket to 5802, error"); return false; } if( setsockopt(_sClientSocket, SOL_SOCKET, 0x5801, (PCSTR)&bBroadcast, sizeof(BOOL)) != 0 ) { debugLog("Failed to set socket to 5801, error"); return false; } if (connect(_sClientSocket, (struct sockaddr *) &_sDestinationAddr, sizeof(_sDestinationAddr)) < 0) { debugLog("Connection to XeDebug Server failed"); return false; } send(_sClientSocket, "XEDBG|APP", sizeof("XEDBG|APP"), 0); Sleep(200); DWORD dwThreadId; CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadDebug, 0, 0, &dwThreadId); IsDebugging = true; return true; } return false; } void EndDebugger() { if(!IsDebugging) return; if(pCustomData == NULL) return; send(_sClientSocket, "XEDISCODBG", (int)strlen("XEDISCODBG"), 0); Monter(DEVICE_HARDISK0_PART1, "hdd1:"); XLaunchNewImage(pCustomData->DebuggerPath, NULL); } DWORD WINAPI ThreadDebug(LPVOID lpParam) { XSetThreadProcessor(GetCurrentThread(), 2); char recvbuf[1024] = {0}; int iResult; do { memset(recvbuf, 0, sizeof(recvbuf)); iResult = recv(_sClientSocket, recvbuf, sizeof(recvbuf), 0); if(strcmp(recvbuf, "/START") == 0) { send(_sClientSocket, "XEDISCODBG", sizeof("XEDISCODBG"), 0); Monter(DEVICE_HARDISK0_PART1, "hdd1:"); XLaunchNewImage(pCustomData->DebuggerPath, 0); } else if(strcmp(recvbuf, "/RESTART") == 0) { send(_sClientSocket, "XEDISCOAPP", sizeof("XEDISCOAPP"), 0); Monter(DEVICE_HARDISK0_PART1, "hdd1:"); XSetLaunchData(pCustomData, sizeof(pCustomData)); XLaunchNewImage("hdd1:\\XeDebug\\debug\\default.xex", 0); } else { } } while (iResult > 0); IsDebugging = false; return 0; } void debugLog(char* output) { ofstream writeLog; if(IsDebugging) { char sendbuf[256]; sprintf_s(sendbuf,sizeof(sendbuf),"LOG|%s", output); send(_sClientSocket, sendbuf, (int)strlen(sendbuf), 0); } else { // Credits to dstruktiv writeLog.open("game:\\debug.log",ofstream::app); if (writeLog.is_open()) { writeLog.write(output,strlen(output)); writeLog.write("\n",1); } writeLog.close(); } }
xedebug.h[]
bool StartDebugger(); void EndDebugger();
Using your debug function[]
Whenever you want an event to get logged, just call your function:
#include <xtl.h> #include "AtgConsole.h" #include "AtgUtil.h" #include "AtgInput.h" ATG::Console console; #include "XeDebug.h" VOID __cdecl main() { console.Create( "game:\\Media\\Fonts\\Arial_12.xpr", 0x2F0230FF, 0xFFFFFFFF ); if(StartDebugger()) console.Format("XeDebug Started\n"); else console.Format("XeDebug Failed to Start\n"); debugLog("Hello World"); DWORD startTime = GetTickCount(); while(GetTickCount() < startTime + 20000) { // Wait 20 seconds then return to XeDebug } EndDebugger(); }
- thanks to Team XeLove