CSGOをチートしよう!チート対策を回避!?

CSGO、正式名称はCounter-Strike: Global Offensiveで一人称視点のシューティングゲームです。今回はこのゲームをチートする方法をご紹介します。この記事の内容通りにすれば対策を回避しながらチートできるはずです。現在、steamで無料でプレイできるので興味のある方はやってみてください。

CSGOには以下の2つのチート対策がされています。

VAC
ユーザーモードで動作するチート対策ソフト。
OverWatch
疑わしいプレイヤーの対戦が録画され、Investigatorと呼ばれる調査員がチートしているか否かの判決をくだし、黒だった場合アカウントがバンになります。チートを多用しすぎて、人間技とは思えないプレイを連発していると危険です。

注意
オンラインではテストしておらず、本当にVACを回避できているか確証はとれていません。オフラインでのBOT対戦で動作確認をしただけです。そのため、何らかの手違いが発生し、アカウントがBANになる可能性がありますので、そのリスクを受け入れたうえで自己責任で使用してください。

今回のチートできること

・Driver Hiding (Kill Patchguard before use) @JKornev
・Process Hiding (Kill Patchguard before use) @landhb
・Simple glow Wallhack
・Highlights defuser
・No flash
・Aimbot
・Smooth aimbot
・TriggerBot - Supports randomized delay.
・Another simple program to Display Ranks (Work in progress)
・Displays enemies on the Radar
・Bhop
・OBRegisterCallback to limit access to the GarhalController.exe & GarhalRankDisplayer.exe (Read VAC section)

VAC Bypassのイメージ図



必要なツール

GarHal_CSGO - 今回のメインになるCSGOをチートするためのプログラム、VC++のソースコード

Visual Studio Community 2019 - GarHal_CSGOをビルドするために使用するIDE

Windows Driver Kit (WDK) & SDK - ドライバーを開発するために必要なライブラリ

Haze-Dumper v2.4.1 - CSGOからオフセットを抽出するプログラム

環境

Windows10 HOME 2004 19041.867 64bit

ダウンロード & インストール方法

GarHal_CSGO

Codeボタンをクリックし、Download ZIPを選択してダウンロード。
解凍したファイルは、C:\GarHal_CSGO-masterにあると仮定して進めていきます。



Visual Studio community 2019


C++によるデスクトップ開発をチェックしてから、個別のコンポーネントを選択します。


画像赤枠のMSVC v142 ... 軽減ライブラリ(最新)をチェックし、右下の変更をクリック。
これでVisual Studioのインストールは完了です。



Windows Driver Kit (WDK) & SDK


赤枠部分をクリックしてSDKとWDKをインストール。
これでドライバをビルドする環境が整いました。

CSGOの設定

念のため、CSGOをinsecureモードに変更しておきましょう。
Steamを起動し、赤枠のライブラリをクリック。


左にあるゲームリストから、CSGOを右クリックしてプロパティを選択。


一般タブの下のほうにある起動オプションに -insecure と入力します。


これでVACで保護されているサーバーに接続できなくなりました。
VACを無効にしたわけではないので、その辺は注意が必要です。

Haze-Dumperで最新のオフセットを抜き出す

まずこちらのサイトにアクセスし、exeファイルをダウンロードしましょう。


次にこちらのサイトからconfig.jsonをダウンロードします。


config.jsonをクリック

画面右端にあるRawをクリック


右クリックから名前を付けて保存を選択し、config.jsonをダウンロードします。

ダウンロードできましたら、hazedumper-v2.4.1.exeと同じディレクトリにおいてください。
そうすると↓画像のようになったと思います。


CSGOを起動し、bot対戦を開始してから、hazedumper-v2.4.1.exeを実行します。
これでオフセットが自動で抜き出されました。
hazedumper-v2.4.1.exeと同じディレクトリにcsgo.hppがあるので、これをテキストエディタで開いてください。


次にプロジェクト内のオフセットを更新します。
管理者モードでVisual Studioを起動し、C:\GarHal_CSGO-master\Garhal.slnを開きましょう。


画像の赤枠にoffsets.hppと入力し、目的のファイルを検索します。
GarhalControllerとGarhalRankDisplayerに1つずつありますね。
この2つをダブルクリックして開いてください。

先ほど開いておいたcsgo.hppにnamespace netvarsと記載があると思います。
先頭のnの左にカーソルを置き、Ctrl + Shift + Endキーを押し、Ctrl + Cでコピーします。
その状態でVisual Studioに移りましょう。

