問題タブ [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.

0 投票する
2 に答える
343 参照

language-agnostic - 自己修正コード?

私は次のことをしたいと思います。プログラムで構造体を宣言し、実行時にプログラムが実行されている場合、ユーザー入力があれば、別の新しい構造体を作成したり、コードでその構造体を編集したりできるはずです。どうすればそれができますか?これは「自己修正コード」ですか?明確にしてください。いくつかの例を挙げてください。ありがとう

私がやりたいことのアイデアを教えてください.「student」と呼ばれる「構造/クラス」があり、「int roll_no」や「int reg_no」などの変数が含まれています。ユーザーが実行時に「char name」のような新しい変数を追加したい場合、どうすればよいでしょうか?

0 投票する
1 に答える
1434 参照

c++ - C++自己修正アセンブリコードをインライン化する方法は?

これをC++関数でインライン化するにはどうすればよいですか。

どのように私は置くだろう DB B8 DB 00

エラー C2400: 'opcode' のインライン アセンブラー構文エラー。'constant' が見つかりまし た cl.exe の実行中にエラーが発生しました。

これをセクションに入れることはできないと思います.data。このようなバイトを含めるためにできることはそれだけです。

0 投票する
1 に答える
480 参照

assembly - プロセッサはデータを「L1 コード」キャッシュから「L1 データ」キャッシュに切り替えますか?

知りたいのですが、マイクロプロセッサ (ロング モードの SandyBridge アーキテクチャで言う) は、データを「L1 コード」キャッシュから「L1 データ」キャッシュに、またはその逆にどのように切り替えますか? ページがデータ ストレージに使用されたため、L1 キャッシュにキャッシュされたとします。次に、OS の実行中に、命令ポインタが現在 L1 データ キャッシュにキャッシュされているメモリ位置にジャンプします (JMP 命令を発行します)。プロセッサはデータを L1 データから L1 コード キャッシュに移行しますか? データ管理命令が L1 コード キャッシュに格納されているアドレスに対して発行された場合 (つまり、アドレスがコード実行ではなくデータ格納に適していることを意味します) についても同じ質問があります。プロセッサはこれらの問題をどのように処理しますか?

私は自己変更コードについて勉強しているので、これを尋ねています。コードキャッシュの詳細を読むことができる追加情報があれば、リンク/参照を投稿してください。

0 投票する
0 に答える
306 参照

android - NDK を変更し、新しい実験的リリース パッケージを生成する

NDK を変更し、doc 'android-ndk-r6\docs\DEVELOPMENT.html' を使用して新しい実験的リリース パッケージを生成しようとしていますが、スクリプト $NDK/build/tools/rebuild-all-prebuilt を実行した後に次のエラーが発生します.sh --toolchain-pkg=:

エラー: ソース ディレクトリは次の ARCH をサポートしていません: arm 。. . エラー: 無効な sysroot: /tmp/ndk-Administrator/build/platforms/android-9/arch-arm

--sysroot= を使用して、有効なものを示します。

それを解決する方法を教えてください

0 投票する
4 に答える
6300 参照

assembly - ホモイコニックで「制限のない」自己修正コード + Lisp は本当に自己修正ですか?

私の Lisp に関する知識はごくわずかであることを率直に認めます。しかし、私はその言語に非常に興味があり、近い将来、それを真剣に学び始める予定です. これらの問題に対する私の理解には間違いなく欠陥があるため、明らかに間違っていることを言う場合は、反対票を投じるのではなく、コメントして修正してください。

真のホモイコニックで自己修正可能な言語

Homoiconicity (コードはデータと同じ表現を持つ) と無制限の自己変更 (新しいコードを発行したり、関数ポインターを変更したりするだけでなく、実行中のコードのあらゆる側面を変更できることを意味する無制限の意味) の両方をサポートするプログラミング言語の例を探しています/代議員。)

私がこれまでに見つけた、この基準に適合する例は 3 つしかありません。

  1. マシンコード。すべてが数字であるホモイコニック。ポインターが含まれているという点で無制限に変更可能であり、そのアドレスがコードまたはデータを保持しているかどうかに関係なく、任意のメモリ アドレスを操作するために使用できます。
  2. マルボルジ。マシンコードと同じ理由。すべての命令は、実行後に自身を変更します
  3. DNA。プログラミング言語ではありませんが、それでも興味深いものです。マシンコードと同じ意味での自己変更ではありません。実際の命令とデータが変更された場所。ただし、それは自己複製であり、以前の状態に応じて変異/進化する可能性があります (放射線などの副作用が時々発生します)。とにかく、これは自己修正の間接的な方法です。簡単に言えば、DNA は自己改変することができますが、それは関連する突然変異と共にその全体を複製することによって行われます。DNA の物理的な文字列は「不変」です。

Lisp がこのリストにない理由

Lisp はそのリストに含まれていません。なぜなら、Lisp はほぼホモイコニックであり、制限付きの自己変更しかサポートしていないように思われるからです。次のようなことができます

と同じことを行います

