Analisi del codice statico per rilevare il passaggio di un wchar_t* a bstr
-
13-11-2019 - |
Domanda
Dal BSTR
è solo un typedef
per wchar_t*
La nostra base di codice ha diversi (molti?) luoghi in cui i letterali di stringa vengono passati a un metodo in attesa di BSTR
Questo può rovinare i marshaller o chiunque cerchi di usarne qualsiasi BSTR
Metodo specifico (ad es. SysStringLen
).
Esiste un modo per rilevare staticamente questo tipo di uso improprio?
Ho provato a compilare con VC10 /Wall
e con analisi del codice statico Microsoft tutte le regole Ma il seguente pezzo di codice offensivo non viene contrassegnato da nessuno dei due.
void foo(BSTR str)
{
std::cout << SysStringLen(str) << std::endl;
}
int _tmain()
{
foo(L"Don't do that");
}
Aggiornare: Dopo aver provato a vandalizzare wtypes.h
Nel rilevare questo tipo di trasgressioni che ho rinunciato.
Ho provato due percorsi, entrambi i quali ho potuto lavorare con il mio programma di esempio sopra, ma una volta provato un vero progetto hanno fallito.
- Crea una classe denominata
BSTR
Ma da aVARIANT
ha unBSTR
Come membro dell'Unione, la nuova classe non poteva avere costruttori o operatori di assegnazione, questo si spezzava ogni luogo eranoNULL
è stato trattato come aBSTR
. Ho provato a sostituireNULL
Con un tipo che ha operatori di conversione ma dopo aver aggiunto dozzine di nuovi operatori (confronto, conversione ecc.) Ho iniziato a imbattermi in chiamate ambigue e ho rinunciato. - Ho quindi provato la strada suggerita da @cashcow e @hans (Makeing
BSTR
untypedef
a un altro tipo di puntatore). Non ha funzionato neanche, dopo aver aggiuntotoBSTR
efromBSTR
metodi e rifiuti comutil.h (_bstr_t
) e altri luoghi con conversioni sono finalmente arrivato al punto in cui il compilatore soffocato alle intestazioni prodotte da IDLS (i valori predefiniti sono tradotti in stringhe letterali ampie).
In breve, ho rinunciato a provare a raggiungere questo obiettivo da solo, se qualcuno conosce uno strumento di analisi del codice che può aiutare sarei molto felice di sentirlo.
Soluzione
Credo Copertura afferma di rilevare questo tipo di vulnerabilità. Ricordo che avevano menzionato le cose COM in particolare quando hanno dimostrato in un'azienda per cui lavoravo.
I loro scheda dati Certamente sembra implicare che verificano le classi di uso improprio BSTR. Hanno un demo-period; Potresti provarlo e vedere se contrassegna l'input del campione.
Altri suggerimenti
Sei in grado di modificare i tuoi metodi per prendere invece _bstr_t o cccomstr?
In caso contrario, come letterale è tecnicamente un const wchar_t *, se esiste un'impostazione del compilatore per non consentire la conversione del puntatore letterale-> non contropiede, allora puoi farlo.
In caso contrario, esiste la possibilità di modificare la definizione di BSTR per essere breve senza segno *. Quindi se crei tutta la tua fonte, riceverai errori del compilatore ovunque venga trasmesso un letterale e puoi correggere tutto questo codice. Allora suggerirei di risponderlo ...
Puoi provare a compilare con Clang, le sue analisi statiche/dinamiche potrebbero trovare ciò che stai cercando.
Sovraccaricare tutte le funzioni con il BSTR e inoltrarle con la conversione appropriata.
void foo( BSTR str )
{
std::cout << SysStringLen(str) << std::endl;
}
void foo( const WCHAR *str )
{
foo( SysAllocString( str ));
}
int _tmain()
{
foo( L"don't do this" );
return 0;
}
Oppure, per generare errori del compilatore, modificare tutti i tipi di parametri da BSTR in qualcos'altro e cercare gli errori:
typedef UINT bar;
void foo( bar _str )
{
// make the compiler happy below
BSTR str = (BSTR)_str;
std::cout << SysStringLen(str) << std::endl;
}
int _tmain()
{
foo( L"don't do this" );
foo( (bar)42 );
return 0;
}
Errore C2664: 'Foo': Impossibile convertire il parametro 1 da 'const wchar_t [14] a' bar '
Suppongo che l'errore C2664 e il tipo "const wchar_t [] identificato dal compilatore sia ciò che si desidera che il compilatore trovi per ogni chiamata interna effettuata alla funzione usando il BSTR?