• ベストアンサー

Windowsアプリケーションをメモリーで実行する

EXEファイルをchar*bufと言う変数メモリーにロードして実行する場合の入り口(call又はjmp)アドレスはどこになるでしょうか? winmain()関数のアドレスがわかりません。 通常は実行ファイルをクリックするとOSがDLL等をマシン語に展開して実行しますが、メモリー上での実行はどの様にすればいいでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.13

>プログラムカウンターのつもりです。 先にも書きましたが、あなた自身にしかわからない造語を使われても他者にはわかりません。 あなたが勝手につくった造語なんて調べてもわかりませんから質問する際には、そのような造語は使うべきではないです。 もちろん回答もですが。 「動かないretcode」が動かない理由に関連する事項は、あなた自身で他の回答者の補足に書いてます。 少なくともその補足の内容を理解してるならわかるはずの理由です。

7777777v
質問者

お礼

お返事が遅くなり申し訳ありません・・・年寄りは早寝早起きがモットーでして・・・ハイ 今回の解決ポイントについご提示頂き感謝いたします。 PECOFFを実行 LoadLibrary,GerProcAddress 例外(提示されたコード) これらのキーワードで勉強の糸口が開けました。 専門用語も満足に知らず基礎勉強もせず、とにかくプログラムしてみて結果よければ自分のものにする結果オーライの繰り返しだったような気がします。 SNSツールが存在する世代に生まれて幸せです。

その他の回答 (12)

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.12

