none
Dúvidas em fechamento de processos (Iniciante) RRS feed

  • Pergunta

  • Primeiramente bom dia a todos.

    Eu sou um ADM de um servidor de um jogo e gostaria de fazer um anti-cheat para ele pelo Visual Studio Express 2012.

    O que eu gostaria de aplicar nesse anti-cheat era o seguinte:

    Eu gostaria que o anti-cheat abrisse junto com o .EXE do jogo e que ficasse em segundo plano, impossibilitando de ser fechado tanto pela janela quanto pelos processos (essa não é a parte principal pois já tenho uma ideia de como vou fazer isso)

    Eu também gostaria de que ele fechasse todos os "Hacks" que eu designaria-lo a fechar...

    Agora com fechamento de processo eu até tenho uma base também, más eu queria que de algum jeito (que não sei qual)

    ele detectasse o "Hack" de um jeito que, caso eu mudasse o nome da janela ou o nome do processo do hack, o meu anti-cheat continuasse detectando o mesmo.

    E que ao detectar um hack o meu anti-cheat automáticamente feche o .EXE do meu jogo e o próprio anti-cheat..

    Bom eu sei que estou pedindo de mais, más tentem responder parte das minhas dúvidas para eu tentar fazer aqui xD

    Já procurei bastante na net más não achei nada muito útil para mim.

    Obrigado desde já pela atenção galera.

    Fui.

    quarta-feira, 2 de outubro de 2013 18:24

Respostas

  • Isso vai dar trabalho. 

    Veja se não é possível escrever dlls para o seu jogo e dar um load junto com ele. Há jogos que suportam extensões. Veja com os desenvolvedores. 

    Se for o caso, fica mais fácil dar o load com o jogo e espiar por cheaters.

    Não é tão simples como parece bloquear um, você tem que conhecer o seu inimigo primeiro. O que ele faz, como faz. Assim você não se preocupa apenas em fechar o arquivo Cheat1.exe, mas sim em não permitir que qualquer cheater insira um código específico ou um comando ou alguma alteração na memória.

    Se você saber o que ele faz, não importa o nome dele, assim, você pode bloquear vários com o mesmo código, apenas bloqueando uma ação específica. 

    Um cheater geralmente mexe na memória, alterando valores em realtime, por isso fica fácil fazer as alterações. Você guarda a pontuação de um jogador no como Int Points = 15000, if Resposta = "Steve Jobs" então Points += 1000, logo Console(Points) "16000"

    Basta ele ler os espaços da memória que o jogo está ocupando e alterar diretamente para Points=160000 for exemple.

    Se o jogo rolar via server, aí fica bem mais fácil. Veja uma boa resposta aqui:

    Ooooohh I love questions like this.

    Right, first up:

    we are hosting a game server

    Bam, there you go. If the client must send the state update back to the game server before this is pushed out to other clients, you have a chance to analyze the game state for changes. This means you can detect anomalous patterns. So for example, if you suddenly see a massive change of value in gold, you can then shut that user out of the game.

    There's many statistical approaches you can take. Aside from the obvious "huge change" or "impossible action" you can apply more long term solutions - such as gold over time. Assuming I know about the "don't add massive amounts of gold to my character" trick I might increment gold in safe amounts over time. Great, if I always push the edge. However, that constant increase won't correlate with the equivalent gold earned in genuine consistent gameplay, so... again, detect and shut the account down.

    The key here is that these are things you can do on the server side that the end user can do nothing about, even if they've manipulated the game state.

    Now, onto your Win32 side questions. First up, I don't think WriteProcessMemory is a particularly valid call for any DLL to make, with the exception of debuggers (which will replace instructions in code - this is how breakpoints set by debuggers work), however, there's no way you can reliably replace this for every call on the system without writing what is effectively a rootkit - i.e. you'd affect everyone, not just yourself. So this isn't really an option.

    One thing you could do - and it's no mean feat - is to periodically check your own executable memory for modification. For more, see Tamper Aware/Self Healing Code on codeproject. Basically, periodically invoke this and crash the game if you detect any modifications.

    You might also consider code signing - it's not ridiculously expensive, and it does provide a built into windows way of preventing offline executable modifications.

    If you store saved state locally, you might consider saving checksums and sending these to your server accounts. No, this is not bulletproof, but it adds extra complexity.

    If you're going to implement any of these features, you're going to need to raise the barrier a bit and make it hard for the cracker to disable, skip or otherwise work around your protection mechanisms. Let's be clear - if someone is determined enough, you're done for, but you can at least make their lives very painful.

    The top articule for anti reverse engineering on my reading list is also from code project. The guide is very thorough and should give you an excellent grounding in exactly what you can do to confuse and otherwise upset debuggers. I'll walk through one of them, which I think is fantastic:

     SetUnhandledExceptionFilter(UnhandledExcepFilter);
     __asm{xor eax, eax}
     __asm{div eax}
    

    This is evil. Basically, as the article explains, the UnhandledExceptionHandler is called on a non-debug process as the handler of last resort; however, in this case we deliberately clear eax, then divide by zero. That'll cause a processor fault, which the OS then sends back to the executable's exception handler - only if there's a debugger attached. If there is a debugger attached, the debugger gets notified and the executable exits.

    Of course, it is fairly easy for an attacker to replace div eax with one or more nop instructions or something, which means execution will just slide over, but a little self verification picks that up easily enough.

    So, in conclusion then:

    • My first advice would be to try to detect cheats on the server side. Here, you hold all the keys. You could even introduce these changes "dark", that is, check and see who is cheating, then analyse their states to see if it works, without cutting them off.
    • Then, I'd attempt periodic self verification in several forms:
      • In memory, as much as is reliable, of the executable.
      • In memory, as much as is reliable, of critical data structures.
      • The executable on disk, too.
    • Finally, I'd read that reverse engineering guide top to bottom - and see what you can apply to your executable. I realise you said you can't modify your executable, but honestly unless you do so, you're likely to be up against it. After all, a second "watcher process" can just be killed by an attacker.

    Link:http://security.stackexchange.com/questions/16448/detecting-or-preventing-process-memory-injections-on-windows-anti-hack

    Há uma série de implementações que podem ser feitas.

    sds

    • Marcado como Resposta Giovani Cr terça-feira, 8 de outubro de 2013 14:35
    quinta-feira, 3 de outubro de 2013 14:35

