#include #include #include // this program searches for the seed used to generate a given sequence of pseudo random numbers // as usually generated by HTC bootloaders to fill sdcard headers, or CID blocks // typedef std::vector ByteVector; #define RNG(seed) ((unsigned char)((seed)>>16)) bool testseed(unsigned long seed, const unsigned char *buf, int size) { while (size--) { if (*buf++ != RNG(seed)) return false; seed = 2531011+214013*seed; } return true; } bool dumpseed(unsigned long seed, int size) { printf(" "); for (int i=1 ; i<=size ; i++) { if ((i&31)==0) printf("\n"); printf("%02x", RNG(seed)); seed = 2531011+214013*seed; } printf("\n"); return true; } bool findseed(const unsigned char *buf, int size) { unsigned long seed= 0; const unsigned char *p=buf; const unsigned char *end= buf+size; unsigned char c0= buf[0]; unsigned long seedhist[256]; int seedidx=0; while (1) { seed = 2531011+214013*seed; seedhist[seedidx++]= seed; if (seedidx==256) seedidx=0; if (RNG(seed)==c0) { if (testseed(seed, buf, size)) break; } if (seed==0) return false; } printf("found seed: %08lx ( -256: %08lx )\n", seed, seedhist[seedidx]); dumpseed(seedhist[seedidx], 512); return true; } int c2nyb(char c) { if (c>='0' && c<='9') return c-'0'; if (c>='a' && c<='f') return c-'a'+10; if (c>='A' && c<='F') return c-'A'+10; return -1; } int cvhex2bytes(unsigned char *buf, int bufsize, char *hex) { int nyb[2]; int i=0; int nbytes=0; while (*hex) { nyb[i]= c2nyb(*hex++); if (nyb[i]>=0) i++; if (i>1) { *buf++ = (nyb[0]<<4) | nyb[1]; nbytes++; if (nbytes>=bufsize) break; i=0; } } return nbytes; } int main(int argc, char **argv) { ByteVector data; int i; for (i=1 ; i