2010-08-05 2 views
5

C++ 프로그램에서 메서드 호출을 중재해야합니다 (이 클래스는 별도의 공유 라이브러리에 있습니다). 나는 LD_PRELOAD를 사용할 수 있다고 생각했지만, 어떻게 작동 할 지 확신하지 못했다. (나는 C 함수의 예제를 발견했다.) 개입 된 클래스 구현에서 어떤 코드를 복사하지 않고 단일 메소드의 개입을 설정하는 방법이 있는가?C++ 클래스 메서드에 대한 LD_PRELOAD

답변

2

이식성이 좋지는 않지만 C에서 삽입 기능을 작성하고 C++ 방법의 변환 된 이름을 지정할 수 있습니다. 물론이 매개 변수를 명시 적으로 처리해야하지만 모든 ELF ABI는이를 보이지 않는 첫 번째 인수로 처리한다고 생각합니다.

+0

나는 당신에게 동일한 질문을 가지고 있습니다. 어떻게 원래의 C++ 메서드를 호출합니까? 이 메소드가 그 이름을 숨기는 것처럼 보입니다 ... – BruceBerry

+0

'dlsym (RTLD_NEXT, "mangled_name_of_function")'. 그건 그렇고 내 기술도 Tony도 가상 함수로 작동하지 않는다. (가상 함수라면 그냥 서브 클래스에서 오버라이드 할 수 있겠는가?) – zwol

+0

클라이언트를 만지지 말아야하기 때문에 무시하지 말아야한다. 객체를 인스턴스화하는 코드. 이 방법은 가상은 아니지만 분명히 나에게 맞는 방법은 없습니다. -/ – BruceBerry

6

삽입 된 코드에 대한 파일을 만듭니다 (구현이 라인 외부에 있는지 확인하십시오) ... 네임 스페이스, 클래스 이름 및 함수는 가로 채기를 원하는 메소드와 동일해야합니다. 클래스 정의에서 가로 채지 않으려는 다른 메소드에 대해서는 언급하지 마십시오. LD_PRELOAD는 인터셉트 공유 객체에 대한 전체 경로가 필요하다는 것을 기억하십시오.

예를 들어,있는 파일 libx2.cc 작성) 무효 X ::을 Fn1을 (가로 챌 수 :

 
#include <iostream> 

class X 
{ 
    public: 
    void X::fn1(); 
}; 

void X::fn1() { std::cout << "X2::fn()\n"; } 

를 그리고 그것을 컴파일 :

 
g++ -shared -o libx2.so libx2.cc 

그런 다음

람 실행
 
LD_PRELOAD=`pwd`/libx2.so ./libx_client 

건배

+0

이것은 덜 해킹 것 같습니다. 그건 그렇고, – BruceBerry

+0

시도해 보겠습니다.이 새로운 메서드에서 원래의 메서드를 어떻게 호출합니까? – BruceBerry

+0

Yikes - 방금 귀하의 질문에 주목했습니다. Linux (only)에서는 dlsym (RTLD_NEXT, "name")을 사용할 수 있습니다 - 이것은 명시 적으로 검색 함수와 일치하지 않는다고 말하고 나중에로드 된 객체에서 하나를 찾습니다. 다른 OS의 경우 잘 모르겠습니다 만 Linux에서 이식성에 대해 말하는 웹 페이지가 있어야하므로 RTLD_NEXT 검색이 좋습니다. Doh - Zack은 다년 전에 감사했습니다. –