2013-03-03 2 views
1

Qt 프레임 워크를 사용하여 빌드 된 제 3 자 실행 파일에 DLL을 주입하는 C# 응용 프로그램을 작성했습니다. 이 DLL은 EasyHook을 사용하여 여러 특정 기능에 대한 호출을 차단합니다. 주입 된 코드가 호출되면, 나는이 함수에 대한 매개 변수 인 객체의 일부를 검사하려고 시도합니다.C#에서 C++/CLI를 통해 네이티브 객체에 액세스!

static extern bool XmlParse(IntPtr Reader, IntPtr Source) 

내가 싶습니다 :

예를 들어, 나는 몇 가지 XML 구문 분석 만든 전화 도청 한 내 C# 코드에서

virtual bool __thiscall QXmlSimpleReader::parse(class QXmlInputSource const &) 

을,이 일치하는의 PInvoke 서명이 "Source"클래스의 멤버 인 "data()"함수를 호출하십시오. 즉, QXmlSimpleReader는 QXmlInputSource에서 원시 XML을 구문 분석하지만, 그렇게하기 전에이 "data()"함수를 통해 원시 XML을 조사하려고합니다.

여기 전문가 중 한 분의 조언으로 C++/CLI를 사용하여 개체에 기본적으로 액세스하려고했습니다 (Calling methods in third-party DLLs 참조).

헤더 : 나는 C# 코드에서 IntPtr입니다을 받아 C++에서 래퍼 객체를 구축 한

public ref class QXmlInputSource 
{ 
public: 
    // Constructor must be called with C# IntPtr 
    QXmlInputSource(IntPtr Ptr); 

    bool LoadQt(void); 
    bool UnloadQt(void); 

    String^ Data(); 

private: 
    // Pointer to the native Qt object 
    void * Native; 
    HINSTANCE DllHandle; 

    // SIGNATURE: virtual QString QXmlInputSource::data() const 
    typedef void * (__thiscall *QXmlInputSource_Data)(void *); 
    QXmlInputSource_Data fpData; 
}; 

CPP 파일 :

QXmlInputSource::QXmlInputSource(IntPtr Ptr) 
{ 
    LoadQt(); 
    Native = Ptr.ToPointer(); 
} 

bool QXmlInputSource::LoadQt(void) 
{ 
    FARPROC Addr; 

    /* get handle to dll */ 
    std::wstring LibName = QtPath + QtXml; 
    DllHandle = LoadLibrary(LibName.c_str()); 

    /* get pointer to the function in the dll*/ 
    Addr = GetProcAddress(HMODULE (DllHandle), "[email protected]@@[email protected]@XZ"); 
    fpData = QXmlInputSource_Data(Addr); 

    return true; 
} 

bool QXmlInputSource::UnloadQt() 
{ 
    /* Release the Dll */ 
    FreeLibrary(DllHandle); 
    return true; 
} 

String^ QXmlInputSource::Data() 
{ 
    void* Ptr = fpData(Native); 
    return "EPIC FAIL"; 
} 

Qt는 기반 응용 프로그램 충돌을 내가하려고 fpData() 함수 포인터를 호출하십시오. 도움말 : P

몇 가지 추가 정보 또는 도움이되지 않을 수 있습니다 :

  • 을 나는 성공적를 사용하여 같은 QString.count()와 QString.data (같은 "간단한"객체)에 기능을 불렀다 같은 방법론. (QString 표준 유니 코드 문자열에 대한 그냥 경량 래퍼 것).

  • 내가 관심이있는 XML 함수가 포함 된 QtXml4.dll 파일에는 실제로 두 개의 parse() 메소드가 있습니다. 하나는 소스가 const &이고 다른 하나는 소스입니다. 나는 둘 중 하나를 사용해야하는지 잘 모른다. 나는 어떤 경우에도 내 서명이 변하지 않을 것이라고 생각합니다.

  • 내가 주위를 재생하려고 동안, 나는 C# 코드에서 IntPtr입니다을 역 참조와 C++에 전달 시도 :

    IntPtr입니다 DerefSrc = (IntPtr입니다) Marshal.PtrToStructure (출처의 typeof (IntPtr입니다)); 대략 메모리에 QtXml4.dll의 주소와 일치 - 나는이 두 IntPtrs의 값을 출력하면 DerefSrc는 1.6GB의 값을 가지고있는 동안

