アセンブラとdraeneiを使用してMMORPGのボットを作成しています。 パート0

Hi%username%! ハブラーの記事で大騒ぎして、MMORPGのボットを書くことについて彼らのいくつかを見つけました。 間違いなくこれらは非常に興味深く有益な記事ですが、それらの可能性は非常に少ないです。 たとえば、特定のルートに沿ってMobまたは鉱石を飼育し、攻撃的なMob、プレイヤー、途中であなたを攻撃するすべての人を殺し、その後にわいせつを叫ぶ必要がある場合はどうなりますか? 一般的に、平均的なプレーヤーMMORPGの完全なエミュレーション。 AutoIt用のマクロを記述し、ウィンドウ内のクリックをシミュレートし、カーソルの下のピクセルを分析することは、私たちのオプションではありません。 興味がありますか? 猫へようこそ!

免責事項:著者は、この記事で得た知識の使用またはそれらの使用に起因する損害について責任を負いません。 ここに記載されているすべての情報は、教育目的でのみ提供されています。 特に、MMORPGを開発している企業がボットに対処するのに役立ちます。 そして、もちろん、この記事の著者はボットドライバーではなく、詐欺師でもありません。




内容


  1. パート0-コードインジェクションポイントを見つける
  2. パート1-サードパーティコードの実装と実行
  3. パート2-pr索好きな目からコードを隠す
  4. パート3-World of Warcraft 5.4.xの視界(構造)
  5. パート4-World of Warcraft 5.4.xの視界(移動)
  6. パート5-World of Warcraft 5.4.xの視界(カスタムファイアボール)


だからすぐに。

1.実装の実装方法の選択(ちょっとした理論)


間違いなく、ゲームプロセスでコードを実装する必要があります。 このために、実行可能ファイル自体を変更すること(非常に簡単ですが、禁止を決定して取得することも簡単です)またはDLLを実装することもできます(また、非常に簡単に決定できます)が、これは私たちにとってはありません。 私たちのアプローチは、制御を受け取ってそれを返すプロセスのメインスレッドにコードを注入することです。

これを行うには、アンチチートにとってそれほど明白ではなく、私たちにとって有用ではない実装ポイントを見つける/考え出す必要があります。 そのような点はたくさんありますが、多くの理由から、最善の解決策はゲームをレンダリングに導入することです。 Direct3Dのフックを作成します。 繰り返しになりますが、多くの理由から、EndScene関数をインターセプトするのが最善です。なぜなら、呼び出される前に、ゲームワールドやその他の計算に対するすべての変更が既に行われているからです。 明確にするために、内部で進行中のプロセスを次に示します。

  1. ...
  2. 現在のゲームシーンのオブジェクトの描画
  3. なりすましのD3D EndSceneを呼び出す
  4. 私たちのコード
  5. 元のD3D EndSceneを呼び出す
  6. 次のシーン
  7. ...


このキーのシーンは、いわゆるフレームです。 つまり、コードはfpsの頻度で動作します。

注:fpsはかなり高い値になる可能性があるため、コードのすべての呼び出しを処理する必要はありません。 1秒あたり10〜15コールで十分だと思います




2.ツールキット


計画の概要を説明しましたが、今はツールが必要です。 私は(ほとんどの希望のように)既製のものをすべて使用するのが大好きです。 したがって、次のものを取得することを提案します。

  1. C#でコードを記述するIDE
  2. IDA-私の意見では最高のデバッガー
  3. HackCalc -VA(仮想アドレス)をオフセットに、またはその逆に変換するための計算機
  4. SlimDX-.NET用DirectXフレームワーク
  5. FlatAsm Managed-ライブラリは、アセンブリコードのニーモニックをバイトコードに変換します





3.実装ポイントを検索する


そのため、メソッドを理解し、ツールを取得しました。次に、コードを挿入する場所を理解する必要があります。