offsets.hppにもnamespace netvarsと記載がありますよね。
同じように先頭のnの左にカーソルを置き、Ctrl + Shift + Endキーを押し、Ctrl + vで張り付けします。
これで最新のオフセットに更新できました。

offsets.hppはGarhalControllerとGarhalRankDisplayerの合計2つあるので、2つとも同じ手順で更新しておきましょう。
わかりにくいと思うので、こちらに動画を用意しました。


右が更新前、左が更新後です。
画像のように、ほとんどのアドレスが変わっていることがわかります。
これで最新のオフセットに更新され、ビルドの準備が整いました!

Visual Studioでビルドしよう

今回ビルドするプロジェクトは以下の3つです。
・Garhal - カーネルドライバー。CSGOのメモリの読み書きを担当
・GarhalController - ドライバーに対して指示を送る、ユーザーモードで動作するプログラム
・GarhalRankDisplayer - ランキングを表示するプログラム

それでははじめていきましょう。
まず、ビルド構成をDebugからReleaseに変更してください。


このままビルドするとエラーが出るので、それを修正します。
画像の赤枠にhide.cと入力し、ダブルクリックして開いてください。


紫字が変更箇所です。

1行目、#pragma warning...の最後に 6001 6387) と6387を付け足します。
8行目、LPSTR result = ExAllocatePool2(NonPagedPool, 2 * sizeof(ULONG) + 30,'Tag1');

これで一度ビルドします。
メニューバーのビルドからソリューションのビルドをクリック。


ここで下記画像のようにエラーが出ると思うので、赤枠をダブルクリックしてntos.hを開き、
Ctrl + Sを押し上書き保存します。出来ましたら、もう一度ビルドしてみましょう。



これでようやくビルドが成功しました。
ビルドが終わるとC:\GarHal_CSGO-master\x64\Releaseに以下の3つのファイルが作成されます。
今回使用するのは上の2つだけです。

・Garhal.sys
・GarhalController.exe
・GarhalRankDisplayer.exe

チートの設定を変更しよう

C:\GarHal_CSGO-master\GarhalController\garhal.cfg を GarhalController.exeと同じディレクトリ
C:\GarHal_CSGO-master\x64\Releaseにコピーしてください。
garhal.cfgが設定ファイルになるので、これをテキストエディタで開き、自分好みに変更できます。

ここではひとまず以下の設定を変更してみました。左の数字は行数です。
2.Aimbots = 2
4.AimbotKey = 0x43
6.Aimbot Target = 1
26.Radar = True

セキュアブートを無効にする

まずお使いのパソコンでセキュアブートが有効になっているかを確認します。
Windowsキー + R を押し、msinfo32と入力後、OKをクリックしてください。


そうすると↓画像のようにシステム情報が表示されるので、検索文字列にブートと入力し、
次を検索をクリックしてセキュアブートの状態を確認します。


セキュアブートはBIOSの設定から無効にできます。
BIOSの起動方法はパソコンによって違うので、説明書を見たり、サポセンに電話するなりして調べてください。

参考画像

Enabled  -> 有効
Disabled -> 無効

セキュアブートはセキュリティ上必要な機能のため、どこかのタイミングで有効に戻しておきましょう。

ドライバーを起動しよう

セキュアブートを無効にできたら、次はドライバーをインストールします。
まず、windowsキー + Rを押し、cmdと入力したあと、Ctrl + Shift + Enterで管理者としてコマンドプロンプトを起動しましょう。
次に、下記のコマンドを実行し、テストモードをオンにします。

bcdedit /set testsigning on


この時点でセキュアブートを無効にしてないと、上のコマンドを実行したとき、エラーが出ます。
ここで一度コンピュータを再起動してください。そうするとデスクトップの右下にテストモードがオンになったことを知らせる表記があると思います。


再び管理者としてコマンドプロンプトを起動して、下記のコマンドを実行します。

sc create garhal type= kernel binpath="C:\GarHal_CSGO-master\x64\Release\Garhal.sys"


sc start garhal


これでドライバーが起動しました。
この状態でCSGOを起動し、GarhalController.exeを実行すれば設定したチートがオンになります。


ドライバーを停止させるには下記のコマンドを入力します。

sc stop garhal


ゲームを終了した後は、念のためドライバを停止しておきましょう。
起動し続けていると何らかの不具合が起き、OSが強制終了になる可能性があります。

最後に下記のコマンドを実行して、テストモードをオフにします。

bcdedit /set testsigning off


POINT