는, 소스, 3.5MB 주위의 값을 갖는다. 내 생각에 DerefSrc는 절대 참조 인 반면 3.5Mb는 상대적 오프셋입니다. DerefSrc를 상대 주소로 변환하고 대신 C++로 전달하는 것이 가치가 있습니까? 당신은에서 LoadLibrary와 GetProcAddress를의 반환 값을 확인하지 않는 :

1 :

+1

코드 삽입의 첫 번째 규칙은 절대 최소 코드를 삽입하는 것입니다. 이로 인해 C++/CLI는 ** 매우 열악한 후보입니다. 또한 지터와 CLR을 주입하여 실행시켜야합니다. 당신이 그것을하는 방법을 알아낼 수있을 확률은 0입니다. 계산을 해보더라도 프로세스에 이미 CLR이로드되어 있으며 잘못된 버전 일 가능성이 높습니다. 이것을 시도하지 마십시오. –

+0

우리는 결투 전문가의 경우가 있습니다 !! 이전 질문에 대한 링크와 David Heffernan의 답변을 참조하십시오. –

+0

이전 질문은 코드를 다른 프로세스에 주입하는 것이 아닙니다. –

답변

1

나는 몇 가지 문제를 참조하십시오. QXmlInputSource :: data도 DLL에서 내 보낸 메소드입니까? 그렇지 않으면 GetProcAddress가 분명히 실패합니다.

2 : 어떻게 QXmlInputSource 클래스를 인스턴스화합니까? 나는 당신이 C# 코드에서 그렇게하려고 노력하고있는 것처럼 보이기 때문에, 올바르게하기는 어렵다. (클래스에 필요한 크기를 알아야하고, 그 크기의 메모리를 적절히 정렬하고, 생성자를 호출해야한다. 그것).

3 : 함수 포인터를 호출하는 방식이 잘못되었습니다. 당신은 적절한 유형의 방법 포인터 선언해야합니다 QXmlInputSource에 대한 설명서를 보면

FARPROC fp = ::GetProcAddress(...); 

typedef QString (QXmlInputSource::*DataMethod)(); 
DataMethod mpData = reinterpret_cast<DataMethod>(fp); 

QXmlInputSource source; 
QString data = (source.*mpData)(); 

4 :을 : 데이터를, 내가 당신 같은 (포인터에서 비참과 다른 QString를 반환 참조 현재 치료 중). System.String으로 변환하려면 다음과 같은 코드가 필요합니다.

QString s1 = (QChar*)L"example string"; 
String^ s2 = gcnew String((wchar_t*)s1.data()); // calls the String::String(wchar_t*) constructor overload 
+0

1. 죄송합니다. 게시하기 전에 여러 줄의 디버깅 코드를 제거했습니다.이 중 하나는 GetLastError()를 검사하고 0을 반환합니다. 2. 어디서나 원시 QXmlInputSource 객체를 인스턴스화하지 않습니다. 이미 존재하는 객체에 대한 포인터를 취하는 래퍼 클래스를 인스턴스화합니다. 기본적으로 Qt 기반 응용 프로그램 내에서 전달되는 데이터를 스눕 (snoop)하기위한 목표를 기억하십시오. 내 자신의 객체를 인스턴스화하면 그냥 공백이 될 것입니다 ... 3. & 4 나는 오늘 이것들을 가지고 놀 것입니다. –

+0

저는 이미 붙어 있습니다 : P 게시 한 코드 조각은 QString, QChar 및 QXmlInputSource 클래스에 네이티브 클래스로 액세스 할 수 있다고 가정합니다. 하지만 나는 그렇지 않습니다! 게시 한 헤더 및 소스 파일은 단순히 네이티브 객체의 주소를 가리키는 void 포인터를 사용하는 래퍼입니다. QtXml4.dll은 타사 라이브러리이므로 가져올 lib 파일이 없습니다. 나는 아직 Qt 환경을 다루지 않았지만, lib 파일을 얻을 수는 있습니다 .. –

+0

예, Qt 용 .lib 파일을 얻을 수 있습니다. 그럼 당신은 모든 GetProcAddress 및 함수 포인터 물건을 피할 수 있고 .lib 파일의 메소드를 타겟 실행 파일에서 생성 된 객체에서도 호출 할 수 있습니다.하지만 Qt 라이브러리의 버전이 일치하는지 확인해야합니다. 어쨌든, 나는이 경로를 더 진행하기 전에 Hans Passant의 의견을 고려할 것입니다. 나는 DLL 주입에 익숙하지 않다. – user1610015