最初のバージョンでは(+ 1 2 3)は生のコードですが、2 番目のバージョンではデータです。このステートメントが真実であると仮定することにより、Lisp はホミニックでさえないと主張することができます。コードは、リスト/ツリー/S 式の両方であるという意味で、データと同じ表現をしています。しかし、これらのリスト/ツリー/S 式のどれがコードで、どれがデータであるかを明示的にマークしなければならないという事実は、結局のところ Lisp はホミニックではないと言っているように思えます。表現は非常に似ていますが、コードまたはデータを扱っているかどうかを実際に言わなければならない細部が異なります。これは決して悪いことではありません (実際、それ以外のことはすべて狂気です) が、Lisp とマシン コードの違いを浮き彫りにしています。マシン コードでは、どの数値が命令で、どの数値がポインターで、どの数値がデータであるかを明示的にマークする必要はありません。

これは、無制限の自己変更に対するさらに強力なケースです。もちろん、コードを表すリストを取得して操作することもできます。たとえば、

そして、あなたはそれを実行しますeval。しかし、これを行うと、コードをコンパイルして実行するだけです。既存のコードを変更するのではなく、新しいコードを発行して実行するだけです。C# は式ツリーを使用してまったく同じことを行うことができますが、形式があまり便利ではありません (これ、独自の AST である Lisp とは対照的に、C# コードがその AST とは異なる表現を持つために発生します)。実際にソース ファイル全体を取得し、実行中にそのソース ファイル全体を変更して、ソース ファイルに加えられた変更がプログラムの動作にリアルタイムで影響を与えることはできますか?

これを行う何らかの方法がない限り、Lisp はホモニックでも自己修正でもありません。(定義に関する議論を先延ばしにするために、Lisp はホモイコニックでもなければ、マシン コードと同じ程度の自己修正でもありません。 )

Lisp Homoiconic/Unrestrictly 自己変更可能にする方法

Lisp をマシンコードのようにホモイコニック/自己修正可能にする 3 つの方法が考えられます。

  1. 非フォンノイマン アーキテクチャ。誰かが、プログラムの最下位レベルの表現が直接実行できる AST である驚くべき仮想マシンを発明できたら (それ以上のコンパイルは必要ありません)。そのようなマシンでは、AST は実行可能な命令とデータの両方を表します。残念ながら、AST は依然としてコードまたはデータのいずれかでなければならないため、問題は解決されていません。eval 関数が存在しても、これは変わりません。機械語では、コードとデータの間を好きなだけ行ったり来たりできます。一方、eval と Lisp では、リストをデータからコードに「評価」して実行すると、そのリストを再びデータとして取得する方法はありません。実際、そのリストは永久になくなり、その値に置き換えられました。たまたまポインターである重要なものが欠けている可能性があります。
  2. ラベルを一覧表示します。すべてのリストにも一意のラベルが必要である場合、特定のラベルを持つリストに対して関数を実行することにより、間接的な自己変更を行うことができます。継続と組み合わせることで、最終的にマシンコードと同じ意味で自己修正コードが可能になります。ラベルは、マシン コードのメモリ アドレスと同等です。例として、AST の最上位ノードに「main」というラベルが付いている Lisp プログラムを考えてみましょう。次に、main 内で、ラベル、整数、アトムを受け取る関数を実行し、アトムを、関数に指定されたインデックスに一致するラベルを使用してリストにコピーできます。次に、メインで現在の継続を呼び出します。ほら、自己修正コード。
  3. Lisp マクロ。私は Lisp マクロを理解するのに時間をかけたことがありません。実際、それらは私が考えていることを正確に実行する可能性があります。

ポイント 1. と 2. を組み合わせると、完全に自己変更的な Lisp が生成されます。説明されている魔法の Lisp マシンを作成できるという条件で。2. 単独で自己変更 Lisp を作成できますが、フォン ノイマン アーキテクチャでの実装は非常に非効率的です。

質問

  1. マシンコード、DNA、malbolge 以外に、完全自己改変が可能でホモイコニックな言語はありますか?
  2. (上記のテキストで tl;dr を実行した場合は、わざわざ回答しないでください) . Lispは本当にホモイコニック+自己修正ですか? もしあなたがそうおっしゃるなら、私の議論のどこで私が道に迷ったのかを正確に引用していただけますか?

付録

制限のない自己修正を伴うがホモニシティを持たない言語

  1. 組み立て。コードは数字ではなく単語を使用するため、同義性は失われますが、メモリに対する完全な制御を保持し、無制限の自己変更を可能にするポインタがまだあります。
  2. 生のポインターを使用するすべての言語。例: C/C++/Objective C。アセンブリと同じ引数
  3. 仮想ポインターを含む JIT 言語。たとえば、安全でないコンテキストで実行されている C#/.net などです。Assembly と同じ引数。

何らかの形で関連/興味深い可能性のあるその他の概念と言語: Lisp、Ruby、Snobol、Forth とコンパイル時のメタプログラミング、Smalltalk とそのリフレクション、すべてが関数であるというプロパティを持つ型指定されていないラムダ計算 (これは、ラムダ計算を直接実行するマシンを発明できれば、ラムダ計算はホモイコニックであり、フォン ノイマンのマシン コードは、そのマシンで実行するとそうではありません.[そして、ゲーデルの定理は実行可能になるでしょう.ハハ、恐ろしい考え :P])

