Impedisci l’app C # dall’uccisione del processo

Come posso proteggere la mia app C # da qualcuno che uccide il suo processo tramite taskman o programmaticamente?

Ecco il mio scenario:

L’app A è un’app MFC sviluppata da un’altra squadra. Ha un’interfaccia remota basata su testo non pubblicata abilitata tramite una backdoor.

Sto sviluppando l’app B, un’app di WinForms C # che interagisce con A. B abilita la backdoor di A quando ha bisogno di un accesso remoto per chiuderla al termine (o in caso di errore).

Sto esplorando i modi in cui gli utenti potrebbero abusare di B per ottenere l’accesso alle funzionalità nascoste di A, come uccidere il processo di B dopo aver abilitato l’interfaccia remota di A. Mi piacerebbe avere un’ultima possibilità per B di chiudere la backdoor di A quando ciò accade.

B usa localhost per interagire con A, quindi non sono preoccupato per lo scenario di spegnimento.

Sto cercando una soluzione che non implichi il cambiamento di A.

Non mi aspetto di poter fermare Dark Tangent (anche se questo sarebbe un bonus), ma in questo momento uno script kiddie potrebbe avere la sua strada con questo design 🙂

Queste app funzionano su Windows XP, ma presto supportano anche Vista e 7.

Grazie in anticipo, Jim

Non è ansible – finché l’utente ha il diritto di chiamare TerminateProcess sul proprio programma, non è ansible impedire a End Process di ucciderti immediatamente nel task manager. Raymond Chen ha postato su questo qualche tempo fa: http://blogs.msdn.com/b/oldnewthing/archive/2004/02/16/73780.aspx

Sono disposto a chiudere l’app quando provano, ma prima devo fare alcune cose.

Avere i passaggi necessari allo spegnimento del programma porta a programmi fragili che si rompono facilmente. Anche se puoi impedire a qualcuno di uccidere il tuo programma tramite il task manager, non puoi impedirgli di spegnere il computer o persino di estrarre il cavo dal muro. Qualsiasi compito che fosse così importante da completare sarà perso. E se ci fosse un’interruzione di corrente? Ancora una volta il tuo compito non verrà completato e il tuo codice di pulizia vitale non verrà eseguito.

Invece dovresti rendere il tuo programma robusto ai guasti in qualsiasi momento. Usa le transazioni e salva sempre lo stato sui file atomicamente: assicurati di avere sempre almeno una copia valida dei tuoi dati. Non sovrascrivere i file importanti in modo che diventino temporaneamente non validi.

Infine, puoi aggiungere una finestra di dialogo al tuo programma che, quando provano a chiuderla, avverte che il programma deve essere spento correttamente. Se lo spegnete velocemente, gli utenti non vorrebbero ucciderlo e lo lasceranno terminare correttamente. Se il tuo arresto richiede anni, le persone cercheranno di ucciderlo. Se sei gentile con i tuoi utenti, saranno gentili anche con te.

Se spegnendo velocemente significa che l’utente perderà del lavoro incompleto, avvisalo di questo e offri loro l’opportunità di aspettare che l’attività finisca, ma se davvero vuole uscire dal tuo programma, allora lascia che smettano.

Davvero, davvero, davvero non vuoi farlo. Rende gli utenti molto arrabbiati !! Tuttavia, se si suppone che sia un servizio, eseguirlo come account di servizio e non concedere diritti di amministratore agli utenti.

Risposta breve: non puoi e non dovresti.

Risposta lunga: puoi provare ad avviare un secondo processo di “aiuto”, che verifica ogni x secondi se la tua app è ancora in esecuzione. Se non lo è, lo riavvia.

Se si desidera che un processo venga eseguito per un lungo periodo, non fidarsi degli utenti per mantenerlo in esecuzione, prendere in considerazione i servizi di Windows. Sono progettati per questo.

Penso che tutti abbiano perso il punto. Se lo leggo correttamente (dopo la modifica) desideri sapere quando ti viene “ucciso” in modo da poter chiudere con grazia?

