4

数日前、単一の呼び出し命令にパッチを当てて簡単なフック/迂回路を書きました。Ubuntu 12.xyz (32 ビット) で動作しましたが、Linux Mint 17.1 (32 ビット) に更新すると、セグメンテーション エラーが発生します。

私は2つのプロジェクトを持っています

  • goodGuy という名前の関数を呼び出すターゲット プロジェクト
  • ターゲット アプリケーションの呼び出し命令からのオフセットを上書きする dlopen() によってロードされたライブラリ プロジェクト

呼び出し命令のオフセットを上書きする前に、ページの保護を次のように変更します。

mprotect(pageOf(address),pagesize,PROT_WRITE|PROT_EXEC|PROT_READ)

これは正常に機能します (0 を返します)。

プログラムをデバッグすると、呼び出しのアドレスに書き込もうとしてクラッシュします。

memcpy((void*)(address + 1),(void*)&callOffset,4);

命令を上書きすることは許可されていないようですが、なぜですか?

ALSR を無効に-z execstack -fno-stack-protectorし、g++ でフラグを使用しました。

私のアプリケーションが命令を書くことを許可する方法を知っていますか?

ありがとう、アレックス

編集

申し訳ありませんが、コードは次のとおりです。

対象アプリケーション:

#include <dlfcn.h>
#include <stdio.h>
#include <stdio.h>
#include <iostream>

void goodGuy();
//full lib path !
char libPath[] = "INSER_YOUR_PATH_HERE/lib.so";

int main(){
  dlopen(libPath,RTLD_NOW);
  goodGuy();
  return 0;
}

void goodGuy(){
    printf("good guy :)\n");
}

および共有ライブラリ コード:

#include <stdio.h>
#include <cstring>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>

void badGuy();

int pagesize = sysconf(_SC_PAGESIZE);

void *pageOf(void* p){
    return (void*)((unsigned int)p & ~(pagesize - 1));
}

extern "C" void __attribute__ ((constructor)) DllLoad(void){
    uint32_t addressOfCall = 0x0804862a; //Address where goodGuy is called in target app
    uint32_t addressOfNextInstruction = addressOfCall + 5;
    uint32_t callOffset = (uint32_t)badGuy - addressOfNextInstruction;

    mprotect(pageOf((void*)(addressOfCall + 1)),pagesize, PROT_WRITE|PROT_EXEC|PROT_READ);
    memcpy((void*)(addressOfCall + 1),(void*)&callOffset,4);
}

void badGuy(){
  printf("bad guy :(\n");
}

addressOfCall を見つけるには、gdb でターゲット アプリケーションを開き、gdb targetmain 関数を表示しdisas mainて、+29

gdb$ disas main
Dump of assembler code for function main()
   0x0804860d <+0>: push   ebp
   0x0804860e <+1>: mov    ebp,esp
   0x08048610 <+3>: and    esp,0xfffffff0
   0x08048613 <+6>: sub    esp,0x10
   0x08048616 <+9>: mov    DWORD PTR [esp+0x4],0x2
   0x0804861e <+17>:    mov    DWORD PTR [esp],0x804a060
   0x08048625 <+24>:    call   0x80484f0 <dlopen@plt>
    ___________
   |0x0804862a| <+29>:  call   0x8048636 <goodGuy()>
   |__________|
   0x0804862f <+34>:    mov    eax,0x0
   0x08048634 <+39>:    leave  
   0x08048635 <+40>:    ret    
4

0 に答える 0