2014-11-15 2 views
0

프로세스의 일부 모듈을 언로드하려고합니다.프로세스의 모듈을 강제로 언로드하십시오.

나는이 기능을 사용

bool UnInjectDll(const TCHAR* ptszDllFile, DWORD dwProcessId)  
{  
    if (NULL == ptszDllFile || 0 == ::_tcslen(ptszDllFile))  
    {  
     return false;  
    }  
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;  
    HANDLE hProcess = NULL;  
    HANDLE hThread = NULL;  
    hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);  
    if (INVALID_HANDLE_VALUE == hModuleSnap)  
    {  
     return false;  
    }  
    MODULEENTRY32 me32;  
    memset(&me32, 0, sizeof(MODULEENTRY32));  
    me32.dwSize = sizeof(MODULEENTRY32);  
    if(FALSE == ::Module32First(hModuleSnap, &me32))  
    {  
     ::CloseHandle(hModuleSnap);  
     return false;  
    }  
    bool isFound = false;  
    do  
    {  
     isFound = (0 == ::_tcsicmp(me32.szModule, ptszDllFile) || 0 == ::_tcsicmp(me32.szExePath, ptszDllFile));  
     if (isFound) 
     {  
      break;  
     }  
    } while (TRUE == ::Module32Next(hModuleSnap, &me32));  
    ::CloseHandle(hModuleSnap);  
    if (false == isFound)  
    {  
     return false;  
    }  
    hProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION, FALSE, dwProcessId);  
    if (NULL == hProcess)  
    {  
     return false;  
    }  
    LPTHREAD_START_ROUTINE lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "FreeLibrary");  
    if (NULL == lpThreadFun)  
    {  
     ::CloseHandle(hProcess);  
     return false;  
    }  
    hThread = ::CreateRemoteThread(hProcess, NULL, 0, lpThreadFun, me32.modBaseAddr , 0, NULL);  
    if (NULL == hThread)  
    {  
     ::CloseHandle(hProcess);  
     return false;  
    }  
    ::WaitForSingleObject(hThread, INFINITE);  
    ::CloseHandle(hThread);  
    ::CloseHandle(hProcess);  
    return true;  
} 

을하지만 그것은 할 수없는이 코드 특수 모듈을 사용할 때 내가 프로젝트에서 언로드 할 것인지.

나는 또한 이것을하기 위해 "process detective"도구를 사용하지만이 도구도 이것을 할 수 없다.

이제 원하는 프로세스에서 특수 모듈을 언로드하는 기능을 원합니다. 예를 들어 메시지 상자 만 보여주는 간단한 프로그램을 만들면 이제는 프로세스의 모듈을 볼 수 있습니다. ntdll.dll 모듈과 다른 모듈을 가지고 있습니다. 이제 ntdll.dll 모듈이나 다른 모듈을 제거 할 수 없습니다 . 프로세스가 원하는 프로세스에서 모듈을 제거하도록하는 함수가 필요합니다.

+1

들여 쓰기가 많을까요? 그리고 코드가 무엇을 원하는지, 작동하지 않는 것이 무엇인지 설명하십시오 ... 어떤 단계가 실패하고, 어떤 단계가 다른 것으로 예상되는지/일어나지 않습니까? –

+0

FreeLibrary()를 호출 할 수 있도록 DLL을 삽입해야합니다. 닭고기와 달걀 문제는 분명해야합니다 :) DLL에서 코드를 실행하려고 시도하기 때문에 대상 프로세스가 충돌하는 매우 높은 확률은 어려운 방법을 찾아내는 것입니다. –

+0

@HansPassant 정적으로로드 된 DLL의 핸들에서'FreeLibrary'를 시도하는 것이 효과적이지 않습니다.재미있게도'FreeLibrary'에 대한 호출은 TRUE를 리턴하지만 lib가 언로드되지 않았지만 마지막 에러는 0입니다 ... 허. – PuerNoctis

답변

1

당신이하려는 일은 완전히 위험합니다 (그리고 내 지식으로는 운 좋게도 불가능합니다).

프로그램이나 라이브러리가 다른 특정 DLL과 연결되어 있습니다. 그 대신에이 라이브러리는 다른 라이브러리를 참조하는 식으로 계속 진행됩니다. 프로그램이나 DLL이 Windows의 로더에 의해 메모리 공간에로드되면 이러한 "종속성"도로드되고 가져 오기 주소 테이블에 패치가 적용되므로 실행시 점프 할 위치를 알 수 있습니다. 모든 코드는 원자 엔티티로 함께 고정 배선됩니다.

그런 식으로 정적으로 링크 된 DLL을 언로드하면 (.dll 파일도 정적 .lib 파일과 혼동하지 않고 정적으로 연결할 수 있습니다.) 기본적으로 응용 프로그램이 두 번째 호출을 중단하도록합니다. 그 libarary - 특히 ntdll.dll이 링크 된 모든 libs의 대부분의 뿌리가 될 것입니다. 전화가 무효화됩니다. 이러한 라이브러리는 프로그램에서 의미가 있기 때문에 언로드 할 수 없습니다.

그러나 런타임에 라이브러리를 동적으로로드 한 경우 원하는 언제든지 언로드 할 수 있습니다. 어쨌든 GetProcAddress을 사용하여 동적 주소를 통해 작업하고 있기 때문에 함수 포인터에 유효한 대상이 있는지 확인하는 것은 사용자의 몫입니다. 나는 알고 있지만

그것은 완전히 귀하의 질문에 대답하지 않습니다)

는 당신과 당신이 원하는 어떤 방식으로 떨어져 모자를 취할 수 있지만, 당신은 할 수 없습니다 (그리고 안) 당신의 마음을 찢어 그러나 이것이 단지 당신이 결코 당신이 정말로 알지 못하는 아주 좋은 이유없이 이것을해야한다는 경고 일 뿐이지 만, 나는 당신이 요구하는 것을 할 수 없다는 것을 매우 긍정적으로 생각합니다. 그러나 나는 행복합니다. 다른 사람들이 여기에서 나를 바로 잡을 수 있도록.

로드 된 라이브러리에 무언가를하고 싶고 이미이 파괴적인 코스에 올라가고 싶다면 메모리의 라이브러리 또는 IAT를 직접 덮어 씁니다. 당신은 쇠 지렛대로 들어갈 수 있습니다. 그러나 나는 당신이 찾고있는 것을 얻지 못할 것이라고 생각합니다. ...

관련 문제