이번에는 DLL도 Injection 하여 코드 후킹을 해보았다.
아래 코드는 DLL의 일부이다.
void HookCode(void) { HMODULE hMod; HANDLE hProc = NULL; //Destination Function Address LPVOID pDestFuncAddr; DWORD pGapOfAddress; DWORD dwOldProtect; BYTE NewBytes[5]={0xE9,0,}; // dll의 handle을 구한 뒤 목적함수의 주소를 구함 hMod = GetModuleHandle("KERNEL32.dll"); pDestFuncAddr = (LPVOID)GetProcAddress(hMod,"CreateFileW"); /* JMP 주소 계산 = (이동할 주소) - (현재 주소) - 5(명령어 길이) */ pGapOfAddress = (DWORD)&MyHookFunc - (DWORD)pDestFuncAddr - 5; // 목적지 주소의 원래 5바이트값을 백업 memcpy(g_pOrgBytes, pDestFuncAddr, 5); // 새로 덮어씌울 5바이트값 memcpy(&NewBytes[1], &pGapOfAddress, 4); // 목적지 주소의 가상메모리 권한 변경 /* VirtualProtect(변경할 시작 주소, 변경할 크기(BYTE), 새로 부여할 권한, 기존 권한을 저장할 공간) */ VirtualProtect(pDestFuncAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect); // 새 Opcode 덮어씌움 memcpy(pDestFuncAddr, NewBytes, 5); // 가상메모리 권한 복원 VirtualProtect(pDestFuncAddr, 5, dwOldProtect, &dwOldProtect); } void MyHookFunc(void) { UnHookCode(); MessageBox(NULL,"you are hacked!","알림",MB_OK); }
VirtualProtect() 함수를 이용하여 후킹할 함수의 시작주소로부터 5바이트의 영역을 쓰기권한을 주어
원하는 코드를 삽입할 수 있게 했다.
이번에 후킹한 함수는 CreateFileW()함수로 파일을 저장하기위해 주로 이 함수를 이용한다.
아래 코드는 위 DLL을 원하는 프로세스로 삽입시키는 Injector의 일부이다.
DWORD dwPID = 0xFFFFFFFF; if(argc != 2) { printf("Injector.exe [ProcessName]"); return 1; } //find process dwPID = FindProcessID(argv[1]); if(dwPID == 0xFFFFFFFF) { printf("There is no <%s> process!\n",argv[1]); return 1; } //nject dll InjectDll(dwPID, DEF_DLL_PATH);
매개변수로 프로세스의 이름을 받아서 PID를 구한 후 InjectDll을 호출한다.
BOOL InjectDll(DWORD dwPID, LPCTSTR szDllName) { int ForError=0; HANDLE hProcess, hThread; HMODULE hMod; LPVOID pRemoteBuf; DWORD dwBufSize = lstrlen(szDllName) + 1; LPTHREAD_START_ROUTINE pThreadProc; // dwPID 를 이용하여 대상 프로세스의 HANDLE을 구함 if( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) ) //실패시 NULL 성공시 프로세스핸들 return FALSE; // 대상 프로세스메모리에 szDllName(dwBufSize) 크기만큼 메모리를 할당 pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE); //성공시 할당된 메모리 주소(대상 프로세스 가상메모리) // 할당 받은 메모리에 myhack.dll 경로를 씀 ForError = WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL); if( !ForError ) return FALSE; // LoadLibraryA() API 주소를 구함 hMod = GetModuleHandle("kernel32.dll"); pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"LoadLibraryA"); // 대상프로세스에 스레드를 실행 hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL); WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); CloseHandle(hProcess); printf("모두 끝남"); return TRUE; }
PID값을 이용하여 대상 프로세스에 대한 HANDLE을 구함
VirtualAllocEx() 함수를 이용하여 대상 프로세스의 가상메모리에 메모리를 할당
WriteProcessMemory() 함수를 이용하여 dll의 경로를 할당 받은 메모리에 씀
CreateRemoteThread() 함수를 이용하여 대상프로세스에 스레드 실행
이것을 이용하여 메모장을 후킹해 보았다.
먼저 Injector를 실행했다.
ProcessExplorer로 확인해 보니 삽입이 잘 되어 있다.
이제 "저장"버튼을 눌러서 CreateFileW()을 호출할 수 있게끔 했다.
버튼을 누르자
메시지박스를 띄우며 종료된다.
[소스 코드] :
'리버스엔지니어링 > API Hooking' 카테고리의 다른 글
Win32 API Hooking - Trampoline Code Hooking (0) | 2015.05.29 |
---|