2013-02-10 4 views
0

자기 자신의 프로세스에서 IAT 후킹에 관한 질문을하고 싶습니다.IAT Hooking 자신의 프로세스에 대한 ExitProcess

현재 ExitProcess를 호출하기 전에 특정 함수를 실행하므로 일부 문제가 발생합니다.

내가 가진하지만, 내가 거기에 ExitProcess를 찾기 위해 노력하고, THUNK_DATA-의 이름을 통과하고 (첫 번째 .DLL 인)가 KERNEL32.DLL을 발견 한 후, IMAGE_IMPORT_DESCRIPTOR를 통해 가는, 런타임에 PE를 통과하고 불운.

GetModuleHandleA 
GetProcAddress 
LoadLibraryA 
GetModuleFileNameW 
FreeLibrary 
VirtualQuery 
GetProcessHeap 
HeapFree 
HeapAlloc 
GetSystemTimeAsFileTime 
GetCurrentThreadId 
GetCurrentProcessId 
QueryPerformanceCounter 
IsProcessorFeaturePresent 
WideCharToMultiByte 
MultiByteToWideChar 
LoadLibraryW 
lstrlenA 
LoadLibraryExW 
GetLastError 
RaiseException 
IsDebuggerPresent 
DecodePointer 
EncodePointer 
GetModuleHandleW 

비록 ExitProcess 내에서 아무데도 - 기능을 로깅

, 사람들이 발견되는 기능은 다음과 같습니다.

필자는 실패했지만 이름 대신 함수 포인터 (예 : originalthunkdata 대신 thunkdata 사용)로 열거를 시도했습니다.

ExitProcess 용 GetProcAddress는 PE 내에서 포인터를 반환하지만 loadlibrary가 강제로 kernel32.dll을로드하려고 시도했지만 결과는 동일하지만 강제로로드하려고했습니다.

무엇이 문제 일 수 있습니까?

HMODULE hMod = GetModuleHandle(NULL); 
PIMAGE_DOS_HEADER pImgDosHeaders = (PIMAGE_DOS_HEADER)hMod; 
PIMAGE_NT_HEADERS pImgNTHeaders = (PIMAGE_NT_HEADERS)((LPBYTE)pImgDosHeaders + pImgDosHeaders->e_lfanew); 
PIMAGE_IMPORT_DESCRIPTOR pImgImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)pImgDosHeaders + pImgNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 
UINT indx = 0; 
while(strcmpi((PCHAR)((LPBYTE)pImgDosHeaders + pImgImportDesc[indx].Name), "kernel32.dll")) { ++indx; }; 
PIMAGE_THUNK_DATA pImgThunkData = (PIMAGE_THUNK_DATA)((LPBYTE)pImgDosHeaders +pImgImportDesc[indx].OriginalFirstThunk); 
PIMAGE_IMPORT_BY_NAME pImgImportByName = NULL; 
for(;pImgThunkData->u1.Function; ++pImgThunkData) 
{ 
    pImgImportByName = (PIMAGE_IMPORT_BY_NAME)((LPBYTE)pImgDosHeaders + pImgThunkData->u1.AddressOfData); 
    !strcmpi("ExitProcess",pImgImportByName->Name) ? cout << "ExitProcess Found" : false; 
} 
return true; 

대단히 감사합니다.

+0

프로그램에서 사용하는 런타임 지원 라이브러리의 종류가 확실하지 않습니다. 프로그램을 종료시키는 코드가 들어 있습니다. C/C++에서 공통적 인 별도의 DLL 일 수 있습니다. 프로그램은 단순히 엔트리 포인트에서 돌아가거나 TerminateProcess를 호출하여 종료됩니다. –

+1

@Hans : 프로그램은 거의 항상'ExitProcess'를 호출하여 종료됩니다. 진입 점은 결코 반환되지 않습니다. (대부분의 런타임 지원 라이브러리는 사용자가 제공하는 일종의 메인 함수가 반환하도록 허용하고, 런타임은'ExitProcess'를 호출하지만 반환하는 사용자가 제공 한'main' 함수는 엔트리 포인트가 아닙니다) –

+0

당신은 여전히 ​​atexit) 당신이 crt를 사용하는 경우, 또는 당신은 재미 있기 때문에 Iat 후킹을 대신 할 수 있습니다. 내가 작업 코드를 가지고 있지만 불행히도 Windows가 디스크를 망쳤을 때 길을 잃었다. – sherpya

답변

0

ExitProcess()을 앱에서 정적으로 호출하지 않는 경우 (예 : 앱의 RTL이 아닌 경우) 또는 GetProcAddress()을 통해 동적으로로드 한 경우 앱의 IMPORTS 테이블에 표시되지 않습니다 . IMPORTS 테이블에는 앱이 정적으로 링크되는 함수 만 나열됩니다. 이것이 코드에서 찾을 수없는 이유입니다. PEDUMP 또는 DependancyWalker와 같은 유틸리티를 사용하여 앱이 실제로 정적으로 ExitProcess()에 연결되어 있는지 확인하십시오. 예를 들어, 내 dev 환경 (C++ Builder XE2)에서 콘솔 프로젝트를 만들면 ExitProcess()이 IMPORTS 테이블에 없지만 대신 GUI 프로젝트를 만들면 찾을 수 있습니다. 차이점은 두 가지 유형의 프로젝트가 서로 다른 RTL을 사용하기 때문에 앱 RTL이 앱이 종료 될 때 ExitProcess()을 사용하지 않는다는 것입니다.

+0

나는'ExitProcess()'를 정적으로 호출하지 않는 응용 프로그램을 보지 못했다. – JosephH

+0

레미 감사합니다! 그때까지는 사실, 지금까지는 CRT가 자동으로 ExitProcess를 호출 할 것이라고 생각했습니다.이 시나리오에서는 그렇지 않습니다. exit()를 호출하는 코드를 통해 doexit() 등을 호출합니다. 프로그램의 이스케이프를 처리하는 __CRTDoExit()와 비슷한 밑줄 친 함수에 도달합니다. 그 중 실제로는 ExitProcess에 대한 포인터이거나 런타임에 평가됩니다. –

+0

CRT 소스 코드 (공급 업체가 제공 한 경우)를 보거나, ExitProcess() 자체에 중단 점을 넣어서 호출 중인지 확인해야하지만 그렇지 않은 것처럼 들립니다. –