2012-03-18 17 views
0

Cでは、プログラムの実行中にコンピュータ命令を直接実行する方法が必要です。バイナリでコンピュータ命令を作成する方法を知っている唯一の方法は、16進エディタを使用して、アプリケーションとしてファイルを実行することです。私はどのようにプログラムを使ってバイナリを書いて、それから実行するために新しいプロセスを作らなくてもそれを実行するでしょう。彼らはこれを行う簡単な方法でなければならないようだが、どこに見ても私はそれを見つけることができない。バイナリでコンピュータ命令を直接実行する

私はこれを行うと考えることができる唯一の方法はインラインアセンブリですが、私の現在のプロジェクトでは欠点になるので、バイナリで直接実行するのが最善の方法です。 (これはおそらく、Windows上でドライバを必要とするでしょうか?Linux上でどうやって行うのですか?つまり、クロスプラットフォームの方法はいいでしょう)

ありがとう。

+1

inlinceアセンブリは、バイナリにコンパイルされるインラインアセンブリとして(かなり可能私の知る限りではない)あなたの期待に比べてオーバーヘッドを有していません。 –

+1

すべての命令は、実行時に「バイナリ形式」で表示されます。あなたが達成しようとしていることを説明できますか? – Caleb

+1

スタックを破壊する。 –

答えて

5

あなたがしたいことは少し問題があり、多くの人々に「なぜあなたはそれをやっているのですか?」と尋ねる傾向があります。

オペレーティングシステムがメモリ保護なし(非常にまれ)であると仮定すると、関数をバイト配列にポイントして関数を呼び出すことができます。

unsigned char* code_to_execute = "\xB8\x13\x00\xCD\x10"; 
void (*runCode)(); 

runCode = code_to_execute; 

runCode(); 

しかし、このような何かをやったときに心配するSO多くのものがあります。ここでの要点です。 Cコンパイラが関数呼び出しフレームを設定し、バイナリコードでそれを尊重する方法を知る必要があります。この方法でクロスプラットフォームコードを作成することは不可能です。単一のプラットフォーム上の複数のCコンパイラで実行させることも難しいでしょう。そして、メモリ保護があります。最近のオペレーティングシステムのほとんどは、コードとしてデータを任意に実行させることはありません。あなたは明示的にメモリを実行可能なものとしてマークする必要があり、多くのオペレーティングシステムは特別な許可がなければそれを許可しません。これを行うプラットフォーム間の方法もありません。

もう一度、これは本当に良い考えではないことを強調したいと思います。インラインアセンブリ言語を使用する方が良いでしょう。または、アセンブリ言語をまったく使用しないでください。おそらく、あなたのプロジェクトについてもう少し説明することができ、Cプログラムに直接「バイナリコード」を書くことが重要なのはなぜでしょうか。それは、あなたをかなり助けてくれる回答や勧告を手助けするのに役立ちます。

+0

ありがとう、私はクロスプラットフォームの意味は、すべてのシステムで同じように動作するわけではなく、dllのロードやデバイスドライバの作成などのプラットフォーム依存の方法ではないということです。 これは、コンピュータと直接接続している人工知能に必要です。コンピュータはコンピュータなので、人工知能の言語(バイナリ)を人間が読める(アセンブリ)に変換するだけで、コンピュータの読み込み可能(バイナリ)に変換できるのはなぜですか? AIはOS用に作成されているため、他のプロセッサの動作を心配することは重要ではありません。 – u8sand

+2

好奇心が強い場合は、DOS COMファイルをコンパイルしてDOSで実行できる場合、そのサンプルコードが実際に機能します。ビデオモードを320x200,256色に変更します。 B8は「mov ax」、1300はaxに移動する16ビットの値です。 CDは「コール割り込み」、10はVGAコントローラのビデオカード割り込みです。 –

+0

今、私はそれをキャストする必要はないと思っていたのですか?私はまだ実際にそれを試していない。 – u8sand

2

メモリ内のマシンコードを使用して、そのアドレスを関数ポインタにキャストします。もちろん、Cの呼び出し規約に従う必要があります。