>勉強する気はあるのですが、全般的にはとても時間が無く、今回の解決のためのポイントだけでも教えて頂けたら幸いです。 ポイントは他の回答者の回答も含め出切ってます。 PECOFFを実行できる形でメモリにロードして呼び出せばいいだけです。 そのためにはCPUやOSの仕組みなど理解も必要です(#1の方のいわれてるそのままです) ちなみに私はLoadLibrary,GerProcAddressあたりで呼び出せれば十分ですので詳細な方法は知りませんし、あなたの代わりにその方法を調べる気もありません。 >001B802C番地をCPUがアクセスしないのが原因だと思いますが間違いでしょうか? いいえ。 アクセスしていてアクセスした時点で例外が起きます。 >RETコードの置かれた変数エリアを直接アクセスカウントする必要があるような気がします。 アクセスカウントって何ですか・・・ アクセスのカウント? 造語をされてもわかりませんが。 関数のポインタで呼び出してるだけなので直接とか関係ありません。 事実コメントアウトしてある「動くretcode」の方だと問題なく正常終了します。 マシン語的には「動かないretcode」は「動くretcode」が最適化されてるだけで同じものです。

7777777v
質問者

お礼

>アクセスカウントって何ですか・・・ プログラムカウンターのつもりです。 温かい皆様の回答をもう一度読み直して自力で解決いたします。

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.11

#10 のアセンブラコードの不足分 // void (*foo)(void) = (void (*)(void))&retcode; 001B8030 2C 80 1B 00

7777777v
質問者

お礼

追加分ありがとうございました。 001B8030番地のコードはCPUがアクセスしているのでOKだと思います。

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.10

>push popが発生してretコードを見失ったのだと思います。 「動かないretcode」のどこにpush popが発生する余地があるんですか・・・ VisualStudioから実行してみればわかりますがretを見失って等いません。 int main(int argc, char ** argv[]) { 001B1E80 55 push ebp 001B1E81 8B EC mov ebp,esp 001B1E83 81 EC C0 00 00 00 sub esp,0C0h 001B1E89 53 push ebx 001B1E8A 56 push esi 001B1E8B 57 push edi 001B1E8C 8D BD 40 FF FF FF lea edi,[ebp-0C0h] 001B1E92 B9 30 00 00 00 mov ecx,30h 001B1E97 B8 CC CC CC CC mov eax,0CCCCCCCCh 001B1E9C F3 AB rep stos dword ptr es:[edi] foo(); 001B1E9E 8B F4 mov esi,esp 001B1EA0 FF 15 30 80 1B 00 call dword ptr ds:[1B8030h] 001B1EA6 3B F4 cmp esi,esp 001B1EA8 E8 9D F2 FF FF call __RTC_CheckEsp (01B114Ah) return 0; 001B1EAD 33 C0 xor eax,eax } 001B1EAF 5F pop edi 001B1EB0 5E pop esi 001B1EB1 5B pop ebx 001B1EB2 81 C4 C0 00 00 00 add esp,0C0h 001B1EB8 3B EC cmp ebp,esp 001B1EBA E8 8B F2 FF FF call __RTC_CheckEsp (01B114Ah) 001B1EBF 8B E5 mov esp,ebp 001B1EC1 5D pop ebp 001B1EC2 C3 ret // 動かないretcode 001B802C C3 ret >理由は別にあるのでしょうか? というわけで別にあります。 理由は他の回答者が既に話に出してますので省略。 >この点はロードされるアドレスを指定出来ないことでもあり、絶対アドレスがメモリー上で一致するかが問題のようです。 それだけの話じゃありません。 >この調子でご指導ください。 もうしわけありませんが辞退させていただきます。 自力学習する気のない方のために貴重な時間をさく気はございません。

7777777v
質問者

お礼

勉強する気はあるのですが、全般的にはとても時間が無く、今回の解決のためのポイントだけでも教えて頂けたら幸いです。 動かないコードは 001B802C番地をCPUがアクセスしないのが原因だと思いますが間違いでしょうか? RETコードの置かれた変数エリアを直接アクセスカウントする必要があるような気がします。 又いい加減な返事をしましたが、所詮私のスキルはこの程度です。 是非正解をお願いします。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.9

念の為、確認しておきたいと思います 「アセンブリ歴20年」とのことですが、どのCPUを使った、どのOS用ですか? CPUが違えばアセンブリも違い、OSが違えば同じCPUでもコードが違うことはご理解しているかと思います。 もし、組込み用の8bit程度のマイコンを念頭に置いているのなら、CPU、OSともに規模が段違いですから、そのアセンブリの知識はほとんど役立ちません。

7777777v
質問者

お礼

現在XP,7マシンのwin32アプリケーションでインラインアセンブラで記述しています。 オールアセンブラでアプリケーションを仕上げた事はありません。

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.8

「動かないretcode」「動くretcode」共にi8086系CPUだと何もせず帰るだけのコードのはずですが 「動かないretcode」なぜ動かなくて、「動くretcode」はなぜ動くかわかりますか?(MSDOSの頃だとたぶん「動かないretcode」の方も動くと思いますが) // 動かない char retcode[] = { 0xc3 // RET }; // 動く //void retcode(void) //{ //} void (*foo)(void) = (void (*)(void))&retcode; int main(int argc, char **argv) { foo(); return 0; }

7777777v
質問者

お礼

再度の回答ありがとうございます。 push popが発生してretコードを見失ったのだと思います。 このアプリケーションの機械語をみるとわかるのですが・・・ 理由は別にあるのでしょうか? この調子でご指導ください。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.7

ああ、もう一つ突っ込みどころ。 そもそも普通にコンパイルしたコードは実行時に絶対アドレスが埋め込まれるので、デバッガじゃなくても実行時のオンメモリから機械語として取り出したら特定のアドレスでしか動かないんですが理解されてます? 他にも変数メモリの実行権限も理解されているか怪しいですね。

7777777v
質問者

補足

>じゃなくても実行時のオンメモリから機械語として取り出したら特定のアドレスでしか動かないんですが理解されてます? 皆様の回答で何となく理解することができました。 オールアセンブラで絶対アドレスを使わないようにするか、ロードアドレスを指定するようにします。 >他にも変数メモリの実行権限も理解されているか怪しいですね。 buf = (unsigned char*)VirtualAlloc( (LPVOID)NULL, (DWORD)size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ); PAGE_EXECUTEこのフラグでアクセス出来ないでしょうか?

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.6

相対アドレスでexeファイルや機械語を出力するコンパイラは存じません。 アセンブラで全部書けば、相対アドレスの機械語は生成可能です。 と言うかアセンブラ歴長いなら分かるでしょう? セクションとかも理解されずにアセンブラ組まれているんでしょうか?

7777777v
質問者

お礼

>セクションとかも理解されずにアセンブラ組まれているんでしょうか winmain()関数のなかで_asmのインラインアセンブラで記述しています。 今までに機械語のみでアプリケーションを組んだ経験はありません。 でもご指摘のセクションについては、ロードアドレスを指定出来る様で興味深い参考資料ありがとうございました。

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.5

>ご紹介のページは英語のようですが、私は英語が苦手です。 では辞書を引きながらがんばって読んでください。 >VC++のデバグ画面にはマシン語が生成されているようですが、コードのみ抽出できないでしょうか? 16進ダンプ表示させて抜き出せばいいだけじゃ? >絶対アドレスが含まれていなければ、どこのメモリーでも実行可能でしょうか? 最近のCPUとOSだとどこでも実行可能とは限りません。 >私は基礎勉強もせず皆様のお力を借りてなんとか短時間に解決しようとがんばっています。 他力本願という言葉知ってますか? 基礎勉強をがんばってください。

7777777v
質問者

お礼

再度の回答ありがとうございます。 >最近のCPUとOSだとどこでも実行可能とは限りません。 この点はロードされるアドレスを指定出来ないことでもあり、絶対アドレスがメモリー上で一致するかが問題のようです。 ビルドではビルドした環境での絶対アドレスが生成されるようで、他の回答者様も指摘されたようにVC++では不可能であることがわかりました。 SNS即他力本願を助長するツールではないでしょうか? ちょっとしたヒントでは解決しない課題は基礎勉強しかないようです。

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.4

exeやdllを実行可能なバイナリとしてロードしたいのなら少なくとも http://msdn.microsoft.com/en-us/windows/hardware/gg463119.aspx この辺は理解できるようにならないと。 そこからさらに実行するのはまた別の話になりますが。

7777777v
質問者

お礼

回答ありがとうございます。 ご紹介のページは英語のようですが、私は英語が苦手です。 VC++のデバグ画面にはマシン語が生成されているようですが、コードのみ抽出できないでしょうか? 絶対アドレスが含まれていなければ、どこのメモリーでも実行可能でしょうか? 基礎的なことを教えてください。

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.3

>>通常は実行ファイルをクリックするとOSがDLL等をマシン語に展開して実行しますが、 これは、どこから仕入れた情報ですか?すべてがそうとはいえません。 No.1さんがちょっと書かれていますが、そういうことが理解できるようになるまで先は長いと思います。でも、それを得るために費やした時間・努力は無駄にならないと思います。 小学1年生が微分・積分、三角関数など難しい数学を理解したいとと思うことは立派だけど、それらを理解できるようになるまでに学ぶことは、それなりに多いのと同じ。 一部の素質ある方は一気に理解できるかもしれませんが、普通のかたは、それ相応の学習時間が必要です。 なお、そういうことをやりたい動機は、ライセンス認証回避、プロテクト解除などが多いと思います。そういう動機であっても、プログラム解析で学べることは多いです。 私も、昔、あるソフトの動作を追いかけて、インストール回数制限のあるソフトを無制限版に改造したことありますけど、そのときにマシン語を理解しました。 がんばってください。

7777777v
質問者

お礼

回答ありがとうございます。 この質問は様々な課題がありそうです。 私は基礎勉強もせず皆様のお力を借りてなんとか短時間に解決しようとがんばっています。 EXEファイルの実行は今は無理でも、簡単な4則計算からでも始めたいと思います。 開発はVC++ですがデバグ画面ではアセンブラコードが生成されるようですが、このコードのみ抽出する設定はできるでしょうか? また、分岐やコールは相対アドレスで生成できるでしょうか? 読み込むメモリ上では、 先頭に変数エリアを、以降プログラム本体を置き、実行するアドレスは変数エリアを飛び越えた位置にします。 アセンブラ歴20年以上です。 専門家からすると意味不明なことを書いているかも知れませんが助言よろしくお願いします。

関連するQ&A