問題タブ [machine-code]
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.
gcc - 奇妙な結果がgdbになります
私はasmをたくさん扱っているCの本を読んでいて、GDBでレジスターとメモリーを見ています。問題は、まったく同じソースをコンパイルして分解すると(実際には、本のCDに付属のソースファイルを使用して)、組み立て手順が本の内容とはかなり異なって見えることです。この本はIntelフレーバーのアセンブリを使用しており、gdbに「setdisassembly intel」を入れているので、そうではありません。手順が異なるだけで、いくつかはすべて一緒に異なり、他にもいくつかの癖があります。
たとえば、この本では、eipレジスタにmov命令があります。
forループで変数iを0に初期化することに対応します(i = 0、i <10、i ++)
ただし、私のgdbコンソールでは、ブレークポイントが同じ場所にあります(set break main; run)。次のように表示されます。
別のレジスタをすべて一緒に参照していることに注意してください。espの値を確認すると、ebpではなくespであり、それ自体が0x1cです。しかし、0x1cまたはesp + 0x1cにあるものを調べてみると、それらのアドレスを見ることができないことがわかります。
それで、本が進むにつれて、それはebp、ebp-4などにあるものの軌跡をたどり始めるので、私はまったく従うことができません、そして私のasmでは何も起こっていないようですebpレジスタ
この本は2008年に書かれたので、gccまたはgdbのバージョン変更がその重要な変更を導入するほど古くなっているとは想像できません(またはそれを行いましたか?)...コンパイラの最適化がある可能性はありますかまたは、デフォルトでオンになっているもので、そのような異なる結果が生成されていますか?
前もって感謝します
編集:奇妙な。私はそれぞれの提案を試しましたが、何も機能しませんでした。次に、rm a.outを実行し、新しく再コンパイルしました。これで正常に動作します(手順は本とは異なりますが、本のアドレスに対応するアドレスを調べることができます。対応するパターンに従うことができれば、すべて問題ありません。まったく同じasmである必要はありません、それはそれを簡単にしすぎるでしょう!)すべてのあなたの助けと提案にもう一度感謝します。
linux - x86-64AMDでのCALL命令のオペランド生成
以下は、サンプルプログラムのobjdumpの出力です。
私が理解する必要があるのは、主にアドレス-8048401、コール80483b4に次のように表示されますが、マシンコードは--e8 ae ffffffです。CALL命令がE8であることがわかりますが、関数80483b4のアドレスはどのようにしてFFFFFFAEにデコードされますか?私はグーグルでたくさんの検索をしました、しかしそれは何も返しませんでした。誰か説明してもらえますか?
assembly - リバースエンジニアアセンブリ
私はリバースエンジニアリングの新しいスターターであり、詳細を知りたいのですが、実際には解釈できないいくつかの関数に出くわしたターゲットexeを逆アセンブルしようとしました。うまくいけば、誰かの助けが助けの手を貸してくれるでしょう。
アドレス00161057から00161093までの部分は、私がどうなるか本当に理解していないところです。残りは異なるAPIを呼び出すだけだったので、それはほとんど何もありません(ファイル名は削除されます)
太字の部分を誰かが説明してくれたら本当にありがたいです。
machine-code - 1と0のみのExeファイルの作成:マシンコード
メモ帳に1と0をいくつか入力し、something.exeとして保存して、プログラムを取得したいと思います。明らかに、それはそれほど複雑ではありません。こんにちはと言ってもうまくいくでしょう。テキストを出力するにはどうすればよいですか?すぐに閉じないように一時停止するにはどうすればよいですか?これをすべて言っているところに誰かが持っているリソースはありますか?
assembly - ソフトウェアが実際のハードウェア信号に変換されるのはどの段階ですか?
マシンコードの状態をポストしたプログラムはどうなりますか? アセンブラ/コンパイラは、高レベル コードまたはアセンブリ コードを機械語命令に変換します。この段階では、マシン命令はまだソフトウェア形式であり、メモリに常駐しています。このコードは、ハードウェアで処理できる物理的な電気信号にどのように変換されるのでしょうか? なんらかのインターフェイス デバイスがあれば、それがどのように変換を行うのか知りたいです。
interpreter - マシンコードはどのようにプロセッサと通信しますか?
例としてPythonを取り上げましょう。私が間違っていなければ、プログラムを作成すると、コンピューターは最初にコードをCに「変換」します。次に、Cからアセンブリに変換します。アセンブリはマシンコードで記述されています。(これは私がこれについて持っている漠然とした考えなので、間違っている場合は訂正してください)しかし、書かれたマシンコード、より正確には、プロセッサはその命令をどのように処理し、どのように何をすべきかを「見つける」のですか? ?
assembly - JMP 命令 - 16 進コード
JMP 機械語命令の 16 進コード変換について疑問があります。「JMP 0x400835」など、ジャンプしたい絶対アドレスがあります。まず、これは許されますか?はいの場合、対応する 16 進コードは何ですか? そうでない場合は、最初にEAXなどのレジスタにアドレスを保存してから、「JMP EAX」を入力できますか? x86(64b) アーキテクチャに取り組んでいます。
gdb の diassem 出力から 16 進コードを出力しようとしましたが、一貫性がありません。つまり、16 進コードに宛先アドレスが表示されません。
私は 16 進コードと機械命令に慣れていないので、無知であることをご容赦ください。
c++ - C++ - 非常に奇妙なマシン コードの動作
完全なコードはこちら: http://pastebin.com/MM3vWmqA
関数 fast_generator では、2 つのステートメントにコメントを追加しました。これらのステートメントを切り替えると、コードは最大 1.8 倍速く実行されます。最初のステートメントを削除すると、コードは元のバージョンよりも高速に実行されますが、切り替えた場合に比べて遅くなります。
テストケースは次のとおりです。
最初 - 最も遅い。452ms。
2 番目 - 最初のものよりも高速です。280ms。
3 番目 - 1 番目よりも高速ですが、2 番目よりも低速です。421ms。
元のステートメントのアセンブラー出力は次のとおりです。
これらのステートメントを切り替えても、アセンブラーの出力は同じままであり、これらの asm 命令の唯一の違いが交換されることを確認しました。
VC++10 と VC++11 でテストしましたが、同じ動作です。これらのステートメントを切り替えるとアルゴリズムが約 1.8 倍高速化される理由を誰か説明できますか? std::clock() が正確ではないと思われる場合は、size = 7 に変更してください。私のマシンでは、size = 7 の違いは 12000ms と 7000ms です。
assembly - 実際のマシンコードは、さまざまな時点でどのように見えますか?
マシンコードが実際に何であるかについては多くの意見があるようです。アセンブリ、バイナリ、または16進数だと言う人もいます。
マシンコードは本質的に特定のプロセッサ用の一連の命令であると言うのは正しいですか?もしそうなら、私はこれらが2進数または16進数の表記法、またはアセンブリで表すことができると思います。しかし、翻訳されていない「実際の」機械語はどのように見えるのでしょうか。アーキテクチャのワードサイズに基づいていますか?または、すべての目的と目的で16進数がデフォルトの表現ですか?
ハードドライブに座っているときはどのように見えますか?レジスターに座っているときはどのように見えますか?それが処理されているときはどうですか、それは単にその時点での一連の電圧変化ですか?
c - 100バイト未満のマシンコードに変換する上記のcプログラムのアセンブリコードを書くことができますか?
配列をオーバーフローさせたいのでbuffer[100]
、FreeBSDのbashシェルでPythonスクリプトを渡します。そのバッファをオーバーフローさbuffer[100]
せ、プログラムにホスト名をに出力させるために、文字列として渡すマシンコードが必要stdout
です。
これが私が試したCのコードで、コンソールにホスト名を付けています。:
}
これがgccを使用して取得したアセンブリのコードですが、cプログラムのテキストセクションのマシンコードを探すと100バイトより長く、上記のcプログラムのマシンコードが必要なため、必要以上に長くなっています。それは100バイト未満です。
ある人がすでに別のコンピューターでそれを実行していて、37バイトの既製のマシンコードを私にくれました。彼はperlスクリプトを使用して以下の形式でバッファーに渡します。私は彼のコードを試しましたが、それは機能しますが、彼はそれを行う方法を教えてくれません。
「\x41\ xc1 \ x30 \ x58 \ x6e \ x61 \ x6d \ x65 \ x23 \ x23 \ xc3 \ xbc \ xa3 \ x83 \ xf4 \ x69 \ x36 \ xw3 \ xde \ x4f \ x2f \ x5f \ x2f \ x39 \ x33 \ x60 \ x24 \ x32 \ xb4 \ xab \ x21 \ xc1 \ x80 \ x24 \ xe0 \ xdb \ xd0” </ p>
彼が別のマシンでそれを行ったので、同じコードを取得することはできませんが、両方がまったく同じc関数を使用しているため、マシンコードのサイズはまったく同じではないにしてもほぼ同じになるはずです。彼のマシンコードは37バイトで、シェルに渡してFreeBSD 2.95のバイナリファイルのgets()関数をオーバーフローさせ、ホスト名をstdoutに出力します。私は同じことをしたいと思っています。彼のマシンコードを試しましたが、動作しますが、彼はこのマシンコードをどのように取得したのか教えてくれません。だから私は実際にそのコードを取得する手順について心配しています。
OKここの投稿で提案されているメソッドを試しましたが、関数gethostname()に対して、130文字のマシンコードを取得しました。printf()マシンコードは含まれていませんでした。ホスト名をコンソールに出力する必要があるため、ホスト名も含める必要がありますが、これによりマシンコードが長くなります。コードを100バイトの配列に収める必要があるため、コードは100バイト未満である必要があります。
100バイト未満のマシンコードに変換する上記のcプログラムのアセンブリコードを書くことができますか?