2

そのため、C++コードを使用してさまざまなプログラムの値にアクセスする方法を考えていました。

私はメモリの場所を知っていて、どういうわけかそれにアクセスする必要があることを理解していますが、実際にはその方法がわかりません。

ある程度の体力を持つキャラクターがいて、その体力をc ++コードで読みたいゲームがあるとします(チートエンジンプログラムでさまざまな値を読み取る方法と同様です)。

どうすればこれを達成できますか?

明確にするために:オペレーティングシステムはウィンドウです

4

3 に答える 3

8

ReadProcessMemory / VirtualQuery(ReadProcessMemoryよりも安全)およびWriteProcessMemory 関数を使用できます。

DLLを挿入できる賢い場合は、コードでポインターを使用できます

int * money = 0x00400000+0x00ABCDEF;//pointer to money address
*money = 5000;//set money to 5000.

DLLの例が必要な場合は、次のようになります。

レッドアラート3プレーヤー情報Mod

ニードフォースピード:アンダーグラウンド2チートモッド

ポインタが指すものを変更する場合がありますが、これはアプリケーションの観点からは「危険」である可能性があります。

保護されたメモリ領域、アクセスできないメモリ、必要なもの、または無効な場所を指すポインタにアクセスすると、アプリケーションがクラッシュする可能性があります。Cheat Engineがそれをどのように防ぐかはわかりませんが、いくつかのオプションがあります。

  • アプリケーションを正常に終了し、処理できなかったことをユーザーに知らせます
  • 代わりにtry/catchブロックで問題を処理しますか?(必ず正しいエラーをキャプチャしてください)
  • アプリケーションをハード終了します
  • 何もせずに、アプリケーションを奇妙な動作/クラッシュさせます
  • ... だんだん

また、間接参照を処理し、エラーが発生すると停止する(nullを返す)ポインタークラスを自分で作成しました。

//null as last parameter automaticly "Dereferences"
template<class T = DWORD, class S = DWORD> struct Pointer
{
private:
    std::vector<S> params;
    S variable;
    bool MoreThanOne;
public:
    //null as last parameter automaticly "Dereferences"
    template<class... Args> 
    Pointer(Args... args) 
    {  
        std::array<S, sizeof...(args)> list = {args...};
        for( auto i : list)
            params.push_back(i);
        if(params.size() > 1)
            MoreThanOne = true;
        else
            MoreThanOne = false;
    }
    T ResolvePointer() 
    {  
        variable = params[0];
        if(!MoreThanOne)
            return (T)variable;
        try
        {
            auto it = params.begin();
            ++it;  
            for(; it != params.end(); ++it)
            {
                if(*reinterpret_cast<S*>(variable) == NULL)
                    return static_cast<T>(NULL);
                variable = *reinterpret_cast<S*>(variable) + *it;
            }
        }
        catch(...)
        {   
            return static_cast<T>(NULL);
        }
        return (T)variable;
    }
    T operator()()
    {
        return ResolvePointer();
    }
};

利用方法:

unsigned long ipaddr = htonl(Pointer<unsigned long>(0x00400000+0x008E3A74,0x04,0x38,NULL)());//pointer to players IP address
if(ipaddr != NULL)//....
于 2013-03-27T00:35:55.773 に答える
0

特定のIPCメカニズムを使用せずに、別のプロセスのメモリスペースに書き込むことはできません。オペレーティングシステムは通常、明らかな理由でこれを防ぎます。代わりに、ターゲットアプリケーションの拡張メカニズムを使用するか、逆コンパイル/変更/16進編集して必要な変更を行う必要があります。そうは言っても、そうすることはあなたがいじっているソフトウェアの利用規約に違反しているかもしれません。

明確にするために、コードは問題なくコンパイルされ、任意のアドレスへのポインターを設定できますが、そのアドレスを読み書きしようとすると、OSが介入してエラー状態を引き起こします。

そうすることでソフトウェアのEULAに違反していない場合は、変更したいものを見つけるためのいくつかの指針を以下に示します。

  • コードを読み取り可能なソース形式に逆コンパイルできる場合は、逆コンパイルしてそこで変更を加えます。
  • コンパイルされたバイナリを16進エディタで編集し、明確に定義された値を探して変更します(max_healthは常に25から始まりますか?これは、検索して変更するのに十分な一意である可能性があります)。これに関する注意:挿入しようとしている値が元の値と同じスペースに収まっていることを確認してください。収まらないと、問題が発生し、結果が未定義になります。
  • アプリケーションは、スクリプトAPIやmodサポートなどの拡張メカニズムを提供しますか?もしそうなら、これはあなたが望むタイプのシステム変更を引き起こすためのベクトルになることができます。
于 2013-03-27T00:30:11.593 に答える
0

次の場合を除いて、別のプロセスで変数にアクセスすることはできません。

  1. プログラムは「デバッグ関数」を使用して値にアクセスします。
  2. ある種のIPC(共有メモリ、パイプ、メッセージキュー)を使用してデータを共有/転送します。

各プロセスには独自のアドレス空間があり[1]、アクセスするための何らかのメカニズムがなければ、別のプロセスのアドレス空間にアクセスする方法はありません。

[1]適切なメモリ管理を使用する「実際の」OSについて話していると仮定します。従来のDOSなどの一部のOSでは、プロセス間にメモリ保護がありません。しかし、システムが非常に弱いプロセッサと少量のメモリで実行されていない限り、これらのOSを操作する正気の人は誰もいません。

于 2013-03-27T00:37:59.363 に答える