2011-12-31 4 views
1

작성한 DLL을로드하고 원격 함수를 실행하는 원격 스레드를 생성하려고합니다. DLL이 정상적으로 작동하지만 (확인 됨) 어떤 이유로 원격 스레드가 실패하고 해당 프로세스가 응답을 멈 춥니 다. 원격 스레드가 오류가있는 LoadLibrary 호출에 실패했습니다.

나는 시도하고 무슨 일이 잘못보고 ollyDebug을 사용하고 내가 올바르게 원격 스레드
  • 스레드에 전달되는 두 가지 ...

    1. 내 문자열 (DLL 이름과 함수 이름을) 발견 lasterror 코드 87 "ERROR_INVALID_PARAMETER"로에서 LoadLibrary에 실패

    내 추측이다 든, 원격 스레드에서 LoadLibrary를 (찾을 수 있다는 것입니다이 링커가 내 였는지를 ???, 그냥를에 repspect으로 수행되기 때문에 추측 ...)

    내가 뭘 잘못하고 있니?

    원격 함수의 코드는 다음

    static DWORD WINAPI SetRemoteHook (DATA *data) 
    { 
        HINSTANCE dll; 
        HHOOK WINAPI hook; 
        HOOK_PROC hookAdress; 
    
        dll = LoadLibrary(data->dll); 
    
        hookAdress = (HOOK_PROC) GetProcAddress(dll,data->func); 
        if (hookAdress != NULL) 
        { 
        (hookAdress)(); 
        } 
        return 1; 
    } 
    

    편집 :

    typedef struct 
    { 
        char* dll; 
        char* func; 
    } DATA; 
    
    char* dllName = "C:\\Windows\\System32\\cptnhook.dll"; 
    char* funcName = "SetHook"; 
    char* targetPrgm = "mspaint.exe"; 
    Data lData; 
    lData.dll = (char*) VirtualAllocEx(explorer, 0, sizeof(char)*strlen(dllName), MEM_COMMIT, PAGE_READWRITE); 
    lData.func = (char*) VirtualAllocEx(explorer, 0, sizeof(char)*strlen(funcName), MEM_COMMIT, PAGE_READWRITE); 
    WriteProcessMemory(explorer, lData.func, funcName, sizeof(char)*strlen(funcName), &v); 
    WriteProcessMemory(explorer, lData.dll, dllName, sizeof(char)*strlen(dllName), &v); 
    rDataP = (DATA*) VirtualAllocEx(explorer, 0, sizeof(DATA), MEM_COMMIT, PAGE_READWRITE); 
    WriteProcessMemory(explorer, rDataP, &lData, sizeof(DATA), NULL); 
    

    편집 :

    이 I 원격 였는지를 상기 메모리를 할당하는 부분이다 : 문제는 원격 스레드가 LoadLibrary 기본 주소 대신 "쓰레기"주소를 호출하고있는 것 같습니다. 가능성이 원격 스튜디오 LoadLibrary 주소가 잘못 연결된 비주얼 스튜디오가 있습니까?

    편집 : 로컬 스레드와 동일한 정확한 코드를 실행하려고하면 (CreateRemoteThread의 현재 procces에 대한 핸들을 사용함) 모든 것이 올바르게 작동합니다. 무엇이 이것을 일으킬 수 있습니까?

    호출 기능 코드를 추가해야합니까? 그것은 코드를 올바른 매개 변수를 사용하여 원격 스레드에서 실행되고있는 것으로 보인다 ...

    코드는 VS2010에서 컴파일됩니다.

    데이터는 이름에 char *를 가진 간단한 구조체입니다. (코드에 문자열을 명시 적으로 작성하면 원래의 프로세스에 대한 포인터가 생깁니다.)

    내가 뭘 잘못하고 있니?

  • +0

    당신은 명시 적으로 DLL 경로에서 LoadLibrary를 사용하려고 노력 해요? 예 : LoadLibrary ("C : \\ project \\ my_app.dll"); 매개 변수가 전달되는지 확인하기 만하면 OK – marcinj

    +0

    예. 나는 전체 경로를 사용하고있다. (exe와 dll이 같은 디렉토리에 있기 때문에 dll 이름만으로도 작동해야합니다.) 또한 LoadLibrary 함수가 실패한 사실은 추측이라고 언급해야합니다. (나는 그것이 하나의 매개 변수를 가진 함수이며 올바른 경로임을 LoadLibrary와 같이 볼 수 있습니다 ...) –

    +0

    "데이터"를 원격 스레드에 어떻게 전달합니까? "데이터"가 가리키는 메모리를 어떻게 할당하고 채우고 있습니까? –

    답변

    1

    ERROR_INVALID_PARAMETER으로 실패하면 전달 된 매개 변수에 문제가 있음을 나타냅니다.

    문제의 유일한 매개 변수 인 data->dll을 확인해야합니다.

    이 여기에 초기화된다

    lData.dll = VirtualAllocEx(explorer, 0, sizeof(char) * (strlen(dllName) + 1), MEM_COMMIT, PAGE_READWRITE);

    은 그럼 참조 lData.dll에 저장해야한다의 메모리의 할당이 정말 succeded 여부 검사를 추가 할 수 있습니다.당신이되지 않은 페이지를 저지하려고하면

    기능이 실패

    if (!lData.dll) { 
        // do some error logging/handling/whatsoever 
    } 
    

    당신이 구현 된 호출이 있기 때문에 (그대로 VirtualAllocEx()에 대한 MSDN에서) 실패 감지 수도, 그렇게 데 예약 됨. 결과 오류 코드는 ERROR_INVALID_ADDRESS입니다. (MSDN에서 다시 그대로) 권장

    그래서 당신은 문제의 호출의 네 번째 매개 변수를 modifiy하는 것 같아서 :

    가 예약 및 커밋 페이지를 한 번에, MEM_COMMIT으로하고 VirtualAllocEx를 호출하려면 | MEM_RESERVE.

    추신 : lData.func을 호출 할 때이 연습을 반복하십시오. ;-)

    0

    LoadLibrary가 실제로 유니 코드 버전 인 LoadLibraryW (프로젝트 설정에 따라 다름) 일 수 있습니다. "TCHAR"대신 "char"문자열을 사용하여 Windows API를 사용할 때마다 명시 적으로 ANSI 버전 이름을 사용해야합니다. 이렇게하면 코드가 작성 될 때 디버깅 혼란을 방지 할 수 있으며, 앞으로 프로젝트가 유니 코드로 전환되는 경우에 대비하여 앞으로 또는 다른 사람을 위해 디버깅 혼란을 방지 할 수 있습니다.

    그래서 끔찍한 종결되지 않은 문자열 문제가 사용할 수 있는지 확인하는 것이 고정에 추가 :

    LoadLibraryA(data->dll); 
    
    관련 문제