diff -urpN 179-b/src/dynamic_fmt.c 179-a/src/dynamic_fmt.c
--- 179-b/src/dynamic_fmt.c	2011-12-12 14:48:42.218750000 +0000
+++ 179-a/src/dynamic_fmt.c	2011-12-12 19:10:38.203125000 +0000
@@ -593,6 +593,29 @@ static private_subformat_data curdat;
  * john will call valid on EACH of those formats, asking each one if a string is
  * valid. Each format has a 'private' properly setup data object.
  *********************************************************************************/
+static int HEX_valid(char *Hex) {
+	// Ok, we validate any '$HEX$hex_value string.
+	// we validate this:
+	//   1. all valid hex chars (case does not matter).
+	//   2. must be an even number of hex chars.
+	//   3. byte following MUST be null or '$'.
+	// if valid, we return the length of the data, AFTER hex-to-binary conversion (i.e. the real data length).
+	// if not valid, we return -1
+	int len;
+
+	if (strncmp(Hex, "HEX$", 4))
+		return -1;
+	Hex += 4;
+	for (len = 0; ;++len, Hex+=2) {
+		if (atoi16[(unsigned char)Hex[0]] == 0x7f) {
+			if ((unsigned char)Hex[0] == '$' || !Hex[0])
+				return len;
+			return -1;
+		}
+		if (atoi16[(unsigned char)Hex[1]] == 0x7f)
+			return -1; // odd length
+	}
+}
 static int valid(char *ciphertext, struct fmt_main *pFmt)
 {
 	int i, cipherTextLen;
@@ -657,10 +680,7 @@ static int valid(char *ciphertext, struc
 		cipherTextLen = 40;
 	}
 	for (i = 0; i < cipherTextLen; i++){
-		if (!(  (('0' <= cp[i])&&(cp[i] <= '9')) ||
-			 	(('a' <= cp[i])&&(cp[i] <= 'f')) ||
-				(('A' <= cp[i])&&(cp[i] <= 'F'))
-			))
+		if (atoi16[(unsigned char)cp[i]] == 0x7f)
 			return 0;
 	}
 	if (cp[cipherTextLen] && cp[cipherTextLen] != '$')
@@ -673,11 +693,8 @@ static int valid(char *ciphertext, struc
 			// do another check, just in case there is a HEX$ type salt.
 			if (strncmp(&ciphertext[pPriv->dynamic_SALT_OFFSET], "HEX$", 4) == 0) {
 				// Ok, we do have a HEX.  We now want to compute it's length.
-				if (strlen(&ciphertext[pPriv->dynamic_SALT_OFFSET+4]) == pPriv->dynamic_FIXED_SALT_SIZE*2) {
-					// Ok, check for salt-2, username, etc.
-				} else if (strncmp(&ciphertext[pPriv->dynamic_SALT_OFFSET+pPriv->dynamic_FIXED_SALT_SIZE*2+4], "$$", 2)) {
-			return 0;
-	}
+				if (HEX_valid(&ciphertext[pPriv->dynamic_SALT_OFFSET]) != pPriv->dynamic_FIXED_SALT_SIZE)
+					return 0;
 			} else
 				return 0;
 		}
@@ -686,19 +703,8 @@ static int valid(char *ciphertext, struc
 		// check if there is a 'salt-2' or 'username', etc  If that is the case, then this is still 'valid'
 		char *cpX;
 		if (strncmp(&ciphertext[pPriv->dynamic_SALT_OFFSET], "HEX$", 4) == 0) {
-			if (strlen(&ciphertext[pPriv->dynamic_SALT_OFFSET+4]) <= -(pPriv->dynamic_FIXED_SALT_SIZE*2)) {
-				// ok  We are only 'overlength', due to HEX$hexsalt being longer due to be 2x+4 because 1 byte becomes 2.
-				// Once we convert FROM the external HEX$ format, to binary format, it will be <= the max salt size, and
-				// thus this salt is 'safe' for this format.
-			} else {
-				cpX = mem_alloc(-(pPriv->dynamic_FIXED_SALT_SIZE*2) + 3);
-				strnzcpy(cpX, &ciphertext[pPriv->dynamic_SALT_OFFSET], -(pPriv->dynamic_FIXED_SALT_SIZE*2) + 3);
-				if (!strstr(cpX, "$$")) {
-					MEM_FREE(cpX);
-					return 0;
-				}
-				MEM_FREE(cpX);
-			}
+			if (HEX_valid(&ciphertext[pPriv->dynamic_SALT_OFFSET]) > -pPriv->dynamic_FIXED_SALT_SIZE)
+				return 0;
 		} else {
 			cpX = mem_alloc(-(pPriv->dynamic_FIXED_SALT_SIZE) + 3);
 		strnzcpy(cpX, &ciphertext[pPriv->dynamic_SALT_OFFSET], -(pPriv->dynamic_FIXED_SALT_SIZE) + 3);
@@ -720,6 +726,15 @@ static int valid(char *ciphertext, struc
 			return 0;
 	}
 
+	// Search for HEX$ and validate all of them.
+	cp = strstr(ciphertext, "$HEX$");
+	while (cp) {
+		++cp;
+		if (HEX_valid(cp) < 1)
+			return 0;
+		cp = strstr(cp, "$HEX$");
+	}
+
 	return 1;
 }
 
@@ -1629,7 +1644,7 @@ static unsigned char *FindSaltHash(unsig
 	return AddSaltHash(salt, len, idx);
 }
 static unsigned char *HashSalt(unsigned char *salt, unsigned len) {
-	u32 crc = -1, i;
+	u32 crc = 0xffffffff, i;
 	unsigned char *ret_hash;
 
 	// compute the hash.
@@ -1659,7 +1674,7 @@ static int ConvertFromHex(unsigned char
 static unsigned salt_external_to_internal_convert(unsigned char *extern_salt, unsigned char *Buffer) {
 	// Ok, we get this:   extern_salt = salt_data$$2salt2$$Uuser ...  where anything can be missing or in any order
 	// the any order has 1 exception of salt_data MUST be first.  So if we get $$2salt2, then we know there is no salt-1 value.
-	unsigned char *salt2, *userid, *Flds[10];
+	unsigned char *salt2=0, *userid=0, *Flds[10];
 	int nsalt2=0, nuserid=0, nFlds[10]={0,0,0,0,0,0,0,0,0,0};
 	unsigned char len = strlen((char*)extern_salt), i, bit;
 	unsigned bit_array=0;
@@ -7094,16 +7109,9 @@ int dynamic_SETUP(DYNAMIC_Setup *Setup,
 static int LoadOneFormat(int idx, struct fmt_main *pFmt)
 {
 	extern struct options_main options;
-	char label[40], label_id[40];
+	char label[16], label_id[16], *cp;
 	memcpy(pFmt, &fmt_Dynamic, sizeof(struct fmt_main));
 	dynamic_RESET(pFmt);
-	sprintf(label, "$dynamic_%d$", idx);
-	sprintf(label_id, "dynamic_%d", idx);
-
-	if (!options.format || strncmp(options.format, "dynamic_", 8))
-		pFmt->params.label = str_alloc_copy("dynamic");
-	else
-		pFmt->params.label = str_alloc_copy(label_id);
 
 	if (idx < 1000) {
 		if (dynamic_RESERVED_PRELOAD_SETUP(idx, pFmt) != 1)
@@ -7114,6 +7122,21 @@ static int LoadOneFormat(int idx, struct
 			return 0;
 	}
 
+	/* we 'have' to take the sig from the test array.  If we do not have */
+	/* our preload array 'solid', then the idx will not be the proper */
+	/* number.  So we simply grab the label from the test cyphertext string */
+	strncpy(label, pFmt->params.tests[0].ciphertext, 15);
+	cp = strchr(&label[1], '$');
+	cp[1] = 0;
+	strcpy(label_id, &label[1]);
+	cp = strchr(label_id, '$');
+	*cp = 0;
+
+	if (!options.format || strncmp(options.format, "dynamic_", 8))
+		pFmt->params.label = str_alloc_copy("dynamic");
+	else
+		pFmt->params.label = str_alloc_copy(label_id);
+
 	strcpy(curdat.dynamic_WHICH_TYPE_SIG, label);
 
 	curdat.dynamic_HASH_OFFSET = strlen(label);
diff -urpN 179-b/src/dynamic_preloads.c 179-a/src/dynamic_preloads.c
--- 179-b/src/dynamic_preloads.c	2011-12-02 16:48:52.578125000 +0000
+++ 179-a/src/dynamic_preloads.c	2011-12-12 19:10:59.375000000 +0000
@@ -795,8 +795,10 @@ static DYNAMIC_Setup Setups[] =
 	{ "dynamic_24: sha1($p.$s)",                  _Funcs_24,_Preloads_24,_ConstDefault, MGF_SALTED|MGF_SHA1_40_BYTE_FINISH, MGF_NO_FLAG, -24, 32 },
 	{ "dynamic_25: sha1($s.$p)",                  _Funcs_25,_Preloads_25,_ConstDefault, MGF_SALTED|MGF_SHA1_40_BYTE_FINISH, MGF_NO_FLAG, -24, 32 },
 	{ "dynamic_26: sha1($p) raw-sha1",            _Funcs_26,_Preloads_26,_ConstDefault, MGF_SHA1_40_BYTE_FINISH, MGF_RAW_SHA1_INPUT },
+#if ARCH_LITTLE_ENDIAN
 	{ "dynamic_27: FreeBSD MD5",                  _Funcs_27,_Preloads_27,_Const_27,     MGF_SALTED|MGF_INPBASE64a|MGF_StartInX86Mode, MGF_FreeBSDMD5Setup, 0, 15 },
 	{ "dynamic_28: Apache MD5",                   _Funcs_28,_Preloads_28,_Const_28,     MGF_SALTED|MGF_INPBASE64a|MGF_StartInX86Mode, MGF_FreeBSDMD5Setup, 0, 15 },
+#endif
 #if defined (MMX_COEF)
 	{ "dynamic_29: md5(unicode($p))",             _Funcs_29,_Preloads_29,_ConstDefault, MGF_UTF8, MGF_NO_FLAG, 0, 27 } // if we are in utf8 mode, we triple this in the init() call
 #else
@@ -813,11 +815,23 @@ char *dynamic_PRELOAD_SIGNATURE(int cnt)
 
 int dynamic_RESERVED_PRELOAD_SETUP(int cnt, struct fmt_main *pFmt)
 {
+	char Type[20];
+	sprintf(Type, "dynamic_%d", cnt);
 	if (cnt < 0 || cnt > 1000)
 		return 0;
-	if (cnt >= ARRAY_COUNT(Setups))
+	if (cnt >= ARRAY_COUNT(Setups)) {
+		int j,len, bGood=0;
+		len=strlen(Type);
+		for (j = 0; j < ARRAY_COUNT(Setups); ++j) {
+			if (!strncmp(Type, Setups[j].szFORMAT_NAME, len)) {
+				bGood = 1;
+				break;
+			}
+		}
+		if (!bGood)
 		return 0;
-
+		return dynamic_SETUP(&Setups[j], pFmt);
+	}
 	return dynamic_SETUP(&Setups[cnt], pFmt);
 }
 
@@ -826,10 +840,19 @@ int dynamic_RESERVED_PRELOAD_SETUP(int c
 // 1 is valid.
 int dynamic_IS_VALID(int i)
 {
+	char Type[20];
+	sprintf(Type, "dynamic_%d", i);
 	if (i < 0 || (i > 100 && i < 1000) || i > 2000)
 		return -1;
-	if (i < 1000 && i >= ARRAY_COUNT(Setups))
+	if (i < 1000 && i >= ARRAY_COUNT(Setups)) {
+		int j,len;
+		len=strlen(Type);
+		for (j = 0; j < ARRAY_COUNT(Setups); ++j) {
+			if (!strncmp(Type, Setups[j].szFORMAT_NAME, len))
+				return 1;
+		}
 		return -1;
+	}
 	if (i >= 1000) {
 		if (!dynamic_IS_PARSER_VALID(i))
 			return 0;