0 投票する
2 に答える
881 参照

self-modifying - 自己変更コードのユースケース?

フォン ノイマン アーキテクチャでは、プログラムとデータの両方がメモリに保存されるため、プログラムはそれ自体を変更できます。これはプログラマにとって有用ですか?いくつか例を挙げていただけますか?

0 投票する
2 に答える
25388 参照

c++ - C ++で変更した後にファイルのアクセス許可を修正しますか?

プログラムの実行可能ファイルにデータを保存しています。それを一時ファイルにコピーし、 「マジックストリング」で始まる部分を上書きして、元の名前に変更します。これは悪い考えだと思いますが、実験のためだけにやっています。

ファイルが置き換えられるたびに「実行可能ファイルとしての実行を許可する」を再度有効にする必要があることを除いて、これまでのところすべてが機能するようになりました。これを解決する方法はありますか?

追加情報:私はLinuxを使用しています。

0 投票する
1 に答える
693 参照

c - 自己変更コード、ヒープでのコピー/ジャンプに失敗しました

まず、この投稿が長くなって申し訳ありませんが、問題を明確に説明したかったのです。

C で一種の小さな自己修正プログラムを作成しようとしていますが、いくつかの問題があり、その理由が正確にはわかりません。

プラットフォーム: Ubuntu/Linux 2.6.32-40 x86_64、prog は x86 arch でビルド、gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3、GNU ld (Ubuntu の GNU Binutils) 2.20.1-system.20100303

プログラムの目的は、 ( memalign(3)およびmprotect(2)を使用して) メモリの読み取り/書き込み/実行のチャンクを作成し、このメモリのチャンクで (セグメントで定義された)呼び出された小さな関数をコピーしてから、ポインターを介して関数をコピーしました。この関数は、 を使用してメッセージを表示するだけです。p().textp()printf(puts)

のコードの開始アドレスと終了アドレスを取得するp()(コピーする) ために、関数自体のアドレスと in の直後に作成される関数のアドレスを使用しdummy()ます。p().text

チャンク メモリの作成とコピーは正常に行われますが、チャンク内のコードが実行されると segfault が発生します。これを使用gdbすると、チャンクのコード (コピーされた関数の本体) に入力することは明らかですが、printf の呼び出しは失敗しました。関数とチャンク内のコードを逆アセンブルするp()と、「呼び出し」で使用されるアドレスが同じではないことがわかります。

そして、なぜアドレスが間違っているのかわかりません。コードをコピーすると、それが表示され、p()関数を逆アセンブルしたときに objdump (または gdb) が私に与えたものと同じです。

の再配置プロセスに関する-static潜在的な問題を回避するために、バイナリは で作成されます。コピーされた関数の先頭が実行されるため、でコードを実行しても問題はないようです( で確認してください)。got/pltld.soheapgdb

プログラムの簡略化された src :

p()によって逆アセンブルされた関数objdump(1):

プログラムを gdb(1) で実行すると、コピーされたコードは上記の objdump(1) と同じ (16 進値) になります。

main を見ると、次に chunk に入ります:

しかし、p() とチャンクが逆アセンブルされると、p() 関数の like のcall 0x80d2c90代わりにメモリ チャンクに がありますか? call 0x8048f50 <puts>そのため、表示されるアドレスは同じではありません。

メモリをチェックすると、コードは同一のようです。この時点で、何が起こっているのか理解できません。何が問題なのですか? gdb の解釈に失敗しました。コードのコピーか何か?

ブレークポイントが設定されている場合、メモリ チャンクで実行が続行されます。

したがって、この時点で、プログラムがそのように実行されてセグメンテーション違反が発生するか、$eip が変更されてプログラムがエラーなしで終了します。

何が起こっているのか、何が失敗したのかわかりません。コードのコピーは問題ないように見えます。メモリ チャンクへのジャンプも同様です。では、なぜ (呼び出しの) アドレスが適切ではないのでしょうか?

あなたの答えとあなたの時間をありがとう

0 投票する
2 に答える
4131 参照

ollydbg - 自己変更コードの逆アセンブル

私はただ疑問に思っていました-自己変更バイナリをどのように逆アセンブルしますか? olly や IDA は静的逆アセンブラーなので使用できないと思いますよね?命令の途中にジャンプすると、逆アセンブラはどうなりますか? そして、変成エンジンをどのように分析するのでしょうか?

0 投票する
1 に答える
62 参照

x86 - TARGET_HAS_PRECISE_SMCとはどういう意味ですか?

x86のみがTARGET_HAS_PRECISE_SMC(target-i386 / cpu.h)を定義しているのがわかり、コメントには次のように書かれています。

それが何を意味するのか、もっと知りたいのですが、グーグルは役に立ちません。そのことに光を当てていただけませんか。ありがとう。