D3Dを使用してレンダリングすると、仮想Direct3Dデバイスオブジェクトが作成されます。これは、本質的にはVMT(仮想メソッドテーブル、D3Dメソッドテーブルへのポインターへのポインター)です。 このテーブルにも、BeginScene、EndScene、DrawTextなどのDirect3Dメソッドへのポインターが格納されます。 この場合、EndSceneにのみ関心があります。 Direct3Dデバイスは単一のインスタンスで作成されます。次に、それへのポインターを取得してから、テーブルへのポインターを取得する必要があります。 繰り返しますが、ゲームクライアントで使用されるD3Dを決定する必要があります。 2つのオプション(DX9およびDX11)があり、単純な網羅的検索によってこの問題を解決できます。 このために、SlimDXを使用します。

kernel32.dllの標準ReadProcessMemoryのコードprocessMemory.ReadおよびprocessMemory.ReadBytesラッパー内

DX9で確認します。

//  D3D9 var device = new SlimDX.Direct3D9.Device( new SlimDX.Direct3D9.Direct3D(), 0, DeviceType.Hardware, Process.GetCurrentProcess().MainWindowHandle, CreateFlags.HardwareVertexProcessing, new[] { new PresentParameters() }); using (device) { //   var processMemory = new ProcessMemory((uint)Process.GetCurrentProcess().Id); //       D3D9    0xA8    Com  _D3D9Adress = processMemory.Read<uint>(processMemory.Read<uint>((uint)(int)device.ComPointer) + 0xa8); //   _D3D9OpCode = (int)processMemory.Read<byte>(_D3D9Adress) != 0x6a ? processMemory.ReadBytes(_D3D9Adress, 5) : processMemory.ReadBytes(_D3D9Adress, 7); }
      
      





0xA8はどこから来たのですか?.. d3d9.hを開いてEndSceneメソッドを見つけると、
 STDMETHOD(EndScene)(THIS) PURE;
      
      



IDirect3DDevice9インターフェースの42番目、x86アーキテクチャの1つの機能は4バイトでアドレス指定され、42 * 4 = 168となり、これは0xA8です。

これはすべてtry / catchでラップする必要があり、エラーが発生した場合、D3D11を試す必要があり、すべてが少し複雑になります。EndSceneではなく、SwapChainがインデックス8にあります。 8 * 4 = 32 = 0x20:

 //      D3D11 using (var renderForm = new RenderForm()) { var description = new SwapChainDescription() { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription(100, 100, new Rational(60, 1), SlimDX.DXGI.Format.R8G8B8A8_UNorm), OutputHandle = renderForm.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SlimDX.DXGI.SwapEffect.Discard, Usage = SlimDX.DXGI.Usage.RenderTargetOutput }; SlimDX.Direct3D11.Device device; SlimDX.DXGI.SwapChain swapChain; var result = SlimDX.Direct3D11.Device.CreateWithSwapChain( DriverType.Hardware, DeviceCreationFlags.None, description, //    out device, out swapChain); if (result.IsSuccess) using (device) using (swapChain) { //    -      var processMemory = new ProcessMemory((uint)Process.GetCurrentProcess().Id); //  SwapChain _D3D11Adress = processMemory.Read<uint>(processMemory.Read<uint>((uint)(int)swapChain.ComPointer) + 0x20); _D3D11OpCode = processMemory.ReadBytes(_D3D11Adress, 5); } }
      
      





これはすべて、もう一度try / catchでラップする必要があります。 D3D関数のアドレスを取得しようとしても失敗した場合は、オフセットが変更されているか、D3D9またはD3D11がありません。

結論:EndScene D3D関数のアドレスとこの関数のオペコードがあります。

それらで何ができ、コードを実装する方法は、次の部分で説明できますが、今のところ、投票、上記のコードの理解、google、Yandex、bingute、yahoo ...、コメントで尋ねて、アセンブラのドキュメントを読んでください、完全なハードコアとドレーニがあります!



All Articles