アプリ版:「スタンプのみでお礼する」機能のリリースについて

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

A 回答 (13件中1~10件)

>プログラムカウンターのつもりです。



先にも書きましたが、あなた自身にしかわからない造語を使われても他者にはわかりません。
あなたが勝手につくった造語なんて調べてもわかりませんから質問する際には、そのような造語は使うべきではないです。
もちろん回答もですが。

「動かないretcode」が動かない理由に関連する事項は、あなた自身で他の回答者の補足に書いてます。
少なくともその補足の内容を理解してるならわかるはずの理由です。
    • good
    • 0
この回答へのお礼

お返事が遅くなり申し訳ありません・・・年寄りは早寝早起きがモットーでして・・・ハイ
今回の解決ポイントについご提示頂き感謝いたします。

PECOFFを実行
LoadLibrary,GerProcAddress
例外(提示されたコード)

これらのキーワードで勉強の糸口が開けました。

専門用語も満足に知らず基礎勉強もせず、とにかくプログラムしてみて結果よければ自分のものにする結果オーライの繰り返しだったような気がします。
SNSツールが存在する世代に生まれて幸せです。

お礼日時:2013/08/05 09:00

>勉強する気はあるのですが、全般的にはとても時間が無く、今回の解決のためのポイントだけでも教えて頂けたら幸いです。



ポイントは他の回答者の回答も含め出切ってます。
PECOFFを実行できる形でメモリにロードして呼び出せばいいだけです。
そのためにはCPUやOSの仕組みなど理解も必要です(#1の方のいわれてるそのままです)

ちなみに私はLoadLibrary,GerProcAddressあたりで呼び出せれば十分ですので詳細な方法は知りませんし、あなたの代わりにその方法を調べる気もありません。

>001B802C番地をCPUがアクセスしないのが原因だと思いますが間違いでしょうか?

いいえ。
アクセスしていてアクセスした時点で例外が起きます。

>RETコードの置かれた変数エリアを直接アクセスカウントする必要があるような気がします。

アクセスカウントって何ですか・・・
アクセスのカウント?
造語をされてもわかりませんが。

関数のポインタで呼び出してるだけなので直接とか関係ありません。
事実コメントアウトしてある「動くretcode」の方だと問題なく正常終了します。
マシン語的には「動かないretcode」は「動くretcode」が最適化されてるだけで同じものです。
    • good
    • 0
この回答へのお礼

>アクセスカウントって何ですか・・・

プログラムカウンターのつもりです。

温かい皆様の回答をもう一度読み直して自力で解決いたします。

お礼日時:2013/08/04 23:29

#10 のアセンブラコードの不足分



// void (*foo)(void) = (void (*)(void))&retcode;
001B8030 2C 80 1B 00
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/08/04 21:47

>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

>理由は別にあるのでしょうか?

というわけで別にあります。
理由は他の回答者が既に話に出してますので省略。

>この点はロードされるアドレスを指定出来ないことでもあり、絶対アドレスがメモリー上で一致するかが問題のようです。

それだけの話じゃありません。

>この調子でご指導ください。

もうしわけありませんが辞退させていただきます。
自力学習する気のない方のために貴重な時間をさく気はございません。
    • good
    • 0
この回答へのお礼

勉強する気はあるのですが、全般的にはとても時間が無く、今回の解決のためのポイントだけでも教えて頂けたら幸いです。

動かないコードは
001B802C番地をCPUがアクセスしないのが原因だと思いますが間違いでしょうか?
RETコードの置かれた変数エリアを直接アクセスカウントする必要があるような気がします。
又いい加減な返事をしましたが、所詮私のスキルはこの程度です。

是非正解をお願いします。

お礼日時:2013/08/04 21:46

念の為、確認しておきたいと思います



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

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

お礼日時:2013/08/04 17:12

「動かない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;
}
    • good
    • 0
この回答へのお礼

再度の回答ありがとうございます。

push popが発生してretコードを見失ったのだと思います。

このアプリケーションの機械語をみるとわかるのですが・・・

理由は別にあるのでしょうか?

この調子でご指導ください。

お礼日時:2013/08/04 16:56

ああ、もう一つ突っ込みどころ。


そもそも普通にコンパイルしたコードは実行時に絶対アドレスが埋め込まれるので、デバッガじゃなくても実行時のオンメモリから機械語として取り出したら特定のアドレスでしか動かないんですが理解されてます?

他にも変数メモリの実行権限も理解されているか怪しいですね。

この回答への補足

>じゃなくても実行時のオンメモリから機械語として取り出したら特定のアドレスでしか動かないんですが理解されてます?
皆様の回答で何となく理解することができました。
オールアセンブラで絶対アドレスを使わないようにするか、ロードアドレスを指定するようにします。

>他にも変数メモリの実行権限も理解されているか怪しいですね。

buf = (unsigned char*)VirtualAlloc( (LPVOID)NULL, (DWORD)size,
MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );

PAGE_EXECUTEこのフラグでアクセス出来ないでしょうか?

補足日時:2013/08/04 16:43
    • good
    • 0

相対アドレスでexeファイルや機械語を出力するコンパイラは存じません。


アセンブラで全部書けば、相対アドレスの機械語は生成可能です。
と言うかアセンブラ歴長いなら分かるでしょう?

セクションとかも理解されずにアセンブラ組まれているんでしょうか?
    • good
    • 0
この回答へのお礼

>セクションとかも理解されずにアセンブラ組まれているんでしょうか

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

お礼日時:2013/08/04 16:35

>ご紹介のページは英語のようですが、私は英語が苦手です。



では辞書を引きながらがんばって読んでください。

>VC++のデバグ画面にはマシン語が生成されているようですが、コードのみ抽出できないでしょうか?

16進ダンプ表示させて抜き出せばいいだけじゃ?

>絶対アドレスが含まれていなければ、どこのメモリーでも実行可能でしょうか?

最近のCPUとOSだとどこでも実行可能とは限りません。

>私は基礎勉強もせず皆様のお力を借りてなんとか短時間に解決しようとがんばっています。

他力本願という言葉知ってますか?
基礎勉強をがんばってください。
    • good
    • 0
この回答へのお礼

再度の回答ありがとうございます。

>最近のCPUとOSだとどこでも実行可能とは限りません。

この点はロードされるアドレスを指定出来ないことでもあり、絶対アドレスがメモリー上で一致するかが問題のようです。
ビルドではビルドした環境での絶対アドレスが生成されるようで、他の回答者様も指摘されたようにVC++では不可能であることがわかりました。

SNS即他力本願を助長するツールではないでしょうか?
ちょっとしたヒントでは解決しない課題は基礎勉強しかないようです。

お礼日時:2013/08/04 16:23

exeやdllを実行可能なバイナリとしてロードしたいのなら少なくとも


http://msdn.microsoft.com/en-us/windows/hardware …
この辺は理解できるようにならないと。
そこからさらに実行するのはまた別の話になりますが。
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/08/04 14:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!