Il punto di “uccidere” è che tu “non puoi” fermarlo. Esistono naturalmente soluzioni alternative come l’utilizzo di una seconda app per far rivivere un’app uccisa, ma ciò non ha nulla a che vedere con il semplice fatto di poter chiudere con grazia.

L’approccio migliore consiste nell’eseguire come servizio (quindi non puoi essere ucciso, solo chiederti di chiudere), o ristrutturare il modo in cui la tua app funziona in modo che non abbia bisogno di “mettere in ordine” prima che si chiuda. Quando un’app viene chiusa, la maggior parte delle risorse in esso contenute vengono automaticamente ripulite, quindi sono solo i tuoi dati personali che devi chiudere in modo pulito. Gli approcci che potresti provare sono:

  • Registra spesso il tuo stato su disco in modo da non perdere molto (o altro) se si esce inaspettatamente. (Ricordarsi di svuotare tutti i flussi I / O per accertarsi che siano impegnati sul disco)
  • Salva le informazioni su disco che ti consentono di rilevare un arresto imprevisto al prossimo avvio del programma, in modo che sia in grado di rilevare e correggere eventuali problemi causati dall’uccisione.
  • Dì ai tuoi utenti di non essere idioti, e chiudi la tua domanda gentilmente. Colpiscili negli occhi se ti ignorano. Di solito dopo non più di due volte ascoltano 🙂

Per evitare che la tua richiesta venga chiusa, esegui l’applicazione come un altro utente (ad es. Come servizio o come un altro account utente) e limita gli utenti a essere Utente standard .

In questo modo nessun utente malintenzionato può uccidere il tuo processo, dal momento che solo gli amministratori possono ucciderlo, e questo è un privilegio che tu, apparentemente, non ti fidi di nessuno.

Ha il vantaggio di seguire il progetto previsto del sistema operativo.

@Jim

Se l’App A può ricevere richieste di modifica

  1. Preferibilmente, vorrei un’architettura in cui tutte le App B sono registrate all’apertura della backdoor e sono obbligate a eseguire il ping dell’App A con la registrazione a intervalli, in modo che l’App A possa chiudere la propria backdoor sull’App B non informandolo che ha ancora bisogno di accesso. Questo non è ancora perfettamente sicuro, ma l’App A non dovrebbe essere strutturata con una tale interfaccia senza una sorta di autoregolamentazione per i mezzi di comunicazione “sicuri”.

  2. Oppure, potresti suggerire che l’App A venga modificata per verificare processi validi e se nessuno viene trovato mentre è backdoor è aperto allora viene chiuso (questo è spoofable dal nome elaborato).

Altrimenti, sembra che l’App B dovrebbe chiudere la backdoor il più spesso ansible quando non ha bisogno di un accesso immediato.

Richiedere un’app B per garantire la sicurezza dell’accesso all’App A è davvero un modello scadente.

Per quanto ne so non puoi, e anche se tu potessi davvero non dovresti. immagina quanto sarebbe seccante se non riuscissi a forzare a uccidere un’applicazione.

Se è importante mantenere in esecuzione l’applicazione, è sempre ansible creare un servizio Windows che “ping” l’applicazione per assicurarsi che sia in esecuzione (è ansible utilizzare pipe, socket, file pid denominati … qualsiasi cosa). se il servizio rileva che il processo è morto, può semplicemente riavviarlo. questa è probabilmente la soluzione migliore.

Quando l’applicazione viene avviata per la prima volta, non è ansible eseguire un terzo ap / processo in esecuzione in background e tenta di richiamare l’app B ogni volta, quindi quando l’app B è chiusa, l’app C può vederlo ed eseguirlo una procedura per chiudere la backdoor dell’App A.

In questo modo, quando l’App B si chiude correttamente tramite il pulsante Chiudi desiderato, disabiliterà l’App C dal controllare che l’App B funzioni ancora bene …

Non sono davvero il migliore con C # al momento, ma guardando il tuo problema questo è probabilmente uno dei modi in cui proverei a farlo ..

Inoltre, se l’App B controlla anche l’App C, se l’App C è stata distriggersta, l’App B chiuderà la backdoor se ansible.

Come dicono gli altri, questa potrebbe non essere una buona idea.