問題タブ [self-modifying]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
assembly - x86アセンブリで自己変更コードを作成する方法
最近取り組んでいる趣味の仮想マシン用のJITコンパイラを作成することを検討しています。私は少しアセンブリを知っています(私は主にCプログラマーです。理解できないオペコードを参照してほとんどのアセンブリを読み、いくつかの簡単なプログラムを書くことができます)が、いくつかの例を理解するのに苦労しています。私がオンラインで見つけた自己修正コードの。
これはそのような例の1つです:http://asm.sourceforge.net/articles/smc.html
提供されているサンプルプログラムは、実行時に約4つの異なる変更を行いますが、いずれも明確に説明されていません。Linuxカーネル割り込みは数回使用され、説明も詳細もされていません。(作成者は、割り込みを呼び出す前にデータをいくつかのレジスタに移動しました。彼は引数を渡していたと思いますが、これらの引数はまったく説明されておらず、読者に推測を任せています。)
私が探しているのは、自己変更プログラムのコードの中で最も単純で最も単純な例です。私が見て、x86アセンブリの自己変更コードをどのように記述しなければならないか、そしてそれがどのように機能するかを理解するために使用できるもの。あなたが私に指摘できるリソース、またはこれを適切に示すことができるあなたが与えることができる例はありますか?
私はアセンブラとしてNASMを使用しています。
編集:私はLinuxでもこのコードを実行しています。
c - アセンブリーでの JIT コンパイラーの作成
非 JIT VM としては十分なパフォーマンスを発揮する仮想マシンを C で作成しましたが、何か新しいことを学び、パフォーマンスを向上させたいと考えています。私の現在の実装では、スイッチを使用して VM バイトコードから命令に変換し、ジャンプ テーブルにコンパイルします。私が言ったように、それが何であるかについてはまともなパフォーマンスですが、JITコンパイラでしか克服できない障壁にぶつかりました.
少し前に自己変更コードについて同様の質問をしましたが、適切な質問をしていないことに気付きました。
したがって、私の目標は、この C 仮想マシン用の JIT コンパイラを作成することであり、x86 アセンブリで実行したいと考えています。(アセンブラとして NASM を使用しています) これを行う方法がよくわかりません。私はアセンブリに慣れており、自己変更コードの例をいくつか調べましたが、コード生成の方法はまだわかりません。
これまでの主なブロックは、引数を使用して命令を実行可能なメモリにコピーすることです。NASM で特定の行にラベルを付け、静的引数を使用してそのアドレスから行全体をコピーできることは承知していますが、これはあまり動的ではなく、JIT コンパイラでは機能しません。バイトコードから命令を解釈し、それを実行可能メモリにコピーし、最初の引数を解釈してメモリにコピーし、次に 2 番目の引数を解釈してメモリにコピーできる必要があります。
GNU lightning や LLVM など、この作業を容易にするいくつかのライブラリについて知らされています。ただし、外部リソースを使用する前に、これがどのように機能するかを理解するために、最初にこれを手動で記述したいと思います。
このタスクを開始するために、このコミュニティが提供できるリソースや例はありますか? 「add」や「mov」などの 2 つまたは 3 つの命令を使用して実行可能コードを生成し、引数をメモリ内で動的に生成する単純な例は、驚くべきことです。
executable - ランタイムコード変更の賢いケースはありますか?
実行時コードの変更(実行時に自身のコードを変更するプログラム)の正当な(スマートな)使用法を思いつくことができますか?
最近のオペレーティングシステムは、この手法が検出を回避するためにウイルスによって使用されているため、これを実行するプログラムに眉をひそめているようです。
私が考えることができるのは、コンパイル時に知ることができない何かを実行時に知ることによって、いくつかのコードを削除または追加する、ある種の実行時最適化です。
c++ - C++ ブール変数の変更
私は C++ クラスを持っています。このクラスは次のとおりです。
まず、ヘッダー:
そして .cpp ファイル
_modified を含む .cpp ファイルの 3 行すべてにブレークポイントを設定して、設定/変更/読み取りが行われている場所を正確に確認できるようにしました。シーケンスは次のようになります。
- コンストラクターのブレークポイントがトリガーされます。_modified 変数が true に設定されていることを確認
- アクセサーのブレークポイントがトリガーされます。_modified 変数は FALSE です!
これは、PageTableEntry のすべてのインスタンスで発生します。クラス自体は変数を変更していません-何か他のものです。残念ながら、私は何を知りません。クラスは new を使用して動的に作成され、ベクトルやマップを含むさまざまな STL 構造に (ポインターとして) 渡されます。ミューテーターは自分のコードから呼び出されることはありません (私はまだその時点に到達していません)。また、STL 構造が呼び出されることはありません。ミューテーターでブレークポイントが呼び出されることはないため、それらが呼び出されていないと想定することしかできません。 .
明らかに、特定の状況下で、誰が何を知っているかによって引き起こされる、クラスのミューテーターを介さずにプライベート変数を変更できる「落とし穴」がありますが、それが何であるかは想像できません。何かご意見は?
更新:各段階でのこの
値:
コンストラクター 1: 0x100100210
コンストラクター 2: 0x100100400 アクセサー
1: 0x1001003f0 アクセサー
2: 0x100100440
UPDATE2:
(PageTableEntry にアクセスする場所を示すコード)
これらは、問題を引き起こすために PageTableEntry オブジェクトが保存され、STL 構造から取得される唯一のポイントです。他のすべての関数は、testAddr() 関数を使用してエントリを取得します。
UNRELATED: C++ には現在 65663 の質問があり、今日これまでに 164 が質問されているため、今日だけで C++ タグ付きの質問の数が 16 ビットの符号なし整数を超えたことを意味します。使える?いいえ、面白いですか?はい。:)
c++ - 自己修正コード [C++]
自己変更コードに関するコードブレーカーのジャーナル記事を読んでいたところ、次のコード スニペットがありました。
このコードは、スタック上で Demo() を実行したと思われます。ほとんどのコードは理解できますが、「func_len」が割り当てられている部分で混乱します。私が知る限り、彼らは別のランダム ポインター アドレスから 1 つのランダム ポインター アドレスを減算しています。
誰か説明してくれませんか?
powershell - 自己変更 PowerShell スクリプトを作成することは可能ですか?
自己変更 PowerShell スクリプトを作成することは可能ですか?
次の名前のスクリプトがあるとしますfoo.ps1
。
このスクリプトは を出力しHello world
ます。印刷するには、どのような手法を使用できGoodbye world
ますか?
c - C 標準は自己変更コードを許可しますか?
Cで移植可能な方法で自己変更コードは可能ですか?
私が尋ねる理由は、ある意味で、OOP は自己変更コードに依存しているからです (実行時に実行されるコードは、実際には v テーブルなどでデータとして生成されるため)。これは行き過ぎであり、コンパイラでのほとんどの最適化を妨げます。
例えば:
最適化コンパイラは*pAddend
をループから引き上げることができp
ます。ただし、これは自己変更コードでは有効な最適化ではなくなりました。
このように、C は自己変更コードを許可していないように見えますが、同時に、C では OOP のようなことができないことを意味するのではないでしょうか? C は本当に自己変更コードをサポートしていますか?
c - Cで自己修正コードを書く方法は?
変更が重要でない場合でも、継続的に変更されるコードを記述したいと思います。
たとえば、次のようなものかもしれません
コードで、最初の反復後に行x := 200
を別の行にx := 199
変更し、次の反復後に次のx := 198
ように変更する必要があるとします。
そのようなコードを書くことは可能ですか?そのためにインラインアセンブリを使用する必要がありますか?
編集:これが私がCでそれをやりたい理由です:
このプログラムは実験的なオペレーティングシステムで実行され、他の言語からコンパイルされたプログラムの使用方法がわかりません。このようなコードが必要な本当の理由は、このコードが仮想マシンのゲストオペレーティングシステムで実行されているためです。ハイパーバイザーは、コードのチャンクを変換するバイナリトランスレーターです。翻訳者はいくつかの最適化を行います。コードのチャンクを1回だけ変換します。次回ゲストで同じチャンクが使用されるとき、トランスレータは以前に変換された結果を使用します。これで、コードがその場で変更された場合、翻訳者はそれに気づき、以前の翻訳を失効としてマークします。したがって、同じコードの再翻訳を強制します。これは私が達成したいことであり、翻訳者に多くの翻訳を強制することです。通常、これらのチャンクは、分岐命令(ジャンプ命令など)間の命令です。自己修正コードはこれを達成するための素晴らしい方法だと思います。
mips - レジスタに格納された数値を MIPS の命令として実行できますか?
命令を取り、それをオペコード、rs、rt などの 2 進数表現に分解した場合、この 2 進数をレジスタに入れ、MIPS にそれを命令として扱わせることができますか?
例えば:
命令: add $t0, $s0, $t0
次のように分類されます。
000000 10010 01000 01000 00000 100000
これは整数に対応します: 18696
この整数をレジスタに格納してから、MIPS にそれを命令として扱わせることはできますか?
自己変更コードのアイデアを念頭に置いてこれを尋ねます。
self-modifying - 自己変更コードである実際のアプリケーションはありますか?
Web 上には、自己変更コードの記述方法を示す例はほとんどありません。しかし、それらは単なる例です。自己変更コードである実際のアプリケーションがあるかどうかを知りたいです。ありがとう!