2010-12-16 8 views
10

私はAndroid上で自己修正ネイティブコードを作成し、それをエミュレータで実行しようとしています。私のサンプルは、android-ndkのHelloJNIサンプルに基づいています。Androidのネイティブの自己修正コード

#define NOPE_LENGTH 4 

typedef void (*FUNC) (void); 

// 00000be4 <nope>: 
//  be4: 46c0  nop   (mov r8, r8) 
//  be6: 4770  bx lr 
void nope(void) { 
    __asm__ __volatile__ ("nop"); 
} 

void execute(void){ 
    void *code = mmap(NULL, NOPE_LENGTH, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 

    if (code != MAP_FAILED) { 
     memcpy(code, nope, NOPE_LENGTH); 

     ((FUNC)code)(); 
    } 
} 

問題はこのコードがクラッシュしていることです。なにが問題ですか?

+2

注:実際にコードを変更する場合は、命令キャッシュをフラッシュする必要があります。ARMのIキャッシュとDキャッシュは一貫性がないため、特定の場所で値を見ることができても、CPUそれが実行しようとすると、それらを表示します。 Dalvikは、JITコンパイラの実装でLinux cacheflush(2)を使用しています。 – fadden

答えて

11

推測すると、nope()はThumbとしてコンパイルされましたが、あなたはそれをARMと呼んでいます(mmapがワードアラインされたポインタを返すと仮定します)。 Thumbコードを呼び出すには、アドレスの下位ビットを設定する必要があります。 、あなたが実行しようとしているコードがThumbであることを確認して、割り当てられたメモリ(親指とARMのために4用2)の整列を保証する必要があり、それを正しく行うには

((FUNC)(((unsigned int)code)|1))(); 

(または:このような何かを試してみてくださいARM)を使用し、それに応じてビット0を設定します。

+0

ありがとうございます。 -marmオプションを指定してコードをコンパイルし、メモリブロックの適切な配置を指定してコードを正常に実行しました。 –

関連する問題