static RBOOL _longestString ( RPCHAR begin, RU32 max, RU32* toSkip, RU32* longestLength, RBOOL* isUnicode ) { RBOOL isSuccess = FALSE; RU32 size = 0; RWCHAR unicodeLow = 0xFF; RWCHAR unicodeHigh = ( (RWCHAR)( -1 ) ^ 0xFF ); RPWCHAR possibleChar = NULL; RU32 nSpecialChar = 0; if( NULL != begin && NULL != toSkip && NULL != longestLength && NULL != isUnicode ) { *longestLength = 0; *toSkip = 0; for( size = 0; size < max; size++ ) { if( 0 == begin[ size ] ) { break; } else if( !rpal_string_charIsAscii( begin[ size ] ) || size == max - 1 ) { // We're only looking for clean C NULL-terminated strings *toSkip = size + 1; return FALSE; } else if( rpal_string_charIsAscii( begin[ size ] ) && !rpal_string_charIsAlphaNum( begin[ size ] ) ) { nSpecialChar++; if( nSpecialChar > _MAX_SAMPLE_SPECIAL_CHAR ) { // Too many special characters, may be binary data *toSkip = size + 1; return FALSE; } } } if( 1 == size ) { // This looks like it might be the first character of a unicode // string. So let's look for one. *isUnicode = TRUE; for( size = 0; size < max; size += sizeof( RWCHAR ) ) { possibleChar = (RPWCHAR)( begin + size ); if( 0 == *possibleChar ) { break; } else { if( !rpal_string_charIsAscii( (RCHAR)( *possibleChar & unicodeLow ) ) || 0 != ( *possibleChar & unicodeHigh ) || size == max - sizeof( RWCHAR ) ) { *toSkip = size + 1; return FALSE; } } } } *longestLength = size + 1; *toSkip = *longestLength; isSuccess = TRUE; } return isSuccess; }
RPRIVATE RVOID _searchForStrings ( rList stringsFound, rList searchStrings, RPU8 pBuff, RU64 size, RU64 baseAddr, RU32 minLength, RU32 maxLength ) { RPU8 pCurr; RPU8 pEnd; RPCHAR pStartStr = NULL; RBOOL isChar; RPU16 pwCurr; RPU16 pwEnd; RBOOL isWChar; RPWCHAR pwStartStr = NULL; RPWCHAR thisStrW = NULL; rSequence newFoundStr; pCurr = pBuff; pEnd = pBuff + size; // currently we only deal with NULL terminated strings // start with ascii strings... while( pCurr < pEnd ) { isChar = rpal_string_isprint( *pCurr ); if( NULL == pStartStr && isChar ) // found the begining of a string { pStartStr = (RPCHAR)pCurr; } else if( NULL != pStartStr && ( !isChar || 0 == *pCurr ) ) // found the end of a string { // is string NULL or Non-Ascii terminated if( 0 == *pCurr || !rpal_string_charIsAscii( *pCurr ) ) { // Null terminate it so we can use it like a normal string *pCurr = 0; // strlen is really pCurr - pStartStr if( (RU32)( (RPCHAR)pCurr - pStartStr ) >= minLength && (RU32)( (RPCHAR)pCurr - pStartStr ) <= maxLength ) // is string long enough { // convert string to wide char for comparision if( NULL != ( thisStrW = rpal_string_atow( pStartStr ) ) ) { if( _isStringInList( searchStrings, thisStrW ) && NULL != ( newFoundStr = rSequence_new() ) ) { rSequence_addSTRINGW( newFoundStr, RP_TAGS_STRING, thisStrW ); rSequence_addRU64( newFoundStr, RP_TAGS_MEMORY_ADDRESS, baseAddr + ( (RPU8)pStartStr - pBuff ) ); if( !rList_addSEQUENCE( stringsFound, newFoundStr ) ) { rSequence_free( newFoundStr ); } } rpal_memory_free( thisStrW ); } } } pStartStr = NULL; } pCurr++; } // Now look for Unicode strings pwCurr = (RPU16)pBuff; pwEnd = pwCurr + ( size / 2 ); while( pwCurr < pwEnd ) { isWChar = rpal_string_isprintW( *pwCurr ); if( NULL == pwStartStr && isWChar ) // found the begining of a string { pwStartStr = (RPWCHAR)pwCurr; } else if( NULL != pwStartStr && ( !isWChar || 0 == *pwCurr ) ) // found the end of a string { // is string NULL terminated if( 0 == *pwCurr ) { // wcslen is really pCurr - pStartStr if( (RU32)( (RPWCHAR)pwCurr - pwStartStr ) >= minLength && (RU32)( (RPWCHAR)pwCurr - pwStartStr ) <= maxLength ) // is string long enough { if( _isStringInList( searchStrings, pwStartStr ) && NULL != ( newFoundStr = rSequence_new() ) ) { rSequence_addSTRINGW( newFoundStr, RP_TAGS_STRING, pwStartStr ); rSequence_addRU64( newFoundStr, RP_TAGS_MEMORY_ADDRESS, baseAddr + ( (RPU8)pwStartStr - pBuff ) ); if( !rList_addSEQUENCE( stringsFound, newFoundStr ) ) { rSequence_free( newFoundStr ); } } } } pwStartStr = NULL; } pwCurr++; } }