Erkennen, ob ein Spiel gestartet ist

  • C#
  • .NET 4.5

Es gibt 38 Antworten in diesem Thema. Der letzte Beitrag () ist von nafets.

    Am besten ist, du startest es wie ein Anti-Virus mit Systemrechten, sodass es schon läuft, bevor die Windows-Anmeldung läuft. Dann kann er die EXE auch nicht mit dem Taskmanager / Taskkill beenden, und wenn du sie dann noch mit den dir gegebenen Features von NTFS sicherst, kann er die EXE nicht man über eine Linux-Distri löschen, ähnlich wie der Ordner ​SystemVolumeInformation.
    Mein Gedanke war, dass ich verschiedene Optionen zum Schutz mache. 1: Gar keinen, man hat sogar ein Kontextmenü, über welches man das Programm beenden kann, 2: Man hat kein Kontextmenü, 3: RtlSetProcessIsCritical (das bewirkt, dass bei dem Beenden des Programms ein Bluescreen ausgelöst wird, das macht man kein zweites mal). Generell sollte sowas meiner Meinung nach eher kooperativ eingesetzt werden, d. h. dass beide Seiten d'accord sind. 100 %ig sicher werde ich das sowieso nicht hinbekommen, die Daten müssen ja auch irgendwo gespeichert werden, das kann man relativ leicht verfälschen (zumindest würden das die meisten von euch mit etwas Zeit hinbekommen, ist eine Passwortgeschützt SQL-Datenbank und das Passwort steht etwas verschleiert im Code).

    Zu den Jump & Run Games oder generell zu allen Spielen, die im Fenstermodus laufen: Erstmal würde ich nicht davon ausgehen, dass man sowas extrem viel zocken kann (vielleicht mal ne halbe Stunde, mehr aber auch nicht). Wenn das zum Problem werden sollte, habe ich in der Administration eine Funktion eingebaut, welche den Status von den Prozessen verändern kann:


    Man könnte das aber natürlich auch als Service machen. Mal schauen :)
    Mfg
    Vincent

    Dann kann ich aber immer noch per Linux (wenn man keine Administrator-Rechte besitzt) die Registry ändern und die entsprechende Anwendung "entführen" und stattdessen einfach z.B notepad starten.


    Ob das auch bei Diensten funktioniert weiß ich nicht. Kann ich derzeit nicht austesten. ;)
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Meines Erachtens kann man per Linux problemlos Dateien austauschen/löschen/editieren. Die Variante, die @ichduersie angesprochen hat, fände ich
    mal echt interessant.

    Oder du installierst auf seinem PC ein Rootkit, welches deine Anwendung einfach vor jeglichen API-Calls versteckt :D
    Das fände ich sogar noch cooler.

    MfG Tim
    Einfacher wäre es imo, die Zeiten zu denen das Programm läuft zu loggen. Wenn es dann mit irgendeinem Trick beendet wird, kann man das im Nachhinein nachvollziehen.
    Okay, folgendes:
    Habe gerade zwei Stunden mit dem Service rumprobiert bis mir irgendwann aufgefallen ist, dass ich mit dem Service gar nicht die Hooks registrieren kann (1. kann ein Dienst normalerweise keine Events empfangen (das gleiche wie bei einer Konsolenanwendung) und 2. hat der Dienst keinen Zugriff auf den Hook, weil dieser mit dem Desktop zusammenhängt).

    Es gab irgendwann mal eine Anwendung, welche einen andere Anwendung getarnt hat (auch durch Rootkits). Hatte SemperVideo mal vorgestellt (heißt HackerDefender, ist aber nutzlos, weil alle AntiVirusprogramme das sofort erkennen).

    @nafets
    Gute Idee. Wo finde ich eigentlich einen Windows-Log, in dem drin steht, wann Windows gestartet war? Ich weiß, dass es einen Registry-Eintrag gibt, in dem steht, wann Windows das letzte Mal heruntergefahren wurde, aber eine Liste kenne ich nicht...
    Mfg
    Vincent

    Im Event-Log "Microsoft-Windows-Diagnostics-Performance" sind alle Warnungen mit der Event-ID 100 die Startups, 200 sind die Shutdowns.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nafets“ ()

    Über CMD bekommt man das über systeminfo oder direkt systeminfo | findstr "Up Time" auf deutschen Systemen soweit ich weiß mit
    systeminfo | findstr "Systemstartzeit" heraus. Aber das willst du bestimmt nicht so regeln. Hier n Snippet.
    Ich hab mal das Snippet getestet. Man hat eben nicht die "Systemstartzeit" aber dafür die "Systembetriebszeit".

    MfG Tim

    VincentTB schrieb:

    Wo finde ich eigentlich einen Windows-Log, in dem drin steht, wann Windows gestartet war?

    Willst du das in der Anwendung auslesen oder manuell?
    Kannst ja das hier versuchen: msdn.microsoft.com/library/windows/desktop/ms724411.aspx

    BTW: @Fortender Wenn in Windows die Schnellstart Funktion aktiviert ist setzt sich die Systemstartzeit nicht zurück (wird woll dann auch bei deinem Snippet und bei GetTickCount64 so sein)
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „KaskadekingDE“ ()

    Hab ich auch gerade gemerkt, da ein Kollege meinte, der Taskmanager zeigt ihm eine Betriebszeit von 4 Tagen an. Er schließ darauf, dass es die ingesamte Systembetriebszeit sei.
    Meine war aber völlig normal. Dass mein PC insgesamt nicht nur eine Stunde gelaufen ist, war uns dann auch klar...
    q.e.d :thumbsup:
    @nafets
    Könntest du das vielleicht etwas genauer beschreiben. Hab gerade mal in die Ereignisanzeige geguckt, da bin ich nicht fündig geworden.

    @Fortender & @KaskadekingDE
    Aber beide Methoden von euch lesen doch nur die letzte Startup Zeit aus. Ich hätte einfach gerne eine Liste, wann Windows gestartet und heruntergefahren wurde. Es kann ja auch passieren, dass das Programm über mehrere Startups deaktiviert wurde. Übrigends stellt das .Net Framework auch direkt eine Methode bereit, heißt Environment.TickCount​ ;)
    Mfg
    Vincent

    Für was brauchst du diese Zeiten eigentlich? Man kann ja dann auch nicht unterscheiden ob der PC aus war, weil er z.b. schlafen gegangen ist, oder ob
    er nur neugestartet hat. Dann müsste man ja noch die Zeiträume Herunterfahren<->Hochfahren analysieren. Oder du rechnest die SystemUpTime pro Tag, nur das ist ebenfalls
    blöd, da dann ab 0 Uhr immer abgeschnitten wird. Man kann sich jetzt denken gut ok, die Session wird nicht abgeschnitten wenn sie über 0 Uhr hinausgeht, aber was ist wenn ein Neustart getätigt
    wird. Dann wären wir wieder beim Anfangsproblem.

    @KaskadekingDE Was passiert dann eigentlich? In .Net würde eine OverflowException gethrowt werden, aber wenn Environment.TickCount gecallt wird?
    Wie handlet das System das?
    Hmm, simulieren kann man das wohl auch grad nicht so gut :D
    @Fortender


    Es wird keine Overflow geworfen, sondern es geht einfach nur ins Minus. Siehe hier unter Hinweis

    Die Idee war, dass das Programm die Start-und Endzeiten ebenfalls loggt und dann mit dem System vergleicht. Da kommt ein weiteres Problem: Angenommen, das System stürzt ab. Im Eventlog wird das wohl stehen, aber meine Anwendung weiß das ja nicht.

    Deshalb brauchte ich übrigens schon mal die Shutdown Zeit des Systems. Wenn das System abstürzt und wieder startet, hat mein Programm dann eine Zeit angefangen, welche nicht beendet wird. Dies wird erkannt und es wird als Ende einfach die Shutdown Zeit verwendet.
    Mfg
    Vincent

    Das hier listet alle im Windows-EventLog aufgezeichneten Startups und Shutdowns auf (ich nutze jetzt anstelle des vorgeschlagenen Performance-Logs zur Vereinfachung den System-Log):

    C#-Quellcode

    1. #pragma warning disable CS0618 //EventID ist als obsolet gekennzeichnet, die Alternative InstanceId gibt bei mir jedoch aus irgendeinem Grund andere IDs. Deswegen unterdrücke ich einfach die Warnung
    2. Dictionary<int, List<EventLogEntry>> eventsByInstanceId = new EventLog() { Log = "System" }.Entries.OfType<EventLogEntry>().GroupBy(entry => entry.EventID).OrderBy(group => group.Key).ToDictionary(group => group.Key, group => group.ToList()); //Ziemlich langer Spaghetti-Code, ordnet alle Entries nach deren ID in einem Dictionary (das OrderBy kann man weg lassen, ich finde es jedoch beim Debuggen angenehmer)
    3. foreach(EventLogEntry entry in eventsByInstanceId[6005].Concat(eventsByInstanceId[6006]).OrderBy(entry => entry.TimeGenerated)) //Die relevanten Entries finden und nach Zeit ordnen (6005: Startup, 6006: Shutdown)
    4. {
    5. Console.WriteLine("{0} at {1}", entry.EventID == 6005 ? "Startup" : "Shutdown", entry.TimeGenerated); //Ergebnis in einer Konsole ausgeben
    6. }
    7. #pragma warning restore CS0618

    Grüße
    Stefan

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nafets“ ()

    Wenn das System abstürzt wird das doch in der EventLog als "Kritischer Kernelfehler" angezeigt. Jedenfalls wenn ich mal nen Absturz hatte, war das immer so festgehalten.
    Das hat ja dann ebenfalls ne Event ID. Dann müsstest du das doch auch so auslesen können.
    Edit: Ups
    Ich habs mal ordentlich gewrappt und noch die Erkennung von Systemabstürzen hinzugefügt (ich weiß dass die Bezeichnungen für die Klasse und das Enum schlecht sind, mir ist aber grad nichts besseres in den Sinn gekommen):

    C#-Quellcode

    1. static void Main(string[] args)
    2. {
    3. foreach(SystemEvent @event in GetSystemEvents())
    4. {
    5. Console.WriteLine(string.Format("{0}\t{1}", @event.Time, @event.Type));
    6. }
    7. Console.ReadKey(false);
    8. }
    9. #pragma warning disable CS0618
    10. public static IEnumerable<SystemEvent> GetSystemEvents()
    11. {
    12. return new EventLog() { Log = "System" }.Entries
    13. .OfType<EventLogEntry>()
    14. .Where(entry => entry.EventID == 6005 || entry.EventID == 6006 || entry.EventID == 6008) //Alle relevanten Entries herausfiltern
    15. .Select(entry => new SystemEvent(
    16. entry.EventID == 6005 ? SystemEventType.Startup : entry.EventID == 6006 ? SystemEventType.Shutdown : SystemEventType.UnexpectedShutdown,
    17. entry.EventID != 6008 ? entry.TimeGenerated : DateTime.Parse(Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(entry.ReplacementStrings[1] + " " + entry.ReplacementStrings[0]).Where(value => value != 63).ToArray())))) //Bei einem Crash wird erst beim nächsten Start das Ereignis geschrieben, der Zeitpunkt des Absturzes ist dann in dem ReplacementStrings-Array. Allerdings sind in den Strings 63er-Chars, welche das Parsen verhindern -> Entfernung dieser
    18. .OrderBy(entry => entry.Time); //Zeitlich ordnen
    19. }
    20. #pragma warning restore CS0618
    21. public class SystemEvent
    22. {
    23. public SystemEvent(SystemEventType type, DateTime time)
    24. {
    25. this.Type = type;
    26. this.Time = time;
    27. }
    28. public SystemEventType Type { get; private set; }
    29. public DateTime Time { get; private set; }
    30. }
    31. public enum SystemEventType
    32. {
    33. Startup, Shutdown, UnexpectedShutdown
    34. }

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nafets“ ()