2017-02-21 9 views
0

スタック内にローカル変数を作成したか、または文字列用にメモリを割り当てていて、値を入れたいとします。ローカル変数に文字列を動的にロードする

push ebp 
mov ebp, esp 
sub esp, 0xff ; 255 bytes 

そしてCにスタック内の文字列を格納:

strcat(my_str1, "something1"); 
strcat(my_str1, get_var2()); 
strcat(my_str1, "something3"); 
strcat(my_str1, get_var4()); 

私はFASMやNASMで "strcatの" なしていることを行う方法undertandたい:

;1 
mov byte ptr [esp - 1], 's' 
mov byte ptr [esp - 2], 'o' 
mov byte ptr [esp - 3], 'm' 
mov byte ptr [esp - 4], 'e' 
; and so on 

はどのようにこのです完了しました?そして、 "get_var2()"と "get_var4()"の部分については?

;2 
call get_var2 
mov ??byte?? ptr [esp - 11], eax 
; or lea? 
+3

Cで最初に 'strcat'を実装してみましょう(ライブラリ関数を使用せずに)。次に、それがどのように動作するかを確認し、asmで同じことを実行できます。 – Jester

答えて

0

1)sub esp, 0xffあなたがC文字列のための唯一の255バイト(+ゼロターミネータ254文字)が必要な場合はあなたがすでに減らさmov [esp-1],'s')、その後256

2を割り当て、少なくとも4ごとに、整列espを保ちますespなので、ローカル変数はある程度[esp+X]アドレスになります。代わりに[ebp-Y]をCのような関数プロローグで使用して、ebp最初にスタックフレームポインタを初期化する(push ebpmov ebp,espsub esp,local_vars_size ..次にpop ebpret)。

あなたが何をやっているのか、また64bモードで赤いゾーンに書き込むのを知っている場合を除き、決しての値をタッチしないでください。確かでない場合は99%でバグとして終了します。非常に頻繁に見つけにくいものの1つで、まれにしかコードには影響しません。

3)NASMでこれらの4 MOVSは、単一のDWORD定数mov [esp-4],dword 'emos'で行うことができます(ところで、あなたはおそらく'some'を設定したいのですか?)

そして、はい、それはコンパイラがローカルに短い定数を設定する方法の一般的な方法です割り当てられたスタックスペースを使用すると、より大きいデータの場合、定数テンプレートデータからmemcpyを使用することができます。

4)約get_var2()ですので、get_var2()は安定した(char *)ポインタを返しますか?文字列内にすでにいくつの文字があるのか​​を知ることができなければ、strcatを再実装する必要があります。 get_var2()が何らかの値を返す場合は、最初にそれをいくつかの文字に変換して、何個などを決定した後、それらを直接書き込むか、あるループで書くことができます。

また、ローカルスタック上で動作する場合、境界を超えて数バイトを上書きする場合に備えて、変数の周りに安全スペースを割り当てます。また、余分なバイトをいくつかのカナリ値に設定し、関数の終了時にそれをチェックして、スタックオーバーライトが起こったかどうかを確認することもできます(少なくともデバッグビルドで)。 strcatの代わりに、strncatまたはそれに類するものが必要です。悪意のあるデータによるスタックオーバーランを避けるためです。

そうでない場合は、固定メモリバッファに最初にstrcatを実装するようにしてください。ローカルメモリの割り当てを解決するのではなく、コード自体に集中できます。その後、関数呼び出しとして使用することもできます。

+0

'1)sub esp、0xff少なくとも4単位でespを整列させてください。' - なぜ4? – Kevin

+0

@Kevin:x86では、アライメントのとれていないメモリアクセスであっても、ほとんどの場合パフォーマンスが低下します。しかし、特定のSIMD(およびFP?)命令では、不正なメモリアクセス(通常は16Bアライメントが必要で、通常は64b呼び出し規約では必須ですが、32bでは必須ではありません)でクラッシュします。パフォーマンス上の理由から、決してそれを行うことはできません。 1〜3バイトのスペアリング以外の利点はありません。これは、x86の世界では関係のないものです(データ構造でもメンバを整列させ、これよりも多くのバイトを浪費します)。 – Ped7g

関連する問題