ほとんどのデスクトップOSでは、メモリのアクセス許可を変更して実行可能とマークする必要があります。 Windowsの場合はVirtualProtect、Linuxの場合はmprotectとなります。

バイナリマシン命令はクロスプラットフォームではありません。各プロセッサーアーキテクチャーごとに異なるコードを生成する必要があります。

コードにユーザーレベルのアクセス許可が必要な場合のみ、ドライバーは必要ありません。

+0

はい、私はバイナリ命令がクロスプラットフォームではないことを理解しています。私は基本的に "基本的にコンピュータと話す"方法が必要です。しかし、あなたが言っている方法は、DLLを読み込むように聞こえる、私はどのようにプログラムに私のバイナリを取得する必要があります直接 'シェルコーディング'のようなバイト配列に入れて? – u8sand

+0

@ u8sand:バイト配列が機能します。 Andyのような文字列が彼の答えに示されます。実行権限はページ単位であるため、それを自分のページに割り当てると良いですが、それは絶対的な要件ではありません。 –

4

このSO質問はおそらく

How to write self-modifying code in x86 assembly

いけないあなたがについて十分に知っている必要が

...人々は「なぜあなたはこの質問をしている」とあなたを減速させトピックをカバー言語、オペレーティングシステム、またはその両方を実行し、保護システム内でパンチスルーまたは作業します。そして、それはそれにメモリやブランチに(あなたはそれが独立したおよび/またはアドレッシング/い/取得/何でも与えられた依存positition作るためにあなたの仕事をしていると仮定)実行したいバイナリを置くの問題です。 Cでは、関数ポインタを宣言して、このバイナリのアドレスであるその関数にアドレスを割り当て、関数を呼び出すことができます(アドレスに分岐する別の方法がない場合は、通常、asmとasmを渡す任意のアドレスにブランチを実行するそれらをリンクしてください)。

2

生成および実行時に実行されるコードは、アプリケーション内で、非常によく理解問題です。

ウェブを「ジャストインタイムコンパイラ」や「JITコンパイル」、「ダイナミックコード生成」、特に以下を組み合わせて検索することで、コードの生成、実行中の情報の多くを見つけることができます。 Javaのようなプログラミング言語名。

動的なコード生成は、過去15年間のホットな研究課題の一つです。

(Java仮想マシンまたはJVMと呼ばれる)は、Javaランタイムシステムはdramaticly改善(すなわち> 10倍の高速化)のパフォーマンスを得るために(ホットスポットと呼ばれる)動的コンパイル技術を使用しています。

マイクロソフトは、C#などの.NET言語用のジャストインタイムコンパイルを使用しますが、おそらく多くの詳細な情報を見つけることが難しくなります。

Ian PiumartaはSmalltalkのは、現代のウィンドウシステムとオブジェクト指向プログラミング言語のいくつかのタイプのための出発点である(アラン・ケイ、スモールトークの「父と協力し、Viewpoints Research Instituteでいくつかの非常に印象的な動的コンパイル技術(例えばコーラ)を開発してきました)。この技術の一部は、Google Summer of Codeプロジェクトでカイロレンダリングエンジン(Webブラウザなどで使用される)のスピードアップに使用されました。

イアンPiumartaの作品は最も柔軟、かつコンパクトで、それゆえ開始するには良い場所かもしれません。イアンは信じられないほど賢いので、もしあなたがそれを使いたいのであれば、本当に懸命に考えるように準備しておいてください。かもしれない

他の技術:

は、いくつかのJITのアセンブラ、(私はそれらを使用したことがない)正確に何が必要かもしれ生成されがあります一見の価値がある:

、LLVMのJITとGNU libjitは、おそらく最高の自分の通常の 'ホスト' 環境外での使用のために文書化されています。 LLVMはAppleの技術サポートです。 LLVMは、他のシステムを構築するために使用できるようにライブラリのセットから組み立てられるように設計されています。しかし、それは非常に洗練された、高性能のソリューションを目指しているので、かなり急な学習曲線がありそうです。 GNU libjitは小さく見え、そのために理解しやすくなります。私はちょうどインテルのORPを発見したばかりです。

HTH