/* (C) 2003 XDA Developers itsme@xs4all.nl * * unlock code by job@itsx.com * * $Header: /var/lib/cvs/xdautils/xda2dmp/xda2unlockcode.cpp,v 1.1 2004/01/11 20:05:11 itsme Exp $ */ #include #include "stdio.h" #include "args.h" #include "debug.h" #include "stringutils.h" #include "vectorutils.h" #include #include #include "crc32.h" std::string g_device; int g_verbose= 0; DWORD g_rd_memblock_per_read=1024; DWORD g_rd_memblock_per_cmd= 128; size_t findstring(const ByteVector& buf, const std::string& str); HANDLE OpenComport(const std::string& portname); bool SetCommParams(HANDLE hPort, int speed, int bits, int parity, int stopbits); bool WriteCommand(HANDLE hPort, const std::string& command); bool WriteData(HANDLE hPort, int nChars, ...); bool ReadData(HANDLE hPort, ByteVector& buffer, int bufsize); bool SendCommand(HANDLE hPort, int nChars, ...); DWORD CalcUnlockCode(DWORD L1, DWORD L2); bool TryUnlock(HANDLE hPort, DWORD offset); void usage() { printf("Usage: xda2unlockcode [options]\n"); printf("Options:\n"); printf(" -d DEVNAME : connect through specified device (default: USB)\n"); printf(" -c : connect through Serial device (COM1)\n"); printf(" -u : connect through Serial device (\\\\.\\WCEUSBSH001)\n"); printf(" -v[v...] : be verbose[r]\n"); printf(" -br SIZE : read buffer size\n"); printf(" -bc SIZE : max bytes per command\n"); } int main(int argc, char **argv) { DebugStdOut(); int argsfound=0; DWORD dwOffset=0; DWORD dwLength=0; bool bUseUsbDevice= true; for (int i=1 ; i1) printf("read start: %d bytes\n", readbuffer.size()); if (g_verbose>2) printf("..........\n%s\n", ascdump(readbuffer).c_str()); htcs_offset= findstring(readbuffer, "HTCS"); if (htcs_offset!=readbuffer.size()) break; if (g_verbose>1) printf("pre-data: %s\n", ascdump(readbuffer).c_str()); } htcs_offset += 4; if (g_verbose>1) printf("last pre-data: %s\n", ascdump(ByteVector(readbuffer.begin(), readbuffer.begin()+htcs_offset)).c_str()); DWORD nTotal= min(readbuffer.size()-htcs_offset, dwLength); buffer.resize(nTotal); if (nTotal) std::copy(readbuffer.begin()+htcs_offset, readbuffer.begin()+htcs_offset+nTotal, buffer.begin()); size_t unreadptr= htcs_offset+nTotal; if (g_verbose>2) printf("read %d bytes, still %d to go, or %d left\n", nTotal, dwLength-nTotal, readbuffer.size()-unreadptr); // copy rest of binary data while (buffer.size() < dwLength) { if (!ReadData(hPort, readbuffer, g_rd_memblock_per_read)) return false; if (g_verbose>1) printf("read bin: %d bytes\n", readbuffer.size()); if (g_verbose>2) printf("..........\n%s\n", hexdump(readbuffer).c_str()); DWORD nValid= min(readbuffer.size(), dwLength-nTotal); DWORD nBufEnd= buffer.size(); buffer.resize(buffer.size()+nValid); if (nValid) std::copy(readbuffer.begin(), readbuffer.begin()+nValid, buffer.begin()+nBufEnd); unreadptr= nValid; nTotal += nValid; } if (g_verbose>0) printf("%d bytes binary data\n", nTotal); if (g_verbose>2) printf("read %d bytes, %d left\n", nTotal, readbuffer.size()-unreadptr); if (readbuffer.size()-unreadptr < 8) { if (g_verbose>1) printf("only %d bytes of extra data\n", readbuffer.size()-unreadptr); ByteVector readextra; if (!ReadData(hPort, readextra, 8)) return false; std::copy(readextra.begin(), readextra.end(), readbuffer.end()); } if (g_verbose>1) printf("post-data: %s\n", ascdump(ByteVector(readbuffer.begin()+unreadptr, readbuffer.end())).c_str()); DWORD crc= *(DWORD*)(vectorptr(readbuffer)+unreadptr); DWORD calccrc= calccrc32(buffer); if (crc!=calccrc) { printf("!!! received crc= %08lx calced crc= %08lx\n", crc, calccrc); //return false; } return true; } HANDLE OpenComport(const std::string& portname) { return CreateFile (portname.c_str(), GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, 0, NULL); } bool SetCommParams(HANDLE hPort, int speed, int bits, int parity, int stopbits) { SetupComm(hPort, 0x8000, 0x8000); DCB dcb; dcb.DCBlength= sizeof(DCB); if (!GetCommState (hPort, &dcb)) return FALSE; dcb.BaudRate= speed; dcb.ByteSize= bits; dcb.Parity= parity; dcb.StopBits= stopbits; dcb.fOutxCtsFlow= 0; dcb.fDtrControl= DTR_CONTROL_ENABLE; dcb.fRtsControl= 0; dcb.fAbortOnError= 0; if (!SetCommState (hPort, &dcb)) return FALSE; COMMTIMEOUTS to; if (!GetCommTimeouts(hPort, &to)) return FALSE; to.ReadIntervalTimeout = 0; to.ReadTotalTimeoutMultiplier = 0; to.ReadTotalTimeoutConstant = 200; to.WriteTotalTimeoutMultiplier = 0; to.WriteTotalTimeoutConstant = 20000; if (!SetCommTimeouts(hPort, &to)) return FALSE; SetCommMask(hPort, EV_RXCHAR); return TRUE; } bool vWriteData(HANDLE hPort, int nChars, va_list ap); bool WriteData(HANDLE hPort, int nChars, ...) { va_list ap; va_start(ap, nChars); bool res= vWriteData(hPort, nChars, ap) ; va_end(ap); return res; } bool vWriteData(HANDLE hPort, int nChars, va_list ap) { for (int i=0 ; i=0) { BYTE c= (BYTE)arg; if (!WriteFile(hPort, &c, 1, &nWritten, NULL)) { error("error writing char %02x", c); return FALSE; } if (nWritten!=1) { debug("did not write char %02x", c); return FALSE; } } else { char* p= (char*)arg; if (!WriteFile(hPort, p, strlen(p), &nWritten, NULL)) { error("error writing char %hs", p); return FALSE; } if (nWritten!=strlen(p)) { debug("did not write %d chars of %hs", strlen(p)-nWritten, p); return FALSE; } if (g_verbose>0) printf("SENT: %s\n", p); } } return TRUE; } bool ReadData(HANDLE hPort, ByteVector& buffer, int bufsize) { buffer.resize(bufsize); DWORD nTotal= 0; while (nTotal0) printf("%s\n", ascdump(buffer).c_str()); return true; } size_t findstring(const ByteVector& buf, const std::string& str) { for (int i= 0 ; i> count) | (value << rem)); } DWORD CalcUnlockCode(DWORD L1, DWORD L2) { unsigned long val, val2, val3, val4, val5, Rev1, Rev2; Rev1 = L1 ^ 0x07D0039F; Rev2 = L2 ^ 0x00E0A060; val = 0xFF000000 & Rev2; val2 = 0xF0 & Rev2; val3 =(val >> 4) & 0x0F000000; val = val << 4; val2 = val2 << 0x10; val = val | val2 | val3; val4 = Rev2 &0xF00000; val4 = val4 << 8; val = val | val4; val2 = Rev1 & 0xF0; val3 = Rev1 & 0xF; val = val | (val3 << 4) | (val2 >> 4); val2 = Rev1 & 0xF0000; val = val | (val2 >> 8); val2 = Rev1 & 0xF000000; val = val | (val2 >> 0xC); val2 = Rev1 & 0xF000; val = val | (val2 << 4); val = ror(val, 3); val2 = val & 0xFF; // CC val3 = (val >> 8) & 0xFF; //AA val4 = (val >> 16) & 0xFF; //DD val5 = (val >> 24) & 0xFF; //BB val = (val3 << 24) | (val5 << 16) | (val2 << 8) | val4; val = ror(val, 0x1E); return val; } bool TryUnlock(HANDLE hPort, DWORD offset) { ByteVector buf; DWORD L[2]; if (!ReadMemoryBlock(hPort, buf, offset, 8, true)) { printf("error reading from %08lx\n", offset); return false; } memcpy((BYTE*)L, vectorptr(buf), 8); if (L[0]==0xffffffff && L[1]==0xffffffff) return false; printf("unlockcode = %08lx\n", CalcUnlockCode(L[0], L[1])); return true; }