テストモードをオンにするのは無署名のドライバーをインストールするためです。インストールしてしまえば次回からはテストモードにする必要はなく、そのままsc start garhalとして起動できます。


まとめ

今回のキーになるのはユーザーモード、カーネルモード間をどのようにして通信しているかです。DeviceIoControlというWinApi関数でドライバーにコントロールコードとデータを送り、それを受け取ったドライバーが要求された指示を実行しているということです。例えば、コントロールコードがIO_READ_REQUESTなら指定されたプロセスのメモリを読み取り、IO_WRITE_REQUESTなら指定されたメモリに値を書き込みます。コントロールコードは開発者が定義し、またそれを受け取ったドライバーが何を実行するのかも自分で実装できます。このあたりを紐解いていけば全貌が見えてくると思うので、ぜひソースを読み込んでみてください。

Cheat EngineでLuaを使ってみよう!

特定のキーを押している間だけ値を固定する

使用ゲームはAsssault Cubeで、キーボードのLを押している間だけ弾数が30で固定されます。
{$lua}
if syntaxcheck then return end
[ENABLE]
t = createTimer()
t.Interval = 10
t.OnTimer = function()
  if isKeyPressed(VK_L) then
    writeInteger('["ac_client.exe"+0010F4F4]+148',30)
  end
end
[DISABLE]
t.destroy()
参考動画

Luaスクリプトの解説


{$lua}はAAスクリプト内でluaを記述する際に必要な宣言
Auto Assemblerに戻すには{$asm}と記述する

[ENABLE]セクション
createTimerでTimerクラスのインスタンスを生成
Intervalには指定された関数を何ミリ秒ごとに実行するかを、
OnTimerには実行する関数を代入する

function()
  if isKeyPressed(VK_L) then
    writeInteger('["ac_client.exe"+0010F4F4]+148',30)
  end
end

上記の関数が10ミリ秒ごとに繰り返し実行される

isKeyPressedはgetAsyncKeyStateのluaバージョン
指定されたキーが押されている場合はtrueが返される
trueならwriteIntegerで指定されたアドレスに値を書き込む
VK_Lは仮想キーでこちらのサイトで調べ、自分の好みのキーを指定できる

[DISABLE]セクション
スクリプトをオフにしたときにdestroyメソッドを呼び出し、インスタンスをメモリから削除

Player Base/Entity Listの見つけ方

プレイヤーオブジェクト
 メモリに実体化されたプレイヤーの構造体 インスタンスまたはエンティティとも言う

プレイヤーベースポインター
 メモリに実体化されたプレイヤーオブジェクトの先頭アドレスを保持しているポインタ変数

Player Baseの見つけ方

仮にHPのアドレスを見つけたとします。次にHPのアドレスにアクセスしている命令を調べ、mov [edi+E4],eaxとなっていれば、おそらくediがプレイヤーオブジェクトの先頭アドレスです。あとはediの値でアドレス検索すれば、緑色のベースポインターのアドレスがヒットするはずです。ヒットしない場合はポインタースキャンを使ってください。

また、プレイヤーオブジェクトを見つければ必ずしも情報がざくざく見つかるわけではありません。例えば風来のシレン5plusの場合、2D画面上の座標はありましたが、肝心のHP、満腹度、経験値は別の構造体にありました。

これはゲームを作成したプログラマーが構造体をどう定義するかによって変わってきます。assault cubeのように1つの構造体にHP、名前、座標、弾丸などたくさんの値を定義していれば連鎖的に値を見つけることができます。

まずは何でもいいので値を見つけていき、ポインタースキャンInjection copyを使用して次回起動時からもその値を参照できるようにしておきます。次にその値の近辺(同じ構造体)に他の情報がないかダンプ画面とdissect data structureを使用してゲームを動かしながら探します。

全体の流れとしてはこんな感じです。

Entity Listとは

赤枠がプレイヤーベースポインター(PlayerBase)、青枠がプレイヤーオブジェクトの先頭アドレスです。

風来のシレン5plus

Counter Strike Source

Entity ListとはEntity(実体)が格納されている配列のことです。
上の画像のオフセットに注目してみると風来のシレンは0x8バイトずつ、CSSは0x10バイトずつアドレスが離れていることが分かります。この2つのゲームの場合ポインター配列になっており、ポインターのアドレスが規則正しく並んでいるのが特徴的ですね。

Entity Listを見つける際はこの特徴を利用します。
どちらもオフセット0、つまり配列の先頭にプレイヤーの実体があるのも重要な点です。

参考URL