Todas as Respostas

  • Certo, e qual sua dúvida em relação ao código?

    Bruno Ferreira de Souza
    MVP - Microsoft Valuable Professional
    MCTS .NET Framework - Windows Applications
    MCPD .NET Framework - Windows Applications
    www.maestrodotnet.com.br
    @BrunoMaestro

    quinta-feira, 3 de outubro de 2013 03:32
  • Isso vai dar trabalho. 

    Veja se não é possível escrever dlls para o seu jogo e dar um load junto com ele. Há jogos que suportam extensões. Veja com os desenvolvedores. 

    Se for o caso, fica mais fácil dar o load com o jogo e espiar por cheaters.

    Não é tão simples como parece bloquear um, você tem que conhecer o seu inimigo primeiro. O que ele faz, como faz. Assim você não se preocupa apenas em fechar o arquivo Cheat1.exe, mas sim em não permitir que qualquer cheater insira um código específico ou um comando ou alguma alteração na memória.

    Se você saber o que ele faz, não importa o nome dele, assim, você pode bloquear vários com o mesmo código, apenas bloqueando uma ação específica. 

    Um cheater geralmente mexe na memória, alterando valores em realtime, por isso fica fácil fazer as alterações. Você guarda a pontuação de um jogador no como Int Points = 15000, if Resposta = "Steve Jobs" então Points += 1000, logo Console(Points) "16000"

    Basta ele ler os espaços da memória que o jogo está ocupando e alterar diretamente para Points=160000 for exemple.

    Se o jogo rolar via server, aí fica bem mais fácil. Veja uma boa resposta aqui:

    Ooooohh I love questions like this.

    Right, first up:

    we are hosting a game server

    Bam, there you go. If the client must send the state update back to the game server before this is pushed out to other clients, you have a chance to analyze the game state for changes. This means you can detect anomalous patterns. So for example, if you suddenly see a massive change of value in gold, you can then shut that user out of the game.

    There's many statistical approaches you can take. Aside from the obvious "huge change" or "impossible action" you can apply more long term solutions - such as gold over time. Assuming I know about the "don't add massive amounts of gold to my character" trick I might increment gold in safe amounts over time. Great, if I always push the edge. However, that constant increase won't correlate with the equivalent gold earned in genuine consistent gameplay, so... again, detect and shut the account down.

    The key here is that these are things you can do on the server side that the end user can do nothing about, even if they've manipulated the game state.

    Now, onto your Win32 side questions. First up, I don't think WriteProcessMemory is a particularly valid call for any DLL to make, with the exception of debuggers (which will replace instructions in code - this is how breakpoints set by debuggers work), however, there's no way you can reliably replace this for every call on the system without writing what is effectively a rootkit - i.e. you'd affect everyone, not just yourself. So this isn't really an option.

    One thing you could do - and it's no mean feat - is to periodically check your own executable memory for modification. For more, see Tamper Aware/Self Healing Code on codeproject. Basically, periodically invoke this and crash the game if you detect any modifications.

    You might also consider code signing - it's not ridiculously expensive, and it does provide a built into windows way of preventing offline executable modifications.

    If you store saved state locally, you might consider saving checksums and sending these to your server accounts. No, this is not bulletproof, but it adds extra complexity.

    If you're going to implement any of these features, you're going to need to raise the barrier a bit and make it hard for the cracker to disable, skip or otherwise work around your protection mechanisms. Let's be clear - if someone is determined enough, you're done for, but you can at least make their lives very painful.

    The top articule for anti reverse engineering on my reading list is also from code project. The guide is very thorough and should give you an excellent grounding in exactly what you can do to confuse and otherwise upset debuggers. I'll walk through one of them, which I think is fantastic:

     SetUnhandledExceptionFilter(UnhandledExcepFilter);
     __asm{xor eax, eax}
     __asm{div eax}
    

    This is evil. Basically, as the article explains, the UnhandledExceptionHandler is called on a non-debug process as the handler of last resort; however, in this case we deliberately clear eax, then divide by zero. That'll cause a processor fault, which the OS then sends back to the executable's exception handler - only if there's a debugger attached. If there is a debugger attached, the debugger gets notified and the executable exits.

    Of course, it is fairly easy for an attacker to replace div eax with one or more nop instructions or something, which means execution will just slide over, but a little self verification picks that up easily enough.

    So, in conclusion then:

    • My first advice would be to try to detect cheats on the server side. Here, you hold all the keys. You could even introduce these changes "dark", that is, check and see who is cheating, then analyse their states to see if it works, without cutting them off.
    • Then, I'd attempt periodic self verification in several forms:
      • In memory, as much as is reliable, of the executable.
      • In memory, as much as is reliable, of critical data structures.
      • The executable on disk, too.
    • Finally, I'd read that reverse engineering guide top to bottom - and see what you can apply to your executable. I realise you said you can't modify your executable, but honestly unless you do so, you're likely to be up against it. After all, a second "watcher process" can just be killed by an attacker.

    Link:http://security.stackexchange.com/questions/16448/detecting-or-preventing-process-memory-injections-on-windows-anti-hack

    Há uma série de implementações que podem ser feitas.

    sds

    • Marcado como Resposta Giovani Cr terça-feira, 8 de outubro de 2013 14:35
    quinta-feira, 3 de outubro de 2013 14:35
  • Bruno


    Bom minha dúvida é na base do código.

    Por exemplo, que comandos eu usarei para identificar se um processo está aberto e que comandos usarei para matar aquele processo.

    E o modo de identificação, se possível eu gostaria que detectasse por FindWindow (acho que esse é o nome)..

    Falei com um amigo meu que fez um anti-cheat desse geito que eu quero fazer, porém ele fez no delphi 7, irei passar o código para tentar mostrar mais ou menos o que eu quero fazer no VB:

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Tlhelp32, ExtCtrls, StdCtrls, jpeg, Commctrl;
    
    type
      TForm1 = class(TForm)
        Timer1: TTimer;
        Image1: TImage;
        Timer4: TTimer;
        procedure Timer1Timer(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure Timer4Timer(Sender: TObject);
      private
        { Private declarations }
        procedure AppMessage(var Msg: TMSG; var HAndled: Boolean);
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
      H: HWnd;
      NomeDoLog: string;
      Arquivo: TextFile;
    
    implementation
    
    {$R *.dfm}
    
    function processExists(exeFileName: string): Boolean;
     var
     ContinueLoop: BOOL;
     FSnapshotHandle: THandle;
     FProcessEntry32: TProcessEntry32;
     begin
     FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
     ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); 
     Result := False;
     while Integer(ContinueLoop) <> 0 do
     begin 
     if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
     UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) = 
     UpperCase(ExeFileName))) then
     begin
     Result := True;
     end;
     ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
     end;
     CloseHandle(FSnapshotHandle); 
     end;
    
    
    function KillTask(ExeFileName: string): integer;
    const
      PROCESS_TERMINATE=$0001;  
    var 
      ContinueLoop: BOOL; 
      FSnapshotHandle: THandle;
      FProcessEntry32: TProcessEntry32;
    begin
      result := 0;  
      FSnapshotHandle := CreateToolhelp32Snapshot 
                         (TH32CS_SNAPPROCESS, 0);  
      FProcessEntry32.dwSize := Sizeof(FProcessEntry32); 
      ContinueLoop := Process32First(FSnapshotHandle,  
                                     FProcessEntry32); 
      while integer(ContinueLoop) <> 0 do
      begin 
        if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = 
             UpperCase(ExeFileName)) 
         or (UpperCase(FProcessEntry32.szExeFile) =
             UpperCase(ExeFileName))) then 
          Result := Integer(TerminateProcess(OpenProcess(
                            PROCESS_TERMINATE, BOOL(0), 
                            FProcessEntry32.th32ProcessID), 0));
        ContinueLoop := Process32Next(FSnapshotHandle, 
                                      FProcessEntry32);
      end;
      CloseHandle(FSnapshotHandle);
    
    
    end;
    
    procedure TForm1.AppMessage(var Msg: TMSG; var HAndled: Boolean);
    begin
      Handled := False;
      case Msg.Message of
        WM_SYSKEYDOWN:
          if Msg.wParam = VK_F4 then
            Handled := True;
      end;
    end;
    
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    if FindWindow('Window', nil) > 0
    then
    KillTask('EndZ.exe');

    Eu coloquei como código de VB pois não tinha a opção de delphi.

    Más enfim, é isso que pretendo fazer.

    Desde já grato.


    • Editado R. Reis quinta-feira, 3 de outubro de 2013 20:44
    quinta-feira, 3 de outubro de 2013 20:13
  • Biseweski

    Percebi que esse código parece meio complicado para mim :/

    Como eu disse sou iniciante e queria fazer uma coisa mais básica por enquanto para depois tentar algo mais complicado...

    Más de qualquer forma obrigado pela ajuda.


    • Editado R. Reis quinta-feira, 3 de outubro de 2013 20:44
    quinta-feira, 3 de outubro de 2013 20:15
  • Para fazer esse tipo programação você já deve ter alguma experiência em programação, em especial com APIs do Windows.

    Bruno Ferreira de Souza
    MVP - Microsoft Valuable Professional
    MCTS .NET Framework - Windows Applications
    MCPD .NET Framework - Windows Applications
    www.maestrodotnet.com.br
    @BrunoMaestro

    quarta-feira, 9 de outubro de 2013 01:21