├── .gitignore ├── Makefile ├── README.md ├── XKCRC.cpp ├── XKCRC.h ├── XKEEPROM.cpp ├── XKEEPROM.h ├── XKGeneral.cpp ├── XKGeneral.h ├── XKRC4.cpp ├── XKRC4.h ├── XKSHA1.cpp ├── XKSHA1.h ├── fixme.h └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | xbeeprom 3 | *.bin 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET=xbeeprom 2 | OBJECTS=$(patsubst %.cpp,%.o,$(wildcard *.cpp)) 3 | 4 | xbeeprom: $(OBJECTS) 5 | g++ -o $@ $^ 6 | 7 | %.o: %.cpp 8 | g++ -o $@ -c $< 9 | 10 | .PHONY: clean 11 | clean: 12 | rm -f $(TARGET) $(OBJECTS) 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | xbox eeprom tool 2 | ================ 3 | 4 | Currently this tool just supports reading/writing the MAC address (what I 5 | needed at the moment), but can be made to be more useful. 6 | 7 | Ideally this would be re-written into a simple Python script or something, but 8 | this code was easy enough to get working as-is (with a little Win API glue). 9 | 10 | License GPL2 11 | -------------------------------------------------------------------------------- /XKCRC.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Mike Davis 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #include "XKCRC.h" 12 | 13 | XKCRC::XKCRC(void) 14 | { 15 | } 16 | 17 | XKCRC::~XKCRC(void) 18 | { 19 | } 20 | 21 | void XKCRC::QuickCRC(UCHAR* CRCVAL, UCHAR* inData, DWORD dataLen) 22 | { 23 | uint32_t high = 0, low = 0; 24 | 25 | for (uint32_t i = 0; i < dataLen / sizeof(uint32_t); i++) 26 | { 27 | uint32_t val = ((uint32_t*)inData)[i]; 28 | uint64_t sum = ((uint64_t)high << 32) | low; 29 | 30 | high = (uint32_t)((sum + val) >> 32); 31 | low += val; 32 | } 33 | 34 | *(uint32_t*)CRCVAL = ~(high + low); 35 | } -------------------------------------------------------------------------------- /XKCRC.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************** 3 | ********************************** 4 | ** BROUGHT TO YOU BY: ** 5 | ********************************** 6 | ********************************** 7 | ** ** 8 | ** [TEAM ASSEMBLY] ** 9 | ** ** 10 | ** www.team-assembly.com ** 11 | ** ** 12 | ****************************************************************************************************** 13 | * This is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 | ****************************************************************************************************** 27 | 28 | ******************************************************************************************************** 29 | ** XKCRC.H - General CRC Class' Header 30 | ******************************************************************************************************** 31 | ** 32 | ** This is the Class Header, see the .CPP file for more comments and implementation details. 33 | ** 34 | ******************************************************************************************************** 35 | 36 | UPDATE LOG: 37 | -------------------------------------------------------------------------------------------------------- 38 | Date: 02/18/2003 39 | By: UNDEAD [team-assembly] 40 | Reason: Prepared 0.2 for Public Release 41 | -------------------------------------------------------------------------------------------------------- 42 | Date: 01/06/2003 43 | By: UNDEAD [team-assembly] 44 | Reason: Prepared for Public Release 45 | -------------------------------------------------------------------------------------------------------- 46 | 47 | */ 48 | 49 | #pragma once 50 | #if defined (_WINDOWS) 51 | #pragma message ("Compiling for WINDOWS: " __FILE__) 52 | #include // MFC core and standard components 53 | #elif defined (_XBOX) 54 | #pragma message ("Compiling for XBOX: " __FILE__) 55 | #include 56 | #else 57 | // #error ERRR: Have to Define _WINDOWS or _XBOX !! 58 | #include "fixme.h" 59 | #endif 60 | 61 | 62 | class XKCRC 63 | { 64 | public: 65 | XKCRC(void); 66 | virtual ~XKCRC(void); 67 | 68 | static void QuickCRC(UCHAR* CRCVAL, UCHAR* inData, DWORD dataLen); 69 | 70 | }; 71 | -------------------------------------------------------------------------------- /XKEEPROM.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************** 3 | ********************************** 4 | ** BROUGHT TO YOU BY: ** 5 | ********************************** 6 | ********************************** 7 | ** ** 8 | ** [TEAM ASSEMBLY] ** 9 | ** ** 10 | ** www.team-assembly.com ** 11 | ** ** 12 | ****************************************************************************************************** 13 | * This is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 | ****************************************************************************************************** 27 | 28 | ******************************************************************************************************** 29 | ** XKEEPROM.CPP - XBOX EEPROM Class' Implementation 30 | ******************************************************************************************************** 31 | ** 32 | ** This Class encapsulates the XBOX EEPROM strucure and many helper functions to parse, 33 | ** Calculate CRC's and Decrypt various values in the XBOX EEPROM.. 34 | ** 35 | ******************************************************************************************************** 36 | 37 | ******************************************************************************************************** 38 | ** CREDITS: 39 | ******************************************************************************************************** 40 | ** XBOX-LINUX TEAM: 41 | ** --------------- 42 | ** Wow, you guys are awsome !! I bow down to your greatness !! the "Friday 13th" Middle 43 | ** Message Hack really saved our butts !! 44 | ** REFERENCE URL: http://xbox-linux.sourceforge.net 45 | ** 46 | ******************************************************************************************************** 47 | 48 | UPDATE LOG: 49 | -------------------------------------------------------------------------------------------------------- 50 | Date: 11/27/2004 51 | By: Yoshihiro 52 | Reason: Update for xbox 1.6 53 | -------------------------------------------------------------------------------------------------------- 54 | Date: 02/18/2003 55 | By: UNDEAD [team-assembly] 56 | Reason: Prepared 0.2 for Public Release 57 | -------------------------------------------------------------------------------------------------------- 58 | Date: 01/25/2003 59 | By: UNDEAD [team-assembly] 60 | Reason: Added XBOX Specific code to read EEPROM Data from Hardware 61 | -------------------------------------------------------------------------------------------------------- 62 | Date: 01/06/2003 63 | By: UNDEAD [team-assembly] 64 | Reason: Prepared for Public Release 65 | -------------------------------------------------------------------------------------------------------- 66 | 67 | */ 68 | 69 | #include "XKEEPROM.h" 70 | 71 | 72 | 73 | /* Default Constructor using a Blank eeprom image... */ 74 | XKEEPROM::XKEEPROM() 75 | { 76 | m_XBOX_Version = V1_0; 77 | ZeroMemory(&m_EEPROMData, sizeof(EEPROMDATA)); 78 | m_EncryptedState = FALSE; 79 | 80 | } 81 | 82 | /* Constructor to specify a eeprom image to use ... */ 83 | XKEEPROM::XKEEPROM(LPEEPROMDATA pEEPROMData, BOOL Encrypted) 84 | { 85 | m_XBOX_Version = V_NONE; 86 | memcpy(&m_EEPROMData, (LPBYTE)pEEPROMData, sizeof(EEPROMDATA)); 87 | m_EncryptedState = Encrypted; 88 | } 89 | 90 | /* Default Destructor */ 91 | XKEEPROM::~XKEEPROM(void) 92 | { 93 | } 94 | 95 | /* Read a EEPROM image from a .BIN file.. */ 96 | /* could be a decrypted or Enrytped.. make sure you specify correct value */ 97 | BOOL XKEEPROM::ReadFromBINFile(LPCSTR FileName, BOOL IsEncrypted) 98 | { 99 | //First Make sure the File exists... 100 | WIN32_FIND_DATA wfd; 101 | HANDLE hf = FindFirstFile(FileName, &wfd); 102 | if (hf == INVALID_HANDLE_VALUE) 103 | return FALSE; 104 | 105 | //Now Read the EEPROM Data from File.. 106 | BYTE Data[EEPROM_SIZE]; 107 | DWORD dwBytesRead = 0; 108 | ZeroMemory(Data, EEPROM_SIZE); 109 | 110 | hf = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 111 | BOOL retVal = ReadFile(hf, Data, EEPROM_SIZE, &dwBytesRead, NULL); 112 | if (retVal && (dwBytesRead >= EEPROM_SIZE)) 113 | { 114 | memcpy(&m_EEPROMData, Data, EEPROM_SIZE); 115 | m_EncryptedState = IsEncrypted; 116 | } 117 | else 118 | retVal = FALSE; 119 | 120 | CloseHandle(hf); 121 | 122 | return retVal; 123 | } 124 | 125 | /* Write the Current EEPROM image to a .BIN file.. */ 126 | BOOL XKEEPROM::WriteToBINFile(LPCSTR FileName) 127 | { 128 | BOOL retVal = FALSE; 129 | DWORD dwBytesWrote = 0; 130 | 131 | //Only write bin file if encrypted.. 132 | if (m_EncryptedState) 133 | { 134 | HANDLE hf = CreateFile(FileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 135 | if (hf != INVALID_HANDLE_VALUE) 136 | { 137 | //Write EEPROM File 138 | retVal = WriteFile(hf , &m_EEPROMData, EEPROM_SIZE, &dwBytesWrote, NULL); 139 | } 140 | CloseHandle(hf); 141 | } 142 | return retVal; 143 | } 144 | 145 | /* Read from a .CFG File ans set Current EEPROM Data */ 146 | /* Encrypt as V1.0 by default */ 147 | BOOL XKEEPROM::ReadFromCFGFile(LPCSTR FileName) 148 | { 149 | //First Make sure the File exists... 150 | BOOL retVal = FALSE; 151 | WIN32_FIND_DATA wfd; 152 | HANDLE hf = FindFirstFile(FileName, &wfd); 153 | if (hf == INVALID_HANDLE_VALUE) 154 | return FALSE; 155 | 156 | //Now Clear the EEPROM Data and read from File.. 157 | BYTE tmpData[EEPROM_SIZE]; 158 | DWORD tmpLen = EEPROM_SIZE; 159 | 160 | if (hf != INVALID_HANDLE_VALUE) 161 | { 162 | //Get Confounder 163 | tmpLen = EEPROM_SIZE; 164 | ZeroMemory(tmpData, tmpLen); 165 | ZeroMemory(&m_EEPROMData, EEPROM_SIZE); 166 | m_EncryptedState = FALSE; 167 | 168 | if (XKGeneral::ReadINIFileItem(FileName, "EEPROMDATA", "Confounder",(LPSTR) &tmpData, &tmpLen)) 169 | { 170 | XKGeneral::StripQuotes((LPSTR)tmpData, &tmpLen); 171 | XKGeneral::HexStrToBytes(tmpData, (LPDWORD)&tmpLen, TRUE); 172 | 173 | memcpy(m_EEPROMData.Confounder, tmpData, 8); 174 | } 175 | 176 | //Get HDDKey 177 | tmpLen = EEPROM_SIZE; 178 | ZeroMemory(tmpData, tmpLen); 179 | if (XKGeneral::ReadINIFileItem(FileName, "EEPROMDATA", "HDDKey",(LPSTR) &tmpData, &tmpLen)) 180 | { 181 | XKGeneral::StripQuotes((LPSTR)tmpData, &tmpLen); 182 | XKGeneral::HexStrToBytes(tmpData, (LPDWORD)&tmpLen, TRUE); 183 | 184 | memcpy(m_EEPROMData.HDDKkey, tmpData, 16); 185 | } 186 | 187 | //Get XBERegion 188 | tmpLen = EEPROM_SIZE; 189 | ZeroMemory(tmpData, tmpLen); 190 | if (XKGeneral::ReadINIFileItem(FileName, "EEPROMDATA", "XBERegion",(LPSTR) &tmpData, &tmpLen)) 191 | { 192 | XKGeneral::StripQuotes((LPSTR)tmpData, &tmpLen); 193 | XKGeneral::HexStrToBytes(tmpData, (LPDWORD)&tmpLen, TRUE); 194 | 195 | memcpy(m_EEPROMData.XBERegion, tmpData, 1); 196 | } 197 | 198 | 199 | //Get Online Key 200 | tmpLen = EEPROM_SIZE; 201 | ZeroMemory(tmpData, tmpLen); 202 | if (XKGeneral::ReadINIFileItem(FileName, "EEPROMDATA", "OnlineKey",(LPSTR) &tmpData, &tmpLen)) 203 | { 204 | XKGeneral::StripQuotes((LPSTR)tmpData, &tmpLen); 205 | XKGeneral::HexStrToBytes(tmpData, (LPDWORD)&tmpLen, TRUE); 206 | 207 | memcpy(m_EEPROMData.OnlineKey, tmpData, 16); 208 | } 209 | 210 | 211 | //Get SerialNumber 212 | tmpLen = EEPROM_SIZE; 213 | ZeroMemory(tmpData, tmpLen); 214 | if (XKGeneral::ReadINIFileItem(FileName, "EEPROMDATA", "XBOXSerial",(LPSTR) &tmpData, &tmpLen)) 215 | { 216 | XKGeneral::StripQuotes((LPSTR)tmpData, &tmpLen); 217 | tmpLen=12; 218 | XKGeneral::MixedStrToDecStr((LPSTR)tmpData, (LPDWORD)&tmpLen, 10, FALSE); 219 | memcpy(m_EEPROMData.SerialNumber, tmpData, 12); 220 | } 221 | 222 | //Get MAC Address 223 | tmpLen = EEPROM_SIZE; 224 | ZeroMemory(tmpData, tmpLen); 225 | if (XKGeneral::ReadINIFileItem(FileName, "EEPROMDATA", "XBOXMAC",(LPSTR) &tmpData, &tmpLen)) 226 | { 227 | XKGeneral::StripQuotes((LPSTR)tmpData, &tmpLen); 228 | XKGeneral::HexStrToBytes(tmpData, (LPDWORD)&tmpLen, TRUE); 229 | 230 | memcpy(m_EEPROMData.MACAddress, tmpData, 6); 231 | } 232 | 233 | 234 | //Get Video Mode 235 | tmpLen = EEPROM_SIZE; 236 | ZeroMemory(tmpData, tmpLen); 237 | if (XKGeneral::ReadINIFileItem(FileName, "EEPROMDATA", "VideoMode",(LPSTR) &tmpData, &tmpLen)) 238 | { 239 | XKGeneral::StripQuotes((LPSTR)tmpData, &tmpLen); 240 | UINT* tmpVM = (UINT*) &m_EEPROMData.VideoStandard; 241 | 242 | if (strcmp((LPCSTR)tmpData, "NTSC") == 0) 243 | *tmpVM = NTSC_M; 244 | else if (strcmp((LPCSTR)tmpData, "PAL") == 0) 245 | *tmpVM = PAL_I; 246 | else 247 | *tmpVM = NTSC_M; 248 | } 249 | 250 | if (m_XBOX_Version == V_NONE) 251 | EncryptAndCalculateCRC(V1_0); //Use default V1.0 252 | else 253 | EncryptAndCalculateCRC(); 254 | 255 | retVal = TRUE; 256 | } 257 | 258 | return retVal; 259 | } 260 | 261 | /* Write the Current EEPROM Data to a .CFG File */ 262 | /* If it is encrypted you have to decrypt it first ! */ 263 | BOOL XKEEPROM::WriteToCFGFile(LPCSTR FileName) 264 | { 265 | BOOL retVal = FALSE; 266 | DWORD dwBytesWrote = 0; 267 | CHAR tmpData[256]; 268 | ZeroMemory(tmpData, 256); 269 | DWORD tmpSize = 256; 270 | 271 | //Check if this is currently an encrypted image.. if it is, then decrypt it first.. 272 | BOOL oldEncryptedState = m_EncryptedState; 273 | if (m_EncryptedState) 274 | Decrypt(); 275 | 276 | HANDLE hf = CreateFile(FileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 277 | if (hf != INVALID_HANDLE_VALUE) 278 | { 279 | //Write CFG File Header.. 280 | const char *fHeaderInfo = "#Please note ALL fields and Values are Case Sensitive !!\r\n\r\n[EEPROMDATA]\r\n"; 281 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 282 | 283 | //Write Serial Number 284 | fHeaderInfo = "XBOXSerial\t= \""; 285 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 286 | WriteFile(hf, m_EEPROMData.SerialNumber, SERIALNUMBER_SIZE, &dwBytesWrote, NULL); 287 | fHeaderInfo = "\"\r\n"; 288 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 289 | 290 | 291 | //Write MAC Address.. 292 | fHeaderInfo = "XBOXMAC\t\t= \""; 293 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 294 | ZeroMemory(tmpData, tmpSize); 295 | XKGeneral::BytesToHexStr(m_EEPROMData.MACAddress, MACADDRESS_SIZE, tmpData, ':'); 296 | strupr(tmpData); 297 | WriteFile(hf, tmpData, (DWORD)strlen(tmpData), &dwBytesWrote, NULL); 298 | fHeaderInfo = "\"\r\n"; 299 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 300 | 301 | 302 | //Write Online Key .. 303 | fHeaderInfo = "\r\nOnlineKey\t= \""; 304 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 305 | ZeroMemory(tmpData, tmpSize); 306 | XKGeneral::BytesToHexStr(m_EEPROMData.OnlineKey, ONLINEKEY_SIZE, tmpData, ':'); 307 | strupr(tmpData); 308 | WriteFile(hf, tmpData, (DWORD)strlen(tmpData), &dwBytesWrote, NULL); 309 | fHeaderInfo = "\"\r\n"; 310 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 311 | 312 | 313 | //Write VideoMode .. 314 | fHeaderInfo = "\r\n#ONLY Use NTSC or PAL for VideoMode\r\n"; 315 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 316 | fHeaderInfo = "VideoMode\t= \""; 317 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 318 | VIDEO_STANDARD vdo = GetVideoStandardVal(); 319 | if (vdo == PAL_I) 320 | fHeaderInfo = "PAL"; 321 | else 322 | fHeaderInfo = "NTSC"; 323 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 324 | fHeaderInfo = "\"\r\n"; 325 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 326 | 327 | //Write XBE Region.. 328 | fHeaderInfo = "\r\n#ONLY Use 01, 02 or 04 for XBE Region\r\n"; 329 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 330 | fHeaderInfo = "XBERegion\t= \""; 331 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 332 | ZeroMemory(tmpData, tmpSize); 333 | XKGeneral::BytesToHexStr(m_EEPROMData.XBERegion, XBEREGION_SIZE, tmpData, 0x00); 334 | strupr(tmpData); 335 | WriteFile(hf, tmpData, (DWORD)strlen(tmpData), &dwBytesWrote, NULL); 336 | fHeaderInfo = "\"\r\n"; 337 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 338 | 339 | //Write HDDKey.. 340 | fHeaderInfo = "\r\nHDDKey\t\t= \""; 341 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 342 | ZeroMemory(tmpData, tmpSize); 343 | XKGeneral::BytesToHexStr(m_EEPROMData.HDDKkey, HDDKEY_SIZE, tmpData, ':'); 344 | strupr(tmpData); 345 | WriteFile(hf, tmpData, (DWORD)strlen(tmpData), &dwBytesWrote, NULL); 346 | fHeaderInfo = "\"\r\n"; 347 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 348 | 349 | //Write Confounder.. 350 | fHeaderInfo = "Confounder\t= \""; 351 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 352 | ZeroMemory(tmpData, tmpSize); 353 | XKGeneral::BytesToHexStr(m_EEPROMData.Confounder, CONFOUNDER_SIZE, tmpData, ':'); 354 | strupr(tmpData); 355 | WriteFile(hf, tmpData, (DWORD)strlen(tmpData), &dwBytesWrote, NULL); 356 | fHeaderInfo = "\"\r\n"; 357 | WriteFile(hf, fHeaderInfo, (DWORD)strlen(fHeaderInfo), &dwBytesWrote, NULL); 358 | 359 | retVal = TRUE; 360 | } 361 | 362 | CloseHandle(hf); 363 | 364 | //Check if this is was an encrypted image.. if it was, then re-encrypt it.. 365 | if (oldEncryptedState) 366 | EncryptAndCalculateCRC(); 367 | 368 | return retVal; 369 | 370 | } 371 | 372 | //very XBOX specific funtions to read/write EEPROM from hardware 373 | #if defined (_XBOX) 374 | void XKEEPROM::ReadFromXBOX() 375 | { 376 | XKUtils::ReadEEPROMFromXBOX((LPBYTE)&m_EEPROMData, 0, 255); 377 | m_EncryptedState = TRUE; 378 | } 379 | 380 | void XKEEPROM::WriteToXBOX() 381 | { 382 | XKUtils::WriteEEPROMToXBOX((LPBYTE)&m_EEPROMData, 0, 255); 383 | } 384 | #endif 385 | 386 | /* Return EEPROM data for this object, Check if it is Encrypted with IsEncrypted() */ 387 | void XKEEPROM::GetEEPROMData(LPEEPROMDATA pEEPROMData) 388 | { 389 | memcpy(pEEPROMData, &m_EEPROMData, EEPROM_SIZE); 390 | } 391 | 392 | /* Set a Decrypted EEPROM image as EEPROM data for this object */ 393 | void XKEEPROM::SetDecryptedEEPROMData(XBOX_VERSION Version, LPEEPROMDATA pEEPROMData) 394 | { 395 | memcpy(&m_EEPROMData, pEEPROMData, EEPROM_SIZE); 396 | m_EncryptedState = FALSE; 397 | m_XBOX_Version = Version; 398 | } 399 | 400 | /* Set a encrypted EEPROM image as EEPROM data for this object */ 401 | void XKEEPROM::SetEncryptedEEPROMData(LPEEPROMDATA pEEPROMData) 402 | { 403 | memcpy(&m_EEPROMData, pEEPROMData, EEPROM_SIZE); 404 | m_EncryptedState = TRUE; 405 | } 406 | 407 | /* Get current detected XBOX Version for this EEPROM */ 408 | XBOX_VERSION XKEEPROM::GetXBOXVersion() 409 | { 410 | return m_XBOX_Version; 411 | } 412 | 413 | /* Get confounder in the form of BYTES in a Hex String representation */ 414 | void XKEEPROM::GetConfounderString(LPSTR Confounder, LPDWORD Length) 415 | { 416 | DWORD len = CONFOUNDER_SIZE; 417 | //Check if this is currently an encrypted image.. if it is, then decrypt it first.. 418 | BOOL oldEncryptedState = m_EncryptedState; 419 | if (m_EncryptedState) 420 | Decrypt(); 421 | 422 | XKGeneral::BytesToHexStr((LPBYTE)&m_EEPROMData.Confounder, len, Confounder); 423 | *Length = len; 424 | 425 | //Check if this is was an encrypted image.. if it was, then re-encrypt it.. 426 | if (oldEncryptedState) 427 | EncryptAndCalculateCRC(); 428 | } 429 | 430 | /* Set Confounder in the form of BYTES in a Hex String representation */ 431 | void XKEEPROM::SetConfounderString(LPCSTR Confounder) 432 | { 433 | DWORD len = CONFOUNDER_SIZE * 2; 434 | BYTE tmpData[(CONFOUNDER_SIZE * 2) + 1]; 435 | ZeroMemory(tmpData, len + 1); 436 | memcpy(tmpData, Confounder, min(strlen(Confounder), len)); 437 | 438 | XKGeneral::HexStrToBytes(tmpData, &len, TRUE); 439 | 440 | //Check if this is currently an encrypted image.. if it is, then decrypt it first.. 441 | BOOL oldEncryptedState = m_EncryptedState; 442 | if (m_EncryptedState) 443 | Decrypt(); 444 | 445 | memcpy(&m_EEPROMData.Confounder, tmpData, CONFOUNDER_SIZE); 446 | 447 | //Check if this is was an encrypted image.. if it was, then re-encrypt it.. 448 | if (oldEncryptedState) 449 | EncryptAndCalculateCRC(); 450 | } 451 | 452 | /* Set HDD Key in the form of BYTES in a Hex String representation */ 453 | void XKEEPROM::GetHDDKeyString(LPSTR HDDKey, LPDWORD Length) 454 | { 455 | DWORD len = HDDKEY_SIZE; 456 | 457 | //Check if this is currently an encrypted image.. if it is, then decrypt it first.. 458 | BOOL oldEncryptedState = m_EncryptedState; 459 | if (m_EncryptedState) 460 | Decrypt(); 461 | 462 | XKGeneral::BytesToHexStr((LPBYTE)&m_EEPROMData.HDDKkey, len, HDDKey); 463 | *Length = len; 464 | 465 | //Check if this is was an encrypted image.. if it was, then re-encrypt it.. 466 | if (oldEncryptedState) 467 | EncryptAndCalculateCRC(); 468 | 469 | } 470 | 471 | /* Set HDD Key in the form of BYTES in a Hex String representation */ 472 | void XKEEPROM::SetHDDKeyString(LPCSTR HDDKey) 473 | { 474 | DWORD len = HDDKEY_SIZE * 2; 475 | BYTE tmpData[(HDDKEY_SIZE * 2) + 1]; 476 | ZeroMemory(tmpData, len + 1); 477 | memcpy(tmpData, HDDKey, min(strlen(HDDKey), len)); 478 | 479 | XKGeneral::HexStrToBytes(tmpData, &len, TRUE); 480 | 481 | //Check if this is currently an encrypted image.. if it is, then decrypt it first.. 482 | BOOL oldEncryptedState = m_EncryptedState; 483 | if (m_EncryptedState) 484 | Decrypt(); 485 | 486 | memcpy(&m_EEPROMData.HDDKkey, tmpData, HDDKEY_SIZE); 487 | 488 | //Check if this is was an encrypted image.. if it was, then re-encrypt it.. 489 | if (oldEncryptedState) 490 | EncryptAndCalculateCRC(); 491 | 492 | } 493 | 494 | 495 | /* Get XBE Region in the form of BYTES in a Hex String representation */ 496 | void XKEEPROM::GetXBERegionString(LPSTR XBERegion, LPDWORD Length) 497 | { 498 | DWORD len = XBEREGION_SIZE; 499 | 500 | //Check if this is currently an encrypted image.. if it is, then decrypt it first.. 501 | BOOL oldEncryptedState = m_EncryptedState; 502 | if (m_EncryptedState) 503 | Decrypt(); 504 | 505 | XKGeneral::BytesToHexStr((LPBYTE)&m_EEPROMData.XBERegion, len, XBERegion); 506 | *Length = len; 507 | 508 | //Check if this is was an encrypted image.. if it was, then re-encrypt it.. 509 | if (oldEncryptedState) 510 | EncryptAndCalculateCRC(); 511 | } 512 | 513 | /* Set XBE Region in the form of BYTES in a Hex String representation */ 514 | void XKEEPROM::SetXBERegionString(LPCSTR XBERegion) 515 | { 516 | DWORD len = XBEREGION_SIZE * 2; 517 | BYTE tmpData[(XBEREGION_SIZE * 2) + 1]; 518 | ZeroMemory(tmpData, len + 1); 519 | memcpy(tmpData, XBERegion, min(strlen(XBERegion), len)); 520 | 521 | XKGeneral::HexStrToBytes(tmpData, &len, TRUE); 522 | 523 | //Check if this is currently an encrypted image.. if it is, then decrypt it first.. 524 | BOOL oldEncryptedState = m_EncryptedState; 525 | if (m_EncryptedState) 526 | Decrypt(); 527 | 528 | memcpy(&m_EEPROMData.XBERegion, tmpData, XBEREGION_SIZE); 529 | 530 | //Check if this is was an encrypted image.. if it was, then re-encrypt it.. 531 | if (oldEncryptedState) 532 | EncryptAndCalculateCRC(); 533 | } 534 | 535 | /* Set XBE Region using Enum Value */ 536 | void XKEEPROM::SetXBERegionVal(XBE_REGION RegionVal) 537 | { 538 | //Check if this is currently an encrypted image.. if it is, then decrypt it first.. 539 | BOOL oldEncryptedState = m_EncryptedState; 540 | if (m_EncryptedState) 541 | Decrypt(); 542 | 543 | switch (RegionVal) 544 | { 545 | case(NORTH_AMERICA): 546 | case(JAPAN): 547 | case(EURO_AUSTRALIA): 548 | { 549 | m_EEPROMData.XBERegion[0] = RegionVal; //Only use first byte of Region... 550 | break; 551 | } 552 | default: 553 | m_EEPROMData.XBERegion[0] = NORTH_AMERICA; //If invalid,use Default of US 554 | } 555 | 556 | //Check if this is was an encrypted image.. if it was, then re-encrypt it.. 557 | if (oldEncryptedState) 558 | EncryptAndCalculateCRC(); 559 | } 560 | 561 | /* Get XBE Region as Enum Value */ 562 | XBE_REGION XKEEPROM::GetXBERegionVal() 563 | { 564 | //Check if this is currently an encrypted image.. if it is, then decrypt it first.. 565 | BOOL oldEncryptedState = m_EncryptedState; 566 | if (m_EncryptedState) 567 | Decrypt(); 568 | 569 | XBE_REGION retVal = XBE_REGION (m_EEPROMData.XBERegion[0]); 570 | 571 | //Check if this is was an encrypted image.. if it was, then re-encrypt it.. 572 | if (oldEncryptedState) 573 | EncryptAndCalculateCRC(); 574 | 575 | return retVal; 576 | } 577 | 578 | /* Get Serial Number in the form of Decimal String representation */ 579 | void XKEEPROM::GetSerialNumberString(LPSTR SerialNumber, LPDWORD Length) 580 | { 581 | DWORD len = SERIALNUMBER_SIZE; 582 | 583 | strncpy(SerialNumber, (LPSTR)&m_EEPROMData.SerialNumber, len); 584 | 585 | *Length = len; 586 | } 587 | 588 | /* Set Serial Number in the form of Decimal String representation */ 589 | void XKEEPROM::SetSerialNumberString(LPCSTR SerialNumber) 590 | { 591 | DWORD len = SERIALNUMBER_SIZE; 592 | strncpy((LPSTR)&m_EEPROMData.SerialNumber, SerialNumber, len); 593 | 594 | CalculateChecksum2(); 595 | } 596 | 597 | /* Get MAC Address in the form of BYTES in a Hex String representation */ 598 | void XKEEPROM::GetMACAddressString(LPSTR MACAddress, LPDWORD Length) 599 | { 600 | DWORD len = MACADDRESS_SIZE; 601 | 602 | XKGeneral::BytesToHexStr((LPBYTE)&m_EEPROMData.MACAddress, len, MACAddress, '-'); 603 | *Length = len; 604 | } 605 | 606 | /* Set MAC Address in the form of BYTES in a Hex String representation */ 607 | void XKEEPROM::SetMACAddressString(LPCSTR MACAddress) 608 | { 609 | DWORD len = MACADDRESS_SIZE * 3; 610 | BYTE tmpData[(HDDKEY_SIZE * 3) + 1]; 611 | ZeroMemory(tmpData, len + 1); 612 | memcpy(tmpData, MACAddress, min(strlen(MACAddress), len)); 613 | 614 | XKGeneral::HexStrToBytes(tmpData, &len, TRUE); 615 | 616 | memcpy(&m_EEPROMData.MACAddress, tmpData, MACADDRESS_SIZE); 617 | 618 | CalculateChecksum2(); 619 | 620 | } 621 | 622 | /* Get Online Key in the form of BYTES in a Hex String representation */ 623 | void XKEEPROM::GetOnlineKeyString(LPSTR OnlineKey, LPDWORD Length) 624 | { 625 | DWORD len = ONLINEKEY_SIZE; 626 | 627 | XKGeneral::BytesToHexStr((LPBYTE)&m_EEPROMData.OnlineKey, len, OnlineKey); 628 | *Length = len; 629 | 630 | } 631 | 632 | 633 | /* Set Online Key in the form of BYTES in a Hex String representation */ 634 | void XKEEPROM::SetOnlineKeyString(LPCSTR OnlineKey) 635 | { 636 | DWORD len = ONLINEKEY_SIZE * 2; 637 | BYTE tmpData[(HDDKEY_SIZE * 2) + 1]; 638 | ZeroMemory(tmpData, len + 1); 639 | memcpy(tmpData, OnlineKey, min(strlen(OnlineKey), len)); 640 | 641 | XKGeneral::HexStrToBytes(tmpData, &len, TRUE); 642 | 643 | memcpy(&m_EEPROMData.OnlineKey, tmpData, ONLINEKEY_SIZE); 644 | 645 | CalculateChecksum2(); 646 | } 647 | 648 | /* Get DVD Region in the form of BYTES in a Hex String representation */ 649 | void XKEEPROM::GetDVDRegionString(LPSTR DVDRegion, LPDWORD Length) 650 | { 651 | DWORD len = DVDREGION_SIZE; 652 | 653 | XKGeneral::BytesToHexStr((LPBYTE)&m_EEPROMData.DVDPlaybackKitZone, len, DVDRegion); 654 | *Length = len; 655 | } 656 | 657 | /* Set DVD Region in the form of BYTES in a Hex String representation */ 658 | void XKEEPROM::SetDVDRegionString(LPCSTR DVDRegion) 659 | { 660 | DWORD len = DVDREGION_SIZE * 2; 661 | BYTE tmpData[(DVDREGION_SIZE * 2) + 1]; 662 | ZeroMemory(tmpData, len + 1); 663 | memcpy(tmpData, DVDRegion, min(strlen(DVDRegion), len)); 664 | 665 | XKGeneral::HexStrToBytes(tmpData, &len, TRUE); 666 | 667 | memcpy(&m_EEPROMData.DVDPlaybackKitZone, tmpData, DVDREGION_SIZE); 668 | 669 | CalculateChecksum3(); 670 | 671 | } 672 | 673 | /*Set Video Standard with Enum */ 674 | void XKEEPROM::SetDVDRegionVal(DVD_ZONE ZoneVal) 675 | { 676 | switch (ZoneVal) 677 | { 678 | case (ZONE1): 679 | case (ZONE2): 680 | case (ZONE3): 681 | case (ZONE4): 682 | case (ZONE5): 683 | case (ZONE6): 684 | { 685 | m_EEPROMData.DVDPlaybackKitZone[0] = ZoneVal; //Only use first byte of Region... 686 | break; 687 | } 688 | default: 689 | m_EEPROMData.DVDPlaybackKitZone[0] = ZONE_NONE; //If invalid,use Default of US 690 | } 691 | 692 | CalculateChecksum3(); 693 | } 694 | 695 | 696 | /*Get DVD Region as Enum */ 697 | DVD_ZONE XKEEPROM::GetDVDRegionVal() 698 | { 699 | DVD_ZONE retVal = DVD_ZONE (m_EEPROMData.DVDPlaybackKitZone[0]); 700 | 701 | return retVal; 702 | } 703 | 704 | /* Get Video Standard in the form of BYTES in a Hex String representation */ 705 | void XKEEPROM::GetVideoStandardString(LPSTR VideoStandard, LPDWORD Length) 706 | { 707 | DWORD len = VIDEOSTANDARD_SIZE; 708 | 709 | XKGeneral::BytesToHexStr((LPBYTE)&m_EEPROMData.VideoStandard, len, VideoStandard); 710 | *Length = len; 711 | } 712 | 713 | /* Set Video Standard in the form of BYTES in a Hex String representation */ 714 | void XKEEPROM::SetVideoStandardString(LPCSTR VideoStandard) 715 | { 716 | DWORD len = VIDEOSTANDARD_SIZE * 2; 717 | BYTE tmpData[(VIDEOSTANDARD_SIZE * 2) + 1]; 718 | ZeroMemory(tmpData, len + 1); 719 | memcpy(tmpData, VideoStandard, min(strlen(VideoStandard), len)); 720 | 721 | XKGeneral::HexStrToBytes(tmpData, &len, TRUE); 722 | 723 | memcpy(&m_EEPROMData.VideoStandard, tmpData, VIDEOSTANDARD_SIZE); 724 | 725 | CalculateChecksum2(); 726 | } 727 | 728 | 729 | /* Set Video Standard with Enum */ 730 | void XKEEPROM::SetVideoStandardVal(VIDEO_STANDARD StandardVal) 731 | { 732 | VIDEO_STANDARD* VidStandard = (VIDEO_STANDARD*) ((LPDWORD)&m_EEPROMData.VideoStandard); 733 | 734 | switch (StandardVal) 735 | { 736 | case (NTSC_M): 737 | case (PAL_I): 738 | { 739 | *VidStandard = StandardVal; //Only use first byte of Region... 740 | break; 741 | } 742 | default: 743 | *VidStandard = VID_INVALID; //If invalid,use Default of US 744 | } 745 | 746 | CalculateChecksum2(); 747 | } 748 | 749 | /*Get Video Standard as Enum */ 750 | VIDEO_STANDARD XKEEPROM::GetVideoStandardVal() 751 | { 752 | VIDEO_STANDARD retVal = (VIDEO_STANDARD) *((LPDWORD)&m_EEPROMData.VideoStandard); 753 | 754 | return retVal; 755 | } 756 | 757 | 758 | /* Encrypt the EEPROM Data for Specific XBOX Version by means of the SHA1 Middle Message hack..*/ 759 | BOOL XKEEPROM::EncryptAndCalculateCRC(XBOX_VERSION XBOXVersion) 760 | { 761 | if (!m_EncryptedState) 762 | { 763 | m_XBOX_Version = XBOXVersion; 764 | return EncryptAndCalculateCRC(); 765 | } 766 | else return FALSE; 767 | } 768 | 769 | /*Encrypt with Current XBOX version by means of the SHA1 Middle Message hack..*/ 770 | BOOL XKEEPROM::EncryptAndCalculateCRC() 771 | { 772 | BOOL retVal = FALSE; 773 | UCHAR key_hash[20]; //rc4 key initializer 774 | 775 | XKRC4 RC4Obj; 776 | XKSHA1 SHA1Obj; 777 | 778 | if (((m_XBOX_Version == V1_0) ||(m_XBOX_Version == V1_1)||(m_XBOX_Version == V1_6)) && (!m_EncryptedState)) 779 | { 780 | //clear and re-create data_hash from decrypted data 781 | ZeroMemory(&m_EEPROMData.HMAC_SHA1_Hash, 20); 782 | SHA1Obj.XBOX_HMAC_SHA1(m_XBOX_Version, (UCHAR*)&m_EEPROMData.HMAC_SHA1_Hash, &m_EEPROMData.Confounder, 8, &m_EEPROMData.HDDKkey, 20, NULL); 783 | 784 | //calculate rc4 key initializer data from eeprom key and data_hash 785 | SHA1Obj.XBOX_HMAC_SHA1(m_XBOX_Version, key_hash, &m_EEPROMData.HMAC_SHA1_Hash, 20, NULL); 786 | 787 | XKRC4::RC4KEY RC4_key; 788 | 789 | //initialize RC4 key 790 | RC4Obj.InitRC4Key(key_hash, 20, &RC4_key); 791 | 792 | //Encrypt data (in eeprom) with generated key 793 | RC4Obj.RC4EnDecrypt ((UCHAR*)&m_EEPROMData.Confounder, 8, &RC4_key); 794 | RC4Obj.RC4EnDecrypt ((UCHAR*)&m_EEPROMData.HDDKkey, 20, &RC4_key); 795 | 796 | CalculateChecksum2(); 797 | CalculateChecksum3(); 798 | 799 | m_EncryptedState = TRUE; 800 | retVal = TRUE; 801 | } 802 | else 803 | { 804 | retVal = FALSE; 805 | m_XBOX_Version = V_NONE; 806 | } 807 | 808 | return retVal; 809 | 810 | } 811 | 812 | /*Decrypt EEPROM using auto-detect by means of the SHA1 Middle Message hack..*/ 813 | BOOL XKEEPROM::Decrypt() 814 | { 815 | BOOL retVal = FALSE; 816 | UCHAR key_hash[20]; //rc4 key initializer 817 | UCHAR data_hash_confirm[20]; //20 bytes 818 | UCHAR XBOX_Version = V1_0; 819 | 820 | XKRC4 RC4Obj; 821 | XKRC4::RC4KEY RC4_key; 822 | XKSHA1 SHA1Obj; 823 | UCHAR eepData[0x30]; 824 | int counter; 825 | //struct rc4_key RC4_key; 826 | //Keep the Original Data, incase the function fails we can restore it.. 827 | ZeroMemory(eepData, 0x30); 828 | memcpy(eepData, &m_EEPROMData, 0x30); 829 | 830 | while (((XBOX_Version < 13) && (!retVal)) && m_EncryptedState) 831 | { 832 | ZeroMemory(key_hash, 20); 833 | ZeroMemory(data_hash_confirm, 20); 834 | memset(&RC4_key,0,sizeof(RC4_key)); 835 | //calculate rc4 key initializer data from eeprom key and data_hash 836 | SHA1Obj.XBOX_HMAC_SHA1(XBOX_Version, key_hash, &m_EEPROMData.HMAC_SHA1_Hash, 20, NULL); 837 | 838 | //initialize RC4 key 839 | RC4Obj.InitRC4Key(key_hash, 20, &RC4_key); 840 | 841 | //decrypt data (from eeprom) with generated key 842 | RC4Obj.RC4EnDecrypt ((UCHAR*)&m_EEPROMData.Confounder, 8, &RC4_key); 843 | RC4Obj.RC4EnDecrypt ((UCHAR*)&m_EEPROMData.HDDKkey, 20, &RC4_key); 844 | 845 | //re-create data_hash from decrypted data 846 | SHA1Obj.XBOX_HMAC_SHA1(XBOX_Version, data_hash_confirm, &m_EEPROMData.Confounder, 8, &m_EEPROMData.HDDKkey, 20, NULL); 847 | 848 | //ensure retrieved data_hash matches regenerated data_hash_confirm 849 | if (strncmp((const char*)&m_EEPROMData.HMAC_SHA1_Hash,(const char*)&data_hash_confirm[0],0x14)) 850 | { 851 | //error: hash stored in eeprom[0:19] does not match 852 | //hash of data which should have been used to generate it. 853 | 854 | //The Key used was wrong.. Restore the Data back to original 855 | ZeroMemory(&m_EEPROMData, 0x30); 856 | memcpy(&m_EEPROMData, eepData, 0x30); 857 | 858 | m_XBOX_Version = V_NONE; 859 | retVal = FALSE; 860 | XBOX_Version++; 861 | } 862 | else 863 | { 864 | m_XBOX_Version = (XBOX_VERSION)XBOX_Version; 865 | m_EncryptedState = FALSE; 866 | retVal = TRUE; 867 | 868 | } 869 | } 870 | return retVal; 871 | } 872 | 873 | 874 | /*Decrypt With Specific RC4 Key, then detect which xbox Version is this key from*/ 875 | BOOL XKEEPROM::Decrypt(LPBYTE EEPROM_Key) 876 | { 877 | BOOL retVal = FALSE; 878 | UCHAR key_hash[20]; //rc4 key initializer 879 | UCHAR data_hash_confirm[20]; //20 bytes 880 | UCHAR XBOX_Version = V1_0; 881 | 882 | XKRC4 RC4Obj; 883 | XKRC4::RC4KEY RC4_key; 884 | XKSHA1 SHA1Obj; 885 | UCHAR eepData[0x30]; 886 | 887 | if (m_EncryptedState) //Can only decrypt if currently encrypted.. 888 | { 889 | //Keep the Original Data, incase the function fails we can restore it.. 890 | ZeroMemory(eepData, 0x30); 891 | memcpy(eepData, &m_EEPROMData, 0x30); 892 | 893 | ZeroMemory(key_hash, 20); 894 | ZeroMemory(data_hash_confirm, 20); 895 | 896 | //calculate rc4 key initializer data from eeprom key and data_hash 897 | SHA1Obj.HMAC_SHA1(key_hash, EEPROM_Key, 16, (UCHAR*)&m_EEPROMData.HMAC_SHA1_Hash, 20, NULL, 0); 898 | 899 | //initialize RC4 key 900 | RC4Obj.InitRC4Key(key_hash, 20, &RC4_key); 901 | 902 | //decrypt data (from eeprom) with generated key 903 | RC4Obj.RC4EnDecrypt ((UCHAR*)&m_EEPROMData.Confounder, 8, &RC4_key); 904 | RC4Obj.RC4EnDecrypt ((UCHAR*)&m_EEPROMData.HDDKkey, 20, &RC4_key); 905 | 906 | //re-create data_hash from decrypted data 907 | SHA1Obj.HMAC_SHA1(data_hash_confirm, EEPROM_Key, 16, (UCHAR*)&m_EEPROMData.Confounder, 8, (UCHAR*)&m_EEPROMData.HDDKkey, 20); 908 | 909 | //ensure retrieved data_hash matches regenerated data_hash_confirm 910 | if (strncmp((const char*)&m_EEPROMData.HMAC_SHA1_Hash,(const char*)&data_hash_confirm[0],0x14)) 911 | { 912 | //error: hash stored in eeprom[0:19] does not match 913 | //hash of data which should have been used to generate it. 914 | 915 | //The Key used was wrong.. Restore the Data back to original 916 | ZeroMemory(&m_EEPROMData, 0x30); 917 | memcpy(&m_EEPROMData, eepData, 0x30); 918 | 919 | m_XBOX_Version = V_NONE; 920 | retVal = FALSE; 921 | } 922 | else 923 | { 924 | //Key supplied is indeed correct for this eeprom.. 925 | //Now detect Version by simply decrypting again with auto detect.. 926 | ZeroMemory(&m_EEPROMData, 0x30); 927 | memcpy(&m_EEPROMData, eepData, 0x30); 928 | m_XBOX_Version = V_NONE; 929 | retVal = Decrypt(); 930 | } 931 | } 932 | return retVal; 933 | } 934 | 935 | //Encapsulated variable.. 936 | BOOL XKEEPROM::IsEncrypted() 937 | { 938 | return m_EncryptedState; 939 | } 940 | 941 | //Calculate Checksum2 942 | void XKEEPROM::CalculateChecksum2() 943 | { 944 | //Calculate CRC for Serial, Mac, OnlineKey, video region 945 | XKCRC::QuickCRC(m_EEPROMData.Checksum2, m_EEPROMData.SerialNumber, 0x2C); 946 | } 947 | 948 | //Calculate Checksum3 949 | void XKEEPROM::CalculateChecksum3() 950 | { 951 | //calculate CRC's for time zones, time standards, language, dvd region etc. 952 | XKCRC::QuickCRC(m_EEPROMData.Checksum3, m_EEPROMData.TimeZoneBias, 0x5C); 953 | } 954 | 955 | -------------------------------------------------------------------------------- /XKEEPROM.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************** 3 | ********************************** 4 | ** BROUGHT TO YOU BY: ** 5 | ********************************** 6 | ********************************** 7 | ** ** 8 | ** [TEAM ASSEMBLY] ** 9 | ** ** 10 | ** www.team-assembly.com ** 11 | ** ** 12 | ****************************************************************************************************** 13 | * This is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 | ****************************************************************************************************** 27 | 28 | 29 | ******************************************************************************************************** 30 | ** XKEEPROM.H - XBOX EEPROM Class' Header 31 | ******************************************************************************************************** 32 | ** 33 | ** This is the Class Header, see the .CPP file for more comments and implementation details. 34 | ** 35 | ******************************************************************************************************** 36 | 37 | ******************************************************************************************************** 38 | ** CREDITS: 39 | ******************************************************************************************************** 40 | ** XBOX-LINUX TEAM: 41 | ** --------------- 42 | ** Wow, you guys are awsome !! I bow down to your greatness !! the "Friday 13th" Middle 43 | ** Message Hack really saved our butts !! 44 | ** REFERENCE URL: http://xbox-linux.sourceforge.net 45 | ** 46 | ******************************************************************************************************** 47 | 48 | UPDATE LOG: 49 | -------------------------------------------------------------------------------------------------------- 50 | Date: 11/27/2004 51 | By: Yoshihiro 52 | Reason: Update for xbox 1.6 53 | -------------------------------------------------------------------------------------------------------- 54 | Date: 02/18/2003 55 | By: UNDEAD [team-assembly] 56 | Reason: Prepared 0.2 for Public Release 57 | -------------------------------------------------------------------------------------------------------- 58 | Date: 01/25/2003 59 | By: UNDEAD [team-assembly] 60 | Reason: Added XBOX Specific code to read EEPROM Data from Hardware 61 | -------------------------------------------------------------------------------------------------------- 62 | Date: 01/06/2003 63 | By: UNDEAD [team-assembly] 64 | Reason: Prepared for Public Release 65 | -------------------------------------------------------------------------------------------------------- 66 | */ 67 | 68 | #pragma once 69 | #if defined (_WINDOWS) 70 | #pragma message ("Compiling for WINDOWS: " __FILE__) 71 | #include // MFC core and standard components 72 | #elif defined (_XBOX) 73 | #pragma message ("Compiling for XBOX: " __FILE__) 74 | #include 75 | #include "XKExports.h" 76 | #include "XKUtils.h" 77 | #else 78 | // #error ERR: Have to Define _WINDOWS or _XBOX !! 79 | #include "fixme.h" 80 | #endif 81 | 82 | #include "XKGeneral.h" 83 | #include "XKRC4.h" 84 | #include "XKSHA1.h" 85 | #include "XKCRC.h" 86 | 87 | 88 | class XKEEPROM 89 | { 90 | public: 91 | //Defines for Data structure sizes.. 92 | #define EEPROM_SIZE 0x100 93 | #define CONFOUNDER_SIZE 0x008 94 | #define HDDKEY_SIZE 0x010 95 | #define XBEREGION_SIZE 0x001 96 | #define SERIALNUMBER_SIZE 0x00C 97 | #define MACADDRESS_SIZE 0x006 98 | #define ONLINEKEY_SIZE 0x010 99 | #define DVDREGION_SIZE 0x001 100 | #define VIDEOSTANDARD_SIZE 0x004 101 | 102 | //EEPROM Data structe value enums 103 | enum XBOX_VERSION 104 | { 105 | V_NONE = 0x00, 106 | V1_0 = 0x0A, 107 | V1_1 = 0x0B, 108 | V1_6 = 0x0C 109 | }; 110 | 111 | enum DVD_ZONE 112 | { 113 | ZONE_NONE = 0x00, 114 | ZONE1 = 0x01, 115 | ZONE2 = 0x02, 116 | ZONE3 = 0x03, 117 | ZONE4 = 0x04, 118 | ZONE5 = 0x05, 119 | ZONE6 = 0x06 120 | }; 121 | 122 | enum VIDEO_STANDARD 123 | { 124 | VID_INVALID = 0x00000000, 125 | NTSC_M = 0x00400100, 126 | PAL_I = 0x00800300 127 | }; 128 | 129 | enum XBE_REGION 130 | { 131 | XBE_INVALID = 0x00, 132 | NORTH_AMERICA = 0x01, 133 | JAPAN = 0x02, 134 | EURO_AUSTRALIA = 0x04 135 | }; 136 | 137 | 138 | //Structure that holds contents of 256 byte EEPROM image.. 139 | #pragma pack(1) 140 | struct EEPROMDATA 141 | { 142 | BYTE HMAC_SHA1_Hash[20]; // 0x00 - 0x13 HMAC_SHA1 Hash 143 | BYTE Confounder[8]; // 0x14 - 0x1B RC4 Encrypted Confounder ?? 144 | BYTE HDDKkey[16]; // 0x1C - 0x2B RC4 Encrypted HDD key 145 | BYTE XBERegion[4]; // 0x2C - 0x2F RC4 Encrypted Region code (0x01 North America, 0x02 Japan, 0x04 Europe) 146 | 147 | BYTE Checksum2[4]; // 0x30 - 0x33 Checksum of next 44 bytes 148 | UCHAR SerialNumber[12]; // 0x34 - 0x3F Xbox serial number 149 | BYTE MACAddress[6]; // 0x40 - 0x45 Ethernet MAC address 150 | BYTE UNKNOWN2[2]; // 0x46 - 0x47 Unknown Padding ? 151 | 152 | BYTE OnlineKey[16]; // 0x48 - 0x57 Online Key ? 153 | 154 | BYTE VideoStandard[4]; // 0x58 - 0x5B ** 0x00014000 = NTSC, 0x00038000 = PAL 155 | 156 | BYTE UNKNOWN3[4]; // 0x5C - 0x5F Unknown Padding ? 157 | 158 | 159 | //Comes configured up to here from factory.. everything after this can be zero'd out... 160 | //To reset XBOX to Factory settings, Make checksum3 0xFFFFFFFF and zero all data below (0x64-0xFF) 161 | //Doing this will Reset XBOX and upon startup will get Language & Setup screen... 162 | BYTE Checksum3[4]; // 0x60 - 0x63 other Checksum of next 163 | 164 | BYTE TimeZoneBias[4]; // 0x64 - 0x67 Zone Bias? 165 | UCHAR TimeZoneStdName[4]; // 0x68 - 0x6B Standard timezone 166 | UCHAR TimeZoneDltName[4]; // 0x5C - 0x6F Daylight timezone 167 | BYTE UNKNOWN4[8]; // 0x70 - 0x77 Unknown Padding ? 168 | BYTE TimeZoneStdDate[4]; // 0x78 - 0x7B 10-05-00-02 (Month-Day-DayOfWeek-Hour) 169 | BYTE TimeZoneDltDate[4]; // 0x7C - 0x7F 04-01-00-02 (Month-Day-DayOfWeek-Hour) 170 | BYTE UNKNOWN5[8]; // 0x80 - 0x87 Unknown Padding ? 171 | BYTE TimeZoneStdBias[4]; // 0x88 - 0x8B Standard Bias? 172 | BYTE TimeZoneDltBias[4]; // 0x8C - 0x8F Daylight Bias? 173 | 174 | BYTE LanguageID[4]; // 0x90 - 0x93 Language ID 175 | 176 | BYTE VideoFlags[4]; // 0x94 - 0x97 Video Settings 177 | BYTE AudioFlags[4]; // 0x98 - 0x9B Audio Settings 178 | 179 | BYTE ParentalControlGames[4]; // 0x9C - 0x9F 0=MAX rating 180 | BYTE ParentalControlPwd[4]; // 0xA0 - 0xA3 7=X, 8=Y, B=LTrigger, C=RTrigger 181 | BYTE ParentalControlMovies[4]; // 0xA4 - 0xA7 0=Max rating 182 | 183 | BYTE XBOXLiveIPAddress[4]; // 0xA8 - 0xAB XBOX Live IP Address.. 184 | BYTE XBOXLiveDNS[4]; // 0xAC - 0xAF XBOX Live DNS Server.. 185 | BYTE XBOXLiveGateWay[4]; // 0xB0 - 0xB3 XBOX Live Gateway Address.. 186 | BYTE XBOXLiveSubNetMask[4]; // 0xB4 - 0xB7 XBOX Live Subnet Mask.. 187 | BYTE OtherSettings[4]; // 0xA8 - 0xBB Other XBLive settings ? 188 | 189 | BYTE DVDPlaybackKitZone[4]; // 0xBC - 0xBF DVD Playback Kit Zone 190 | 191 | BYTE UNKNOWN6[64]; // 0xC0 - 0xFF Unknown Codes / History ? 192 | }; 193 | #pragma pack() 194 | typedef EEPROMDATA* LPEEPROMDATA; 195 | 196 | XKEEPROM(void); 197 | XKEEPROM(LPEEPROMDATA pEEPROMData, BOOL Encrypted); 198 | ~XKEEPROM(void); 199 | 200 | BOOL ReadFromBINFile(LPCSTR FileName, BOOL IsEncrypted); 201 | BOOL WriteToBINFile(LPCSTR FileName); 202 | 203 | BOOL ReadFromCFGFile(LPCSTR FileName); 204 | BOOL WriteToCFGFile(LPCSTR FileName); 205 | 206 | //very XBOX specific funtions to read/write EEPROM from hardware 207 | #if defined (_XBOX) 208 | void ReadFromXBOX(); 209 | void WriteToXBOX(); 210 | #endif 211 | 212 | void GetEEPROMData(LPEEPROMDATA pEEPROMData); 213 | void SetDecryptedEEPROMData(XBOX_VERSION Version, LPEEPROMDATA pEEPROMData); 214 | void SetEncryptedEEPROMData(LPEEPROMDATA pEEPROMData); 215 | 216 | XBOX_VERSION GetXBOXVersion(); 217 | 218 | void GetConfounderString(LPSTR Confounder, LPDWORD Length); 219 | void SetConfounderString(LPCSTR Confounder); 220 | 221 | void GetHDDKeyString(LPSTR HDDKey, LPDWORD Length); 222 | void SetHDDKeyString(LPCSTR HDDKey); 223 | 224 | void GetXBERegionString(LPSTR XBERegion, LPDWORD Length); 225 | void SetXBERegionString(LPCSTR XBERegion); 226 | void SetXBERegionVal(XBE_REGION RegionVal); 227 | XBE_REGION GetXBERegionVal(); 228 | 229 | void GetSerialNumberString(LPSTR SerialNumber, LPDWORD Length); 230 | void SetSerialNumberString(LPCSTR SerialNumber); 231 | 232 | void GetMACAddressString(LPSTR MACAddress, LPDWORD Length); 233 | void SetMACAddressString(LPCSTR MACAddress); 234 | 235 | void GetOnlineKeyString(LPSTR OnlineKey, LPDWORD Length); 236 | void SetOnlineKeyString(LPCSTR OnlineKey); 237 | 238 | void GetDVDRegionString(LPSTR DVDRegion, LPDWORD Length); 239 | void SetDVDRegionString(LPCSTR DVDRegion); 240 | void SetDVDRegionVal(DVD_ZONE ZoneVal); 241 | DVD_ZONE GetDVDRegionVal(); 242 | 243 | void GetVideoStandardString(LPSTR VideoStandard, LPDWORD Length); 244 | void SetVideoStandardString(LPCSTR VideoStandard); 245 | void SetVideoStandardVal(VIDEO_STANDARD StandardVal); 246 | VIDEO_STANDARD GetVideoStandardVal(); 247 | 248 | BOOL EncryptAndCalculateCRC(); 249 | BOOL EncryptAndCalculateCRC(XBOX_VERSION XBOXVersion); 250 | 251 | BOOL Decrypt(); 252 | BOOL Decrypt(LPBYTE EEPROM_Key); 253 | 254 | BOOL IsEncrypted(); 255 | 256 | void CalculateChecksum2(); 257 | void CalculateChecksum3(); 258 | 259 | protected: 260 | EEPROMDATA m_EEPROMData; 261 | XBOX_VERSION m_XBOX_Version; 262 | BOOL m_EncryptedState; 263 | 264 | }; 265 | 266 | typedef XKEEPROM::XBOX_VERSION XBOX_VERSION; 267 | typedef XKEEPROM::DVD_ZONE DVD_ZONE; 268 | typedef XKEEPROM::VIDEO_STANDARD VIDEO_STANDARD; 269 | typedef XKEEPROM::XBE_REGION XBE_REGION; 270 | typedef XKEEPROM::EEPROMDATA EEPROMDATA; 271 | typedef XKEEPROM::LPEEPROMDATA LPEEPROMDATA; 272 | 273 | -------------------------------------------------------------------------------- /XKGeneral.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************** 3 | ********************************** 4 | ** BROUGHT TO YOU BY: ** 5 | ********************************** 6 | ********************************** 7 | ** ** 8 | ** [TEAM ASSEMBLY] ** 9 | ** ** 10 | ** www.team-assembly.com ** 11 | ** ** 12 | ****************************************************************************************************** 13 | * This is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 | ****************************************************************************************************** 27 | 28 | 29 | ******************************************************************************************************** 30 | ** XKGENERAL.CPP - General Utility and Helper function Implementation 31 | ******************************************************************************************************** 32 | ** 33 | ** This Class contains mostly static helper functions to do all kinds of data/type conversions 34 | ** and read from INI files etc.. This is a work in progress and will continue to grow.. 35 | ** 36 | ******************************************************************************************************** 37 | 38 | UPDATE LOG: 39 | -------------------------------------------------------------------------------------------------------- 40 | Date: 02/18/2003 41 | By: UNDEAD [team-assembly] 42 | Reason: Prepared 0.2 for Public Release 43 | -------------------------------------------------------------------------------------------------------- 44 | Date: 01/08/2003 45 | By: UNDEAD [team-assembly] 46 | Reason: Fixed two Memory leaks - Thanks to tommyhl for spotting it!!! 47 | -------------------------------------------------------------------------------------------------------- 48 | Date: 01/06/2003 49 | By: UNDEAD [team-assembly] 50 | Reason: Prepared for Public Release 51 | -------------------------------------------------------------------------------------------------------- 52 | 53 | */ 54 | 55 | #include 56 | #include "XKGeneral.h" 57 | 58 | XKGeneral::XKGeneral(void) 59 | { 60 | } 61 | 62 | XKGeneral::~XKGeneral(void) 63 | { 64 | } 65 | 66 | //This Funciton converts BYTES to a String representation of the HEX value of the Bytes 67 | void XKGeneral::BytesToHexStr(LPBYTE SrcBytes, DWORD byteCount, LPSTR DstString) 68 | { 69 | BytesToHexStr(SrcBytes, byteCount, DstString, 0x00); 70 | } 71 | 72 | //This Funciton converts BYTES to a String representation of the HEX value of the Bytes 73 | //Includes a paramter to specify a seperator or Field delimiter between Hex BYTE values 74 | void XKGeneral::BytesToHexStr(LPBYTE SrcBytes, DWORD byteCount, LPSTR DstString, UCHAR Seperator) 75 | { 76 | USHORT Inc = (Seperator == 0x00)?2:3; 77 | 78 | for (ULONG i=0; i < byteCount; i++) 79 | { 80 | if ((UCHAR)*(SrcBytes+i) > 0x0F) 81 | { 82 | itoa((UCHAR)*(SrcBytes+i), DstString+(i*Inc), 16); 83 | } 84 | else 85 | { 86 | *(DstString+i*Inc) = '0'; 87 | itoa((UCHAR)*(SrcBytes+i), DstString+(i*Inc+1), 16); 88 | 89 | } 90 | } 91 | 92 | if (Seperator != 0x00) 93 | { 94 | for (ULONG i=1; i < byteCount; i++) 95 | *(DstString+i*Inc-1) = Seperator; 96 | } 97 | 98 | } 99 | 100 | //This Function converts a String that Contains anyting to into 101 | //a String that containts ONLY valid numerical values.. 102 | //Specify the base, eg. Hex = 16, Decimal=10 etc. 103 | //RemoveInvalid indacates if invalid values should be Zero or removed.. 104 | void XKGeneral::MixedStrToDecStr(LPSTR StringData, LPDWORD StrLen, CHAR Base, BOOL RemoveInvalid) 105 | { 106 | UCHAR DecChars[16] = HEX_VALUES; 107 | 108 | DWORD dwSize = *StrLen; 109 | DWORD currentOffset = 0; 110 | LPSTR sData = new CHAR[dwSize+1]; 111 | ZeroMemory(sData, dwSize+1); 112 | strncpy(sData, StringData, dwSize); 113 | 114 | if (!RemoveInvalid) 115 | memset(StringData, '0', dwSize); 116 | else 117 | ZeroMemory(StringData, dwSize); 118 | 119 | strupr(sData); 120 | 121 | for (DWORD i = 0; i < dwSize; i++) 122 | { 123 | LPSTR ChrOffset = strchr((LPCSTR)&DecChars, *(sData+i)); 124 | if ((ChrOffset != NULL) && ((ChrOffset - (LPSTR)&DecChars) <= Base-1)) 125 | { 126 | memcpy(StringData+currentOffset, ChrOffset, 1); 127 | currentOffset++; 128 | } 129 | else if (!RemoveInvalid) 130 | { 131 | currentOffset++; 132 | } 133 | } 134 | 135 | delete[] sData; 136 | *StrLen = (DWORD)strlen(StringData); 137 | 138 | } 139 | 140 | DWORD XKGeneral::HexStrToDWORD(LPBYTE StringData, LPDWORD pBufferLen, BOOL RemoveInvalid, BOOL FlipByteOrder) 141 | { 142 | DWORD retVal = 0; 143 | BYTE temp[4]; 144 | 145 | 146 | HexStrToBytes(StringData, pBufferLen, RemoveInvalid); 147 | 148 | if (FlipByteOrder) 149 | { 150 | memcpy(temp, StringData, 4); 151 | StringData[3] = temp[0]; 152 | StringData[2] = temp[1]; 153 | StringData[1] = temp[2]; 154 | StringData[0] = temp[3]; 155 | } 156 | 157 | retVal = *((LPDWORD) StringData); 158 | return retVal; 159 | } 160 | 161 | //This Funciton converts String representation of the HEX value into BYTES 162 | //RemoveInvalid indacates if invalid values should be Zero or removed.. 163 | void XKGeneral::HexStrToBytes(LPBYTE StringData, LPDWORD pBufferLen, BOOL RemoveInvalid) 164 | { 165 | UCHAR retVal = 0x00; 166 | 167 | DWORD dwSize = *pBufferLen; 168 | LPSTR sData = new CHAR[dwSize+1]; 169 | 170 | ZeroMemory(sData, dwSize+1); 171 | strncpy(sData, (LPCSTR)StringData, dwSize); 172 | ZeroMemory(StringData, dwSize); 173 | 174 | MixedStrToDecStr(sData, &dwSize, 16, RemoveInvalid); 175 | 176 | for (DWORD i = 0; i < dwSize/2; i++) 177 | { 178 | UCHAR tmpstr[3]; 179 | ZeroMemory(tmpstr,3); 180 | memcpy(tmpstr, (LPCSTR)(sData+(i*2)), 2); 181 | memset(StringData+i, (UCHAR)strtol((LPCSTR)&tmpstr, NULL, 16), 1); 182 | } 183 | 184 | delete[] sData; 185 | *pBufferLen = dwSize/2; 186 | } 187 | 188 | //This Funciton can read from an INI file and parse out certain values from the file 189 | // 190 | // Example .INI file can contain: 191 | // 192 | // [SECTION_MAIN] 193 | // Value1 = "My Value" 194 | // 195 | BOOL XKGeneral::ReadINIFileItem(const char *INIFileName, const char *INISection, const char *INIItem, char *ItemValue, LPDWORD ValueLen) 196 | { 197 | BOOL retVal = FALSE; 198 | LONG retSize = 0; 199 | 200 | HANDLE iniFile = CreateFile(INIFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 201 | 202 | if (iniFile != INVALID_HANDLE_VALUE) 203 | { 204 | LPSTR sTempSection = NULL; 205 | LPSTR sNextSection = NULL ; 206 | LPSTR sTempItem = NULL; 207 | ULONG sectionOffset = 0; 208 | DWORD filesize = GetFileSize(iniFile, NULL); 209 | BOOL foundSection = FALSE, foundItem=FALSE; 210 | 211 | LPBYTE iniData = new BYTE[filesize+2]; 212 | ZeroMemory(iniData, filesize+2); 213 | memset(iniData, '\n', filesize+2); //This is a cheezy trick to help not to search past end of the file.. 214 | 215 | ReadFile(iniFile, iniData, filesize, &filesize, NULL); 216 | 217 | do 218 | { 219 | sTempSection = strchr((LPCSTR)iniData+sectionOffset, '['); 220 | if ((sTempSection != NULL) && (strncmp(sTempSection+1, INISection, strlen(INISection)) == 0)) 221 | { 222 | sNextSection = strchr((LPCSTR)sTempSection + strlen(INISection), '['); 223 | sNextSection = (sNextSection != NULL)?sNextSection:(LPSTR)iniData + filesize; 224 | 225 | foundSection = TRUE; 226 | break; 227 | } 228 | sectionOffset = (ULONG)((LPBYTE)sTempSection - iniData) + 1; 229 | } 230 | while (sTempSection != NULL); 231 | 232 | if (foundSection) 233 | for (LPSTR finditem = sTempSection+strlen(INISection)+2; finditem < sNextSection-1; finditem = min(strchr(finditem, '\n')+1, sNextSection)) 234 | { 235 | LPSTR snextitem = min(strchr(finditem, '\n')+1, sNextSection); 236 | LPSTR spossible = strchr(finditem, *INIItem); 237 | LPSTR scomment = strchr(finditem, '#'); 238 | 239 | if ((spossible!= NULL) && (scomment != NULL) && (scomment < spossible)) 240 | continue; //found a Commented Line.. 241 | 242 | if ((spossible!= NULL) && (spossible < snextitem)) 243 | finditem = spossible; //found possible match 244 | 245 | //Check if its a sure match... 246 | if (strncmp(finditem, INIItem, strlen(INIItem)) == 0) 247 | { 248 | foundItem = TRUE; 249 | 250 | sTempItem = strchr(finditem+strlen(INIItem), '=') + 1; 251 | LPSTR sEnd = min(strchr(sTempItem, '\n')-1, sNextSection); 252 | LONG sLen = (LONG)(sEnd - sTempItem); 253 | LONG sLen2 = (LONG)min((LONG)strlen(sTempItem), sLen); 254 | 255 | if (*ValueLen >= (DWORD)sLen2) 256 | { 257 | ULONG startpos = 0; 258 | ULONG endpos = (ULONG)sLen2; 259 | 260 | //Do LEFT and RIGHT trim.... 261 | while ((*sTempItem+startpos == ' ') && (startpos < endpos)) 262 | startpos++; 263 | 264 | while ((*sTempItem+endpos == ' ') && (endpos > startpos)) 265 | endpos--; 266 | 267 | 268 | ZeroMemory(ItemValue, sLen2+1); 269 | strncpy(ItemValue, sTempItem+startpos,sLen2-startpos-(sLen2-endpos)); 270 | 271 | } 272 | else 273 | { 274 | foundSection = FALSE; 275 | foundItem = FALSE; 276 | } 277 | retSize = (LONG)min((LONG)strlen(sTempItem), sLen); 278 | 279 | break; 280 | } 281 | } 282 | 283 | retVal = foundSection & foundItem; 284 | delete[] iniData; 285 | CloseHandle(iniFile); 286 | } 287 | 288 | *ValueLen = retSize; 289 | return retVal; 290 | } 291 | 292 | //This Funciton can write value in an INI file 293 | // 294 | // Example .INI file can contain: 295 | // 296 | // [SECTION_MAIN] 297 | // Value1 = "My Value" 298 | // 299 | BOOL XKGeneral::WriteINIFileItem(const char *INIFileName,const char *INISection,const char *INIItem,const char *ItemValue) 300 | { 301 | char ctINIFileName[MAX_PATH+1]; 302 | char ctINISection[MAX_PATH+1]; 303 | char ctINIItem[MAX_PATH+1]; 304 | char ctItemValue[MAX_PATH+1]; 305 | char ctSearchINISection[MAX_PATH+1]; 306 | char ctSearchINIItem[MAX_PATH+1]; 307 | char ctINILine[MAX_PATH]; 308 | FILE *INIFile=NULL; 309 | FILE *TMPFile=NULL; 310 | bool bInINISection=false; 311 | bool bINISectionExist=false; 312 | bool bModified=false; 313 | 314 | strcpy(ctINIFileName,INIFileName); 315 | StripSpaces(ctINIFileName); 316 | strcpy(ctINISection,INISection); 317 | StripSpaces(ctINISection); 318 | strcpy(ctINIItem,INIItem); 319 | StripSpaces(ctINIItem); 320 | strcpy(ctItemValue,ItemValue); 321 | StripSpaces(ctItemValue); 322 | sprintf(ctSearchINISection,"[%s]",ctINISection); 323 | sprintf(ctSearchINIItem,"%s=",ctINIItem); 324 | 325 | INIFile=fopen(ctINIFileName,"r+"); 326 | if (!INIFile) INIFile=fopen(ctINIFileName,"w+"); 327 | if (INIFile) 328 | { 329 | TMPFile=fopen("Z:\\WriteiniBackup.tmp","w+"); 330 | if (TMPFile) 331 | { 332 | while (!feof(INIFile)) 333 | { 334 | if (!fgets(ctINILine,MAX_PATH,INIFile)) break; 335 | // if (fscanf(INIFile,"%s",ctINILine)==EOF) break; 336 | 337 | StripCarriageReturn(ctINILine); 338 | StripSpaces(ctINILine); 339 | 340 | if (strlen(ctINILine)) 341 | { 342 | if (ctINILine[0]=='['&&ctINILine[strlen(ctINILine)-1]==']') 343 | { 344 | if (strcmp(ctINILine,ctSearchINISection)==0) 345 | { 346 | bInINISection=true; 347 | if (!bINISectionExist) bINISectionExist=true; 348 | } 349 | else if (bInINISection) bInINISection=false; 350 | } 351 | else if (bInINISection) 352 | { 353 | if (strncmp(ctINILine,ctSearchINIItem,strlen(ctSearchINIItem))==0) 354 | { 355 | sprintf(ctINILine,"%s%s",ctSearchINIItem,ctItemValue); 356 | bModified=true; 357 | } 358 | } 359 | 360 | } 361 | 362 | if (fprintf(TMPFile,"%s\n",ctINILine)<0) break; 363 | 364 | } 365 | 366 | if (!bModified) 367 | { 368 | if (!bINISectionExist) 369 | { 370 | fprintf(TMPFile,"%s\n",ctSearchINISection); 371 | fprintf(TMPFile,"%s%s\n",ctSearchINIItem,ctItemValue); 372 | bModified=true; 373 | } 374 | else 375 | { 376 | 377 | bInINISection=false; 378 | 379 | rewind(INIFile); 380 | rewind(TMPFile); 381 | 382 | while (!feof(INIFile)) 383 | { 384 | if (!fgets(ctINILine,MAX_PATH,INIFile)) break; 385 | // if (fscanf(INIFile,"%s",ctINILine)==EOF) break; 386 | 387 | StripCarriageReturn(ctINILine); 388 | StripSpaces(ctINILine); 389 | 390 | if (strlen(ctINILine)&&!bModified) 391 | { 392 | if (ctINILine[0]=='['&&ctINILine[strlen(ctINILine)-1]==']') 393 | { 394 | if (strcmp(ctINILine,ctSearchINISection)==0) bInINISection=true; 395 | } 396 | } 397 | 398 | if (fprintf(TMPFile,"%s\n",ctINILine)<0) break; 399 | 400 | if (bInINISection) 401 | { 402 | fprintf(TMPFile,"%s%s\n",ctSearchINIItem,ctItemValue); 403 | bInINISection=false; 404 | bModified=true; 405 | } 406 | } 407 | 408 | } 409 | } 410 | 411 | rewind(INIFile); 412 | rewind(TMPFile); 413 | 414 | while (!feof(TMPFile)) 415 | { 416 | if (!fgets(ctINILine,MAX_PATH,TMPFile)) break; 417 | // if (fscanf(TMPFile,"%s",ctINILine)==EOF) break; 418 | StripCarriageReturn(ctINILine); 419 | StripSpaces(ctINILine); 420 | if (fprintf(INIFile,"%s\n",ctINILine)<0) break; 421 | } 422 | 423 | fclose(TMPFile); 424 | } 425 | fclose(INIFile); 426 | } 427 | return bModified; 428 | } 429 | 430 | //Strip Carriage Return Characters (10,13) From String 431 | void XKGeneral::StripCarriageReturn(LPSTR sString) 432 | { 433 | for (int iInd=0;iInd<(int)strlen(sString);iInd++) 434 | { 435 | if (sString[iInd]==10||sString[iInd]==13) 436 | { 437 | sString[iInd]=0; 438 | break; 439 | } 440 | } 441 | } 442 | 443 | //Strip Space Characters On Left And Right From String 444 | void XKGeneral::StripSpaces(LPSTR sString) 445 | { 446 | StripLeftSpaces(sString); 447 | StripRightSpaces(sString); 448 | } 449 | 450 | //Strip Space Characters On Left From String 451 | void XKGeneral::StripLeftSpaces(LPSTR sString) 452 | { 453 | char *pcTmp=NULL; 454 | int iInd; 455 | 456 | for (iInd=0;iInd<(int)strlen(sString);iInd++) 457 | { 458 | if (sString[iInd]!=' ') 459 | { 460 | pcTmp=&sString[iInd]; 461 | break; 462 | } 463 | } 464 | if (pcTmp) strcpy(sString,pcTmp); 465 | } 466 | 467 | //Strip Space Characters On Right From String 468 | void XKGeneral::StripRightSpaces(LPSTR sString) 469 | { 470 | int iInd; 471 | 472 | for (iInd=strlen(sString)-1;iInd>=0;iInd--) 473 | { 474 | if (sString[iInd]!=' ') 475 | { 476 | sString[++iInd]=0; 477 | break; 478 | } 479 | } 480 | } 481 | 482 | //Strip quotes from mostly File Paths.. hence FILENAME_MAX 483 | void XKGeneral::StripQuotes(LPSTR sString, LPDWORD strLen) 484 | { 485 | StripEnclosedChars(sString, strLen, '\"'); 486 | } 487 | 488 | //This Function simply strips out Characters from a enclosed string.. 489 | //Especially if reading from INI file and value is enlcosed with quotes.. 490 | void XKGeneral::StripEnclosedChars(LPSTR sString, LPDWORD strLen, CHAR EncloseChar) 491 | { 492 | UCHAR tmpString[FILENAME_MAX]; //Work off Max Filename.. should be big enough.. 493 | ZeroMemory(tmpString, FILENAME_MAX); 494 | 495 | //get string to work with.. 496 | strcpy((LPSTR)tmpString, sString); 497 | ZeroMemory(sString, *strLen); 498 | 499 | LPSTR tmpFirst = strchr((LPCSTR)tmpString, EncloseChar); 500 | LPSTR tmpLast = strrchr((LPCSTR)tmpString, EncloseChar); 501 | 502 | //check if Null, if null then just beginning of string.. 503 | tmpFirst = (tmpFirst != NULL)?tmpFirst+1:(LPSTR)tmpString; 504 | 505 | //check if Null, if null then just use end of string.. 506 | tmpLast = (tmpLast != NULL)?tmpLast:(LPSTR)tmpString+*strLen; 507 | 508 | *strLen = (LONG)(tmpLast - tmpFirst); 509 | 510 | if (tmpFirst != NULL) 511 | strncpy(sString, tmpFirst, *strLen); 512 | } 513 | 514 | // Modify Lower Characters Into Upper Characters Into String 515 | void XKGeneral::ToUpperString(LPSTR sString) 516 | { 517 | int iInd; 518 | 519 | for (iInd=0;iInd<(int)strlen(sString);iInd++) 520 | { 521 | if (sString[iInd]>='a'&&sString[iInd]<='z') sString[iInd]=toupper(sString[iInd]); 522 | else sString[iInd]=sString[iInd]; 523 | } 524 | } 525 | 526 | // Modify Upper Characters Into Lower Characters Into String 527 | void XKGeneral::ToLowerString(LPSTR sString) 528 | { 529 | int iInd; 530 | 531 | for (iInd=0;iInd<(int)strlen(sString);iInd++) 532 | { 533 | if (sString[iInd]>='A'&&sString[iInd]<='Z') sString[iInd]=tolower(sString[iInd]); 534 | else sString[iInd]=sString[iInd]; 535 | } 536 | } -------------------------------------------------------------------------------- /XKGeneral.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************** 3 | ********************************** 4 | ** BROUGHT TO YOU BY: ** 5 | ********************************** 6 | ********************************** 7 | ** ** 8 | ** [TEAM ASSEMBLY] ** 9 | ** ** 10 | ** www.team-assembly.com ** 11 | ** ** 12 | ****************************************************************************************************** 13 | * This is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 | ****************************************************************************************************** 27 | 28 | 29 | ******************************************************************************************************** 30 | ** XKGENERAL.H - General Utility and Helper function Class' Header 31 | ******************************************************************************************************** 32 | ** 33 | ** This is the Class Header, see the .CPP file for more comments and implementation details. 34 | ** 35 | ******************************************************************************************************** 36 | 37 | UPDATE LOG: 38 | -------------------------------------------------------------------------------------------------------- 39 | Date: 02/18/2003 40 | By: UNDEAD [team-assembly] 41 | Reason: Prepared 0.2 for Public Release 42 | -------------------------------------------------------------------------------------------------------- 43 | Date: 01/06/2003 44 | By: UNDEAD [team-assembly] 45 | Reason: Prepared for Public Release 46 | -------------------------------------------------------------------------------------------------------- 47 | 48 | */ 49 | 50 | #pragma once 51 | #if defined (_WINDOWS) 52 | #pragma message ("Compiling for WINDOWS: " __FILE__) 53 | #include // MFC core and standard components 54 | #elif defined (_XBOX) 55 | #pragma message ("Compiling for XBOX: " __FILE__) 56 | #include 57 | #else 58 | // #error ERR: Have to Define _WINDOWS or _XBOX !! 59 | #include "fixme.h" 60 | #endif 61 | 62 | #ifndef FILENAME_MAX 63 | #define FILENAME_MAX 260 64 | #endif 65 | 66 | class XKGeneral 67 | { 68 | protected: 69 | #define HEX_VALUES {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'} 70 | 71 | public: 72 | XKGeneral(void); 73 | ~XKGeneral(void); 74 | 75 | //Generic conversion functions.. 76 | static void BytesToHexStr(LPBYTE SrcBytes, DWORD byteCount, LPSTR DstString); 77 | static void BytesToHexStr(LPBYTE SrcBytes, DWORD byteCount, LPSTR DstString, UCHAR Seperator); 78 | static void MixedStrToDecStr(LPSTR StringData, LPDWORD StrLen, CHAR Base, BOOL RemoveInvalid); 79 | static void HexStrToBytes(LPBYTE StringData, LPDWORD pBufferLen, BOOL RemoveInvalid); 80 | static DWORD HexStrToDWORD(LPBYTE StringData, LPDWORD pBufferLen, BOOL RemoveInvalid, BOOL FlipByteOrder); 81 | 82 | //Read items and values from a .INI file.. 83 | static BOOL ReadINIFileItem(const char *INIFileName, const char *INISection, const char *INIItem, char *ItemValue, LPDWORD ValueLen); 84 | static BOOL WriteINIFileItem(const char *INIFileName, const char *INISection, const char *INIItem, const char *ItemValue); 85 | 86 | //Strip Quotes from a string.. 87 | static void StripLeftSpaces(LPSTR sString); 88 | static void StripRightSpaces(LPSTR sString); 89 | static void StripSpaces(LPSTR sString); 90 | static void StripCarriageReturn(LPSTR sString); 91 | static void StripEnclosedChars(LPSTR sString, LPDWORD strLen, CHAR EncloseChar); 92 | static void StripQuotes(LPSTR sString, LPDWORD strLen); 93 | static void ToUpperString(LPSTR sString); 94 | static void ToLowerString(LPSTR sString); 95 | }; 96 | -------------------------------------------------------------------------------- /XKRC4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************** 3 | ********************************** 4 | ** BROUGHT TO YOU BY: ** 5 | ********************************** 6 | ********************************** 7 | ** ** 8 | ** [TEAM ASSEMBLY] ** 9 | ** ** 10 | ** www.team-assembly.com ** 11 | ** ** 12 | ****************************************************************************************************** 13 | * This is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 | ****************************************************************************************************** 27 | 28 | ******************************************************************************************************** 29 | ** XKRC4.CPP - General RC4 Encryption Class' Implementation 30 | ******************************************************************************************************** 31 | ** 32 | ** This is the Class Contains basic RC4 encryption functionality... 33 | ** 34 | ******************************************************************************************************** 35 | 36 | 37 | ******************************************************************************************************** 38 | ** CREDITS: 39 | ******************************************************************************************************** 40 | ** SPEEDBUMP: 41 | ** --------- 42 | ** My utmost greatfullness and admiration goes towards SpeedBump for all his hard work.. 43 | ** I used most of his code and converted to C++ objects etc.. 44 | ** 45 | ** XBOX-LINUX TEAM: 46 | ** --------------- 47 | ** Wow, you guys are awsome !! I bow down to your greatness !! 48 | ** REFERENCE URL: http://xbox-linux.sourceforge.net 49 | ** 50 | ******************************************************************************************************** 51 | 52 | UPDATE LOG: 53 | -------------------------------------------------------------------------------------------------------- 54 | Date: 02/18/2003 55 | By: UNDEAD [team-assembly] 56 | Reason: Prepared 0.2 for Public Release 57 | -------------------------------------------------------------------------------------------------------- 58 | Date: 01/06/2003 59 | By: UNDEAD [team-assembly] 60 | Reason: Prepared for Public Release 61 | -------------------------------------------------------------------------------------------------------- 62 | 63 | */ 64 | #include "XKRC4.h" 65 | 66 | XKRC4::XKRC4(void) 67 | { 68 | } 69 | 70 | XKRC4::~XKRC4(void) 71 | { 72 | } 73 | 74 | void XKRC4::InitRC4Key(UCHAR* pRC4KeyData, int KeyLen, RC4KEY *pRC4Key) 75 | { 76 | UCHAR index1; 77 | UCHAR index2; 78 | UCHAR* state; 79 | short counter; 80 | 81 | state = &pRC4Key->state[0]; 82 | 83 | for(counter = 0; counter < 256; counter++) 84 | state[counter] = (UCHAR)counter; 85 | 86 | pRC4Key->x = 0; 87 | pRC4Key->y = 0; 88 | index1 = 0; 89 | index2 = 0; 90 | 91 | for(counter = 0; counter < 256; counter++) 92 | { 93 | index2 = (pRC4KeyData[index1] + state[counter] + index2) % 256; 94 | swap_byte(&state[counter], &state[index2]); 95 | index1 = (index1 + 1) % KeyLen; 96 | } 97 | } 98 | 99 | void XKRC4::RC4EnDecrypt(UCHAR* pData, int DataLen, RC4KEY *pRC4key) 100 | { 101 | unsigned char x; 102 | unsigned char y; 103 | unsigned char* state; 104 | unsigned char xorIndex; 105 | long counter; 106 | 107 | x = pRC4key->x; 108 | y = pRC4key->y; 109 | state = &pRC4key->state[0]; 110 | 111 | for(counter = 0; counter < DataLen; counter ++) 112 | { 113 | x = (x + 1) % 256; 114 | y = (state[x] + y) % 256; 115 | swap_byte(&state[x], &state[y]); 116 | xorIndex = (state[x] + state[y]) % 256; 117 | pData[counter] ^= state[xorIndex]; 118 | } 119 | 120 | pRC4key->x = x; 121 | pRC4key->y = y; 122 | } 123 | 124 | void XKRC4::swap_byte(unsigned char *a, unsigned char *b) 125 | { 126 | unsigned char swapByte; 127 | swapByte = *a; 128 | *a = *b; 129 | *b = swapByte; 130 | } -------------------------------------------------------------------------------- /XKRC4.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************** 3 | ********************************** 4 | ** BROUGHT TO YOU BY: ** 5 | ********************************** 6 | ********************************** 7 | ** ** 8 | ** [TEAM ASSEMBLY] ** 9 | ** ** 10 | ** www.team-assembly.com ** 11 | ** ** 12 | ****************************************************************************************************** 13 | * This is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 | ****************************************************************************************************** 27 | 28 | 29 | ******************************************************************************************************** 30 | ** XKRC4.H - General RC4 Encryption Class' Header 31 | ******************************************************************************************************** 32 | ** 33 | ** This is the Class Header, see the .CPP file for more comments and implementation details. 34 | ** 35 | ******************************************************************************************************** 36 | 37 | 38 | ******************************************************************************************************** 39 | ** CREDITS: 40 | ******************************************************************************************************** 41 | ** SPEEDBUMP: 42 | ** --------- 43 | ** My utmost greatfullness and admiration goes towards SpeedBump for all his hard work.. 44 | ** I used most of his code and converted to C++ objects etc.. 45 | ** 46 | ** XBOX-LINUX TEAM: 47 | ** --------------- 48 | ** Wow, you guys are awsome !! I bow down to your greatness !! 49 | ** REFERENCE URL: http://xbox-linux.sourceforge.net 50 | ** 51 | ******************************************************************************************************** 52 | 53 | UPDATE LOG: 54 | -------------------------------------------------------------------------------------------------------- 55 | Date: 02/18/2003 56 | By: UNDEAD [team-assembly] 57 | Reason: Prepared 0.2 for Public Release 58 | -------------------------------------------------------------------------------------------------------- 59 | Date: 01/06/2003 60 | By: UNDEAD [team-assembly] 61 | Reason: Prepared for Public Release 62 | -------------------------------------------------------------------------------------------------------- 63 | 64 | */ 65 | #pragma once 66 | #if defined (_WINDOWS) 67 | #pragma message ("Compiling for WINDOWS: " __FILE__) 68 | #include // MFC core and standard components 69 | #elif defined (_XBOX) 70 | #pragma message ("Compiling for XBOX: " __FILE__) 71 | #include 72 | #else 73 | // #error ERR: Have to Define _WINDOWS or _XBOX !! 74 | #include "fixme.h" 75 | #endif 76 | 77 | class XKRC4 78 | { 79 | protected: 80 | void swap_byte(UCHAR* a, UCHAR* b); 81 | 82 | public: 83 | struct RC4KEY 84 | { 85 | UCHAR state[256]; 86 | UCHAR x; 87 | UCHAR y; 88 | }; 89 | 90 | XKRC4(void); 91 | virtual ~XKRC4(void); 92 | 93 | void InitRC4Key(UCHAR* pRC4KeyData, int KeyLen, RC4KEY* pRC4Key); 94 | void RC4EnDecrypt(UCHAR* pData, int DataLen, RC4KEY* pRC4key); 95 | 96 | 97 | }; 98 | 99 | -------------------------------------------------------------------------------- /XKSHA1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************** 3 | ********************************** 4 | ** BROUGHT TO YOU BY: ** 5 | ********************************** 6 | ********************************** 7 | ** ** 8 | ** [TEAM ASSEMBLY] ** 9 | ** ** 10 | ** www.team-assembly.com ** 11 | ** ** 12 | ****************************************************************************************************** 13 | * This is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 | ****************************************************************************************************** 27 | 28 | ******************************************************************************************************** 29 | ** XKSHA1.CPP - SHA1 and HMAC_SHA1 Class' Implementation 30 | ******************************************************************************************************** 31 | ** 32 | ** This file implements the Secure Hashing Algorithm 1 as 33 | ** defined in FIPS PUB 180-1 published April 17, 1995. 34 | ** 35 | ** 36 | ** Added Funcionality to NOT require the KEY when doing HMAC_SHA1 hashes 37 | ** as per xbox-Linux groups "Fridaym 13th Middle Message Hack" 38 | ** 39 | ******************************************************************************************************** 40 | 41 | 42 | ******************************************************************************************************** 43 | ** CREDITS: 44 | ******************************************************************************************************** 45 | ** SPEEDBUMP: 46 | ** My utmost greatfullness and admiration goes towards SpeedBump for all his hard work.. 47 | ** I used most of his code and converted to C++ objects etc.. 48 | ** 49 | ** XBOX-LINUX TEAM: 50 | ** --------------- 51 | ** In particular "Franz", Wow, you guys are awsome !! I bow down to your greatness !! 52 | ** The "Friday 13th" Middle Message Hack really saved our butts !! 53 | ** REFERENCE URL: http://xbox-linux.sourceforge.net 54 | ** 55 | ******************************************************************************************************** 56 | 57 | UPDATE LOG: 58 | -------------------------------------------------------------------------------------------------------- 59 | Date: 02/18/2003 60 | By: UNDEAD [team-assembly] 61 | Reason: Prepared 0.2 for Public Release 62 | -------------------------------------------------------------------------------------------------------- 63 | Date: 01/06/2003 64 | By: UNDEAD [team-assembly] 65 | Reason: Prepared for Public Release 66 | -------------------------------------------------------------------------------------------------------- 67 | Date: 11/27/2004 68 | By: Yoshihiro 69 | Reason: Update for XBOX 1.6 Eeprom 70 | -------------------------------------------------------------------------------------------------------- 71 | 72 | */ 73 | 74 | 75 | #include "XKSHA1.h" 76 | 77 | XKSHA1::XKSHA1(void) 78 | { 79 | } 80 | 81 | XKSHA1::~XKSHA1(void) 82 | { 83 | } 84 | 85 | 86 | int XKSHA1::SHA1Reset(SHA1Context* context) 87 | { 88 | if (!context) 89 | { 90 | return shaNull; 91 | } 92 | 93 | context->Length_Low = 0; 94 | context->Length_High = 0; 95 | context->Message_Block_Index = 0; 96 | 97 | context->Intermediate_Hash[0] = 0x67452301; 98 | context->Intermediate_Hash[1] = 0xEFCDAB89; 99 | context->Intermediate_Hash[2] = 0x98BADCFE; 100 | context->Intermediate_Hash[3] = 0x10325476; 101 | context->Intermediate_Hash[4] = 0xC3D2E1F0; 102 | 103 | context->Computed = 0; 104 | context->Corrupted = 0; 105 | 106 | return shaSuccess; 107 | } 108 | 109 | 110 | int XKSHA1::SHA1Result( SHA1Context* context, UCHAR Message_Digest[SHA1HashSize]) 111 | { 112 | int i; 113 | 114 | if (!context || !Message_Digest) 115 | { 116 | return shaNull; 117 | } 118 | 119 | if (context->Corrupted) 120 | { 121 | return context->Corrupted; 122 | } 123 | 124 | if (!context->Computed) 125 | { 126 | SHA1PadMessage(context); 127 | for(i=0; i<64; ++i) 128 | { 129 | /* message may be sensitive, clear it out*/ 130 | context->Message_Block[i] = 0; 131 | } 132 | 133 | context->Length_Low = 0; /* and clear length */ 134 | context->Length_High = 0; 135 | context->Computed = 1; 136 | 137 | } 138 | 139 | for(i = 0; i < SHA1HashSize; ++i) 140 | { 141 | Message_Digest[i] = context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ); 142 | } 143 | 144 | return shaSuccess; 145 | } 146 | 147 | int XKSHA1::SHA1Input(SHA1Context* context, const UCHAR* message_array, unsigned int length) 148 | { 149 | if (!length) 150 | { 151 | return shaSuccess; 152 | } 153 | 154 | if (!context || !message_array) 155 | { 156 | return shaNull; 157 | } 158 | 159 | if (context->Computed) 160 | { 161 | context->Corrupted = shaStateError; 162 | 163 | return shaStateError; 164 | } 165 | 166 | if (context->Corrupted) 167 | { 168 | return context->Corrupted; 169 | } 170 | 171 | while(length-- && !context->Corrupted) 172 | { 173 | context->Message_Block[context->Message_Block_Index++] = (*message_array & 0xFF); 174 | 175 | context->Length_Low += 8; 176 | 177 | if (context->Length_Low == 0) 178 | { 179 | context->Length_High++; 180 | if (context->Length_High == 0) 181 | { 182 | /* Message is too long */ 183 | context->Corrupted = 1; 184 | } 185 | } 186 | 187 | if (context->Message_Block_Index == 64) 188 | { 189 | SHA1ProcessMessageBlock(context); 190 | } 191 | 192 | message_array++; 193 | } 194 | 195 | return shaSuccess; 196 | } 197 | 198 | 199 | 200 | void XKSHA1::SHA1ProcessMessageBlock(SHA1Context* context) 201 | { 202 | const UINT32 K[] = { /* Constants defined in SHA-1 */ 203 | 0x5A827999, 204 | 0x6ED9EBA1, 205 | 0x8F1BBCDC, 206 | 0xCA62C1D6 207 | }; 208 | int t; /* Loop counter */ 209 | UINT32 temp; /* Temporary word value */ 210 | UINT32 W[80]; /* Word sequence */ 211 | UINT32 A, B, C, D, E; /* Word buffers */ 212 | 213 | /* 214 | * Initialize the first 16 words in the array W 215 | */ 216 | for(t = 0; t < 16; t++) 217 | { 218 | W[t] = context->Message_Block[t * 4] << 24; 219 | W[t] |= context->Message_Block[t * 4 + 1] << 16; 220 | W[t] |= context->Message_Block[t * 4 + 2] << 8; 221 | W[t] |= context->Message_Block[t * 4 + 3]; 222 | } 223 | 224 | for(t = 16; t < 80; t++) 225 | { 226 | W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 227 | } 228 | 229 | A = context->Intermediate_Hash[0]; 230 | B = context->Intermediate_Hash[1]; 231 | C = context->Intermediate_Hash[2]; 232 | D = context->Intermediate_Hash[3]; 233 | E = context->Intermediate_Hash[4]; 234 | 235 | for(t = 0; t < 20; t++) 236 | { 237 | temp = SHA1CircularShift(5,A) + 238 | ((B & C) | ((~B) & D)) + E + W[t] + K[0]; 239 | E = D; 240 | D = C; 241 | C = SHA1CircularShift(30,B); 242 | 243 | B = A; 244 | A = temp; 245 | } 246 | 247 | for(t = 20; t < 40; t++) 248 | { 249 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; 250 | E = D; 251 | D = C; 252 | C = SHA1CircularShift(30,B); 253 | B = A; 254 | A = temp; 255 | } 256 | 257 | for(t = 40; t < 60; t++) 258 | { 259 | temp = SHA1CircularShift(5,A) + 260 | ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; 261 | E = D; 262 | D = C; 263 | C = SHA1CircularShift(30,B); 264 | B = A; 265 | A = temp; 266 | } 267 | 268 | for(t = 60; t < 80; t++) 269 | { 270 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; 271 | E = D; 272 | D = C; 273 | C = SHA1CircularShift(30,B); 274 | B = A; 275 | A = temp; 276 | } 277 | 278 | context->Intermediate_Hash[0] += A; 279 | context->Intermediate_Hash[1] += B; 280 | context->Intermediate_Hash[2] += C; 281 | context->Intermediate_Hash[3] += D; 282 | context->Intermediate_Hash[4] += E; 283 | 284 | context->Message_Block_Index = 0; 285 | } 286 | 287 | 288 | void XKSHA1::SHA1PadMessage(SHA1Context* context) 289 | { 290 | /* 291 | * Check to see if the current message block is too small to hold 292 | * the initial padding bits and length. If so, we will pad the 293 | * block, process it, and then continue padding into a second 294 | * block. 295 | */ 296 | if (context->Message_Block_Index > 55) 297 | { 298 | context->Message_Block[context->Message_Block_Index++] = 0x80; 299 | while(context->Message_Block_Index < 64) 300 | { 301 | context->Message_Block[context->Message_Block_Index++] = 0; 302 | } 303 | 304 | SHA1ProcessMessageBlock(context); 305 | 306 | while(context->Message_Block_Index < 56) 307 | { 308 | context->Message_Block[context->Message_Block_Index++] = 0; 309 | } 310 | } 311 | else 312 | { 313 | context->Message_Block[context->Message_Block_Index++] = 0x80; 314 | while(context->Message_Block_Index < 56) 315 | { 316 | 317 | context->Message_Block[context->Message_Block_Index++] = 0; 318 | } 319 | } 320 | 321 | /* 322 | * Store the message length as the last 8 octets 323 | */ 324 | context->Message_Block[56] = context->Length_High >> 24; 325 | context->Message_Block[57] = context->Length_High >> 16; 326 | context->Message_Block[58] = context->Length_High >> 8; 327 | context->Message_Block[59] = context->Length_High; 328 | context->Message_Block[60] = context->Length_Low >> 24; 329 | context->Message_Block[61] = context->Length_Low >> 16; 330 | context->Message_Block[62] = context->Length_Low >> 8; 331 | context->Message_Block[63] = context->Length_Low; 332 | 333 | SHA1ProcessMessageBlock(context); 334 | } 335 | 336 | 337 | void XKSHA1::quick_SHA1( UCHAR* SHA1_result, ... ) 338 | { 339 | va_list args; 340 | struct SHA1Context context; 341 | 342 | va_start(args,SHA1_result); 343 | 344 | SHA1Reset(&context); 345 | 346 | while(1) 347 | { 348 | UCHAR* buffer = va_arg(args,UCHAR* ); 349 | int length; 350 | 351 | if (buffer == NULL) break; 352 | 353 | length = va_arg(args,int); 354 | 355 | SHA1Input(&context,buffer,length); 356 | } 357 | 358 | SHA1Result(&context,SHA1_result); 359 | 360 | va_end(args); 361 | } 362 | 363 | 364 | void XKSHA1::HMAC_SHA1(UCHAR* result, UCHAR* key, int key_length, UCHAR* text1, int text1_length, UCHAR* text2, int text2_length) 365 | { 366 | UCHAR state1[0x40]; 367 | UCHAR state2[0x40+0x14]; 368 | int i; 369 | struct SHA1Context context; 370 | 371 | for(i=0x40-1; i>=key_length;--i) state1[i] = 0x36; 372 | for(;i>=0;--i) state1[i] = key[i] ^ 0x36; 373 | 374 | // quick_SHA1 ( &state2[0x40], 375 | // state1, 0x40, 376 | // text1, text1_length, 377 | // text2, text2_length, 378 | // NULL ); 379 | 380 | SHA1Reset(&context); 381 | SHA1Input(&context,state1,0x40); 382 | SHA1Input(&context,text1,text1_length); 383 | SHA1Input(&context,text2,text2_length); 384 | SHA1Result(&context,&state2[0x40]); 385 | 386 | for(i=0x40-1; i>=key_length;--i) state2[i] = 0x5C; 387 | for(;i>=0;--i) state2[i] = key[i] ^ 0x5C; 388 | 389 | //quick_SHA1 ( result,state2,0x40+0x14,NULL ); 390 | SHA1Reset(&context); 391 | SHA1Input(&context,state2,0x40+0x14); 392 | SHA1Result(&context,result); 393 | } 394 | 395 | 396 | int XKSHA1::HMAC1Reset(int version,SHA1Context *context) 397 | { 398 | SHA1Reset(context); 399 | switch (version) { 400 | case 9: 401 | context->Intermediate_Hash[0] = 0x85F9E51A; 402 | context->Intermediate_Hash[1] = 0xE04613D2; 403 | context->Intermediate_Hash[2] = 0x6D86A50C; 404 | context->Intermediate_Hash[3] = 0x77C32E3C; 405 | context->Intermediate_Hash[4] = 0x4BD717A4; 406 | break; 407 | case 10: 408 | context->Intermediate_Hash[0] = 0x72127625; 409 | context->Intermediate_Hash[1] = 0x336472B9; 410 | context->Intermediate_Hash[2] = 0xBE609BEA; 411 | context->Intermediate_Hash[3] = 0xF55E226B; 412 | context->Intermediate_Hash[4] = 0x99958DAC; 413 | break; 414 | case 11: 415 | context->Intermediate_Hash[0] = 0x39B06E79; 416 | context->Intermediate_Hash[1] = 0xC9BD25E8; 417 | context->Intermediate_Hash[2] = 0xDBC6B498; 418 | context->Intermediate_Hash[3] = 0x40B4389D; 419 | context->Intermediate_Hash[4] = 0x86BBD7ED; 420 | break; 421 | case 12: 422 | context->Intermediate_Hash[0] = 0x8058763a; 423 | context->Intermediate_Hash[1] = 0xf97d4e0e; 424 | context->Intermediate_Hash[2] = 0x865a9762; 425 | context->Intermediate_Hash[3] = 0x8a3d920d; 426 | context->Intermediate_Hash[4] = 0x08995b2c; 427 | break; 428 | } 429 | 430 | context->Length_Low = 512; 431 | 432 | return shaSuccess; 433 | } 434 | 435 | int XKSHA1::HMAC2Reset(int version,SHA1Context *context) 436 | { 437 | SHA1Reset(context); 438 | switch (version) { 439 | case 9: 440 | context->Intermediate_Hash[0] = 0x5D7A9C6B; 441 | context->Intermediate_Hash[1] = 0xE1922BEB; 442 | context->Intermediate_Hash[2] = 0xB82CCDBC; 443 | context->Intermediate_Hash[3] = 0x3137AB34; 444 | context->Intermediate_Hash[4] = 0x486B52B3; 445 | break; 446 | case 10: 447 | context->Intermediate_Hash[0] = 0x76441D41; 448 | context->Intermediate_Hash[1] = 0x4DE82659; 449 | context->Intermediate_Hash[2] = 0x2E8EF85E; 450 | context->Intermediate_Hash[3] = 0xB256FACA; 451 | context->Intermediate_Hash[4] = 0xC4FE2DE8; 452 | break; 453 | case 11: 454 | context->Intermediate_Hash[0] = 0x9B49BED3; 455 | context->Intermediate_Hash[1] = 0x84B430FC; 456 | context->Intermediate_Hash[2] = 0x6B8749CD; 457 | context->Intermediate_Hash[3] = 0xEBFE5FE5; 458 | context->Intermediate_Hash[4] = 0xD96E7393; 459 | break; 460 | case 12: 461 | context->Intermediate_Hash[0] = 0x01075307; 462 | context->Intermediate_Hash[1] = 0xa2f1e037; 463 | context->Intermediate_Hash[2] = 0x1186eeea; 464 | context->Intermediate_Hash[3] = 0x88da9992; 465 | context->Intermediate_Hash[4] = 0x168a5609; 466 | break; 467 | } 468 | context->Length_Low = 512; 469 | return shaSuccess; 470 | 471 | } 472 | 473 | 474 | void XKSHA1::XBOX_HMAC_SHA1(int version, UCHAR* result, ... ) 475 | { 476 | va_list args; 477 | struct SHA1Context context; 478 | va_start(args, result); 479 | 480 | HMAC1Reset(version, &context); 481 | while(1) { 482 | unsigned char *buffer = va_arg(args,unsigned char *); 483 | int length; 484 | 485 | if (buffer == NULL) break; 486 | length = va_arg(args,int); 487 | SHA1Input(&context,buffer,length); 488 | 489 | } 490 | va_end(args); 491 | 492 | SHA1Result(&context,&context.Message_Block[0]); 493 | 494 | HMAC2Reset(version, &context); 495 | 496 | SHA1Input(&context,&context.Message_Block[0],0x14); 497 | 498 | SHA1Result(&context,result); 499 | } 500 | -------------------------------------------------------------------------------- /XKSHA1.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************** 3 | ********************************** 4 | ** BROUGHT TO YOU BY: ** 5 | ********************************** 6 | ********************************** 7 | ** ** 8 | ** [TEAM ASSEMBLY] ** 9 | ** ** 10 | ** www.team-assembly.com ** 11 | ** ** 12 | ****************************************************************************************************** 13 | * This is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 | ****************************************************************************************************** 27 | 28 | 29 | ******************************************************************************************************** 30 | ** XKSHA1.H - General SHA1 and HMAC_SHA1 Class' Header 31 | ******************************************************************************************************** 32 | ** 33 | ** This is the Class Header, see the .CPP file for more comments and implementation details. 34 | ** 35 | ** This file implements the Secure Hashing Algorithm 1 as 36 | ** defined in FIPS PUB 180-1 published April 17, 1995. 37 | ** 38 | ** 39 | ** Added Funcionality to NOT require the KEY when doing HMAC_SHA1 hashes 40 | ** as per xbox-Linux groups "Fridaym 13th Middle Message Hack" 41 | ** 42 | ******************************************************************************************************** 43 | 44 | 45 | ******************************************************************************************************** 46 | ** CREDITS: 47 | ******************************************************************************************************** 48 | ** SPEEDBUMP: 49 | ** My utmost greatfullness and admiration goes towards SpeedBump for all his hard work.. 50 | ** I used most of his code and converted to C++ objects etc.. 51 | ** 52 | ** XBOX-LINUX TEAM: 53 | ** --------------- 54 | ** In particular "Franz", Wow, you guys are awsome !! I bow down to your greatness !! 55 | ** The "Friday 13th" Middle Message Hack really saved our butts !! 56 | ** REFERENCE URL: http://xbox-linux.sourceforge.net 57 | ** 58 | ******************************************************************************************************** 59 | 60 | UPDATE LOG: 61 | -------------------------------------------------------------------------------------------------------- 62 | Date: 02/18/2003 63 | By: UNDEAD [team-assembly] 64 | Reason: Prepared 0.2 for Public Release 65 | -------------------------------------------------------------------------------------------------------- 66 | Date: 01/06/2003 67 | By: UNDEAD [team-assembly] 68 | Reason: Prepared for Public Release 69 | -------------------------------------------------------------------------------------------------------- 70 | 71 | */ 72 | #pragma once 73 | #if defined (_WINDOWS) 74 | #pragma message ("Compiling for WINDOWS: " __FILE__) 75 | #include // MFC core and standard components 76 | #elif defined (_XBOX) 77 | #pragma message ("Compiling for XBOX: " __FILE__) 78 | #include 79 | #include 80 | #else 81 | // #error ERR: Have to Define _WINDOWS or _XBOX !! 82 | #include "fixme.h" 83 | #endif 84 | 85 | #define SHA1HashSize 20 86 | #define SHA1CircularShift(bits,word) \ 87 | (((word) << (bits)) | ((word) >> (32-(bits)))) 88 | 89 | class XKSHA1 90 | { 91 | struct SHA1Context 92 | { 93 | UINT32 Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ 94 | 95 | UINT32 Length_Low; /* Message length in bits */ 96 | UINT32 Length_High; /* Message length in bits */ 97 | 98 | DWORD Message_Block_Index; /* Index into message block array */ 99 | UCHAR Message_Block[64]; /* 512-bit message blocks */ 100 | 101 | int Computed; /* Is the digest computed? */ 102 | int Corrupted; /* Is the message digest corrupted? */ 103 | }; 104 | 105 | enum 106 | { 107 | shaSuccess = 0, 108 | shaNull, /* Null pointer parameter */ 109 | shaInputTooLong, /* input data too long */ 110 | shaStateError /* called Input after Result */ 111 | }; 112 | 113 | public: 114 | XKSHA1(void); 115 | ~XKSHA1(void); 116 | 117 | void HMAC_SHA1(UCHAR* result, UCHAR* key, int key_length, UCHAR* text1, int text1_length, UCHAR* text2, int text2_length); 118 | void quick_SHA1( UCHAR* SHA1_result, ... ); 119 | 120 | //Skip the Key used from eeprom.. Kudos franz@caos.at 121 | void XBOX_HMAC_SHA1(int version, UCHAR* result, ... ); 122 | 123 | private: 124 | int SHA1Reset(SHA1Context*); 125 | int SHA1Input(SHA1Context*, const UCHAR* , unsigned int); 126 | int SHA1Result(SHA1Context*, UCHAR Message_Digest[SHA1HashSize]); 127 | void SHA1ProcessMessageBlock(SHA1Context* context); 128 | void SHA1PadMessage(SHA1Context* context); 129 | 130 | //Skip the Key used from eeprom.. Kudos franz@caos.at 131 | int HMAC1Reset(int version,SHA1Context *context); 132 | int HMAC2Reset(int version,SHA1Context *context); 133 | 134 | }; 135 | 136 | -------------------------------------------------------------------------------- /fixme.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | typedef char CHAR; 12 | typedef unsigned char UCHAR; 13 | typedef uint8_t BYTE; 14 | typedef uint8_t *LPBYTE; 15 | typedef uint16_t WORD; 16 | typedef WORD *LPWORD; 17 | typedef uint16_t USHORT; 18 | typedef uint32_t DWORD; 19 | typedef uint32_t UINT32; 20 | typedef DWORD *LPDWORD; 21 | typedef int32_t LONG; 22 | typedef uint32_t ULONG; 23 | typedef int BOOL; 24 | #define FALSE 0 25 | #define TRUE (!FALSE) 26 | typedef char *LPSTR; 27 | typedef char *LPCSTR; 28 | typedef void *PVOID; 29 | typedef void *LPVOID; 30 | typedef size_t SIZE_T; 31 | typedef int32_t INT; 32 | typedef uint32_t UINT; 33 | typedef PVOID HANDLE; 34 | 35 | #define FILE_ATTRIBUTE_NORMAL 1 36 | #define FILE_SHARE_WRITE 1 37 | #define FILE_SHARE_READ 1 38 | #define GENERIC_WRITE 1 39 | #define GENERIC_READ 1 40 | #define INVALID_HANDLE_VALUE NULL 41 | #define CREATE_ALWAYS 1 42 | #define OPEN_EXISTING 1 43 | #define OPEN_ALWAYS 1 44 | #define MAX_PATH 255 45 | 46 | typedef struct _WIN32_FIND_DATA { 47 | int dummy; 48 | } WIN32_FIND_DATA; 49 | 50 | static HANDLE CreateFile(...) { assert(0); } 51 | static BOOL WriteFile(...) { assert(0); return TRUE; } 52 | static void CloseHandle(...) { assert(0); } 53 | static HANDLE FindFirstFile(...) { assert(0); return NULL; } 54 | static BOOL ReadFile(...) { assert(0); return TRUE; } 55 | static DWORD GetFileSize(...) { assert(0); return 0; } 56 | 57 | #define ZeroMemory(d,l) memset(d,0,l) 58 | #define min(x,y) ((x)<=(y)?(x):(y)) 59 | 60 | static char *strupr(char *str) 61 | { 62 | for (int i = 0; i < strlen(str); i++) 63 | str[i] = toupper(str[i]); 64 | return str; 65 | } 66 | 67 | // FIXME: Unsafe if sizeof(str) < 9! 68 | static char *itoa(int value, char *str, int base) 69 | { 70 | assert(base == 16); 71 | sprintf(str, "%x", value); 72 | return str; 73 | } 74 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | 2 | // TODO: Make this more useful. I just needed to set the MAC 3 | // address at time of writing, but there's a lot more that 4 | // could be useful. 5 | 6 | #include "XKEEPROM.h" 7 | #include 8 | #include 9 | 10 | const char *usage = "%s \n"; 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | if (argc < 2) { 15 | fprintf(stderr, usage, argv[0]); 16 | return 1; 17 | } 18 | 19 | const char *eeprom_path = argv[1]; 20 | FILE *fd = fopen(eeprom_path, "rb"); 21 | if (fd == NULL) { 22 | fprintf(stderr, "Failed to open eeprom file\n"); 23 | return 1; 24 | } 25 | 26 | fseek(fd, 0, SEEK_END); 27 | size_t eeprom_size = ftell(fd); 28 | 29 | if (eeprom_size != 256) { 30 | fprintf(stderr, "Expected 256 byte eeprem, got %zd\n", eeprom_size); 31 | return 1; 32 | } 33 | fseek(fd, 0, SEEK_SET); 34 | 35 | EEPROMDATA eeprom_data; 36 | size_t bytes_read = fread(&eeprom_data, 1, 256, fd); 37 | assert(bytes_read == eeprom_size); 38 | fclose(fd); 39 | 40 | XKEEPROM eeprom(&eeprom_data, TRUE); 41 | BOOL result = eeprom.Decrypt(); 42 | if (!result) printf("Error: failed to decrypt!\n"); 43 | 44 | char buf[64]; 45 | DWORD len; 46 | eeprom.GetMACAddressString(buf, &len); 47 | printf("MAC Address: %s\n", buf); 48 | 49 | if (argc < 3) return 0; 50 | 51 | char *new_mac = argv[2]; 52 | printf("Setting MAC address to %s\n", new_mac); 53 | eeprom.SetMACAddressString(new_mac); 54 | 55 | result = eeprom.EncryptAndCalculateCRC(); 56 | eeprom.GetEEPROMData(&eeprom_data); 57 | 58 | fd = fopen(eeprom_path, "wb"); 59 | if (fd == NULL) { 60 | fprintf(stderr, "Failed to open eeprom file\n"); 61 | return 1; 62 | } 63 | size_t bytes_written = fwrite(&eeprom_data, 1, 256, fd); 64 | assert(bytes_written == 256); 65 | fclose(fd); 66 | 67 | printf("Ok\n"); 68 | return 0; 69 | } 70 | --------------------------------------------------------------------------------