API 후킹 기법 중 DLL 인젝션 기법이 있음 프로세스에 인젝션된 DLL 파일은 IAT를 후킹해 프로세스에서 호출되는 특정 API의 기능을 변경한다.
windows 계산기 프로세스에 사용자 DLL파일을 삽입해서 IAT의 use32 SetWindowTextW() API 주소를 후킹함 후킹당하면 숫자를 한글로 출력..
API 후킹 기법하기로 했으면 후킹 대상 API를 선정해야된다. 그러려먼 후킹을 원하는 기능을 제공하는 API를 찾는거는 어렵다..
파일 생성: kernel32!CreateFile()
레지스트리 생성: advapi32!RegCreateKeyEx()
네트워크 접속: kernel32!ws2_32!connect()
올리디버거로 열어서보면 일케 두개 API 찾을 수 있음 저 젤위에거랑 맨아래 text드간거..
두개 다 텍스트 에디터에 글씨를 써준다. 근데 위에거는 내부적으로 다시 아래거를 호출하니까 여기서는 아래 SetWindowTextW만 후킹하면 된다고 가정한다.
그래서 일케 찾고.. 이거 호출하는 주소에 브레이크 포인트 설치해서 실행한다.
일케나옴 여기다가 7너허보고 실행하면
내가 입력한 문자열 보이는걸 알 수 ㅣㅆ음
여기에 쌓인걸 볼슁ㅆ는데 이걸 한국어로 바꿔보자 한국어 칠은 60 CE
일케하면 ㄱㅖ산기에 칠로 나옴
후킹 동작 원리
프로세스에서 IAT는 프로그램에서 호출되는 API들의 주소가 저장되는 장소임
IAT 후킹이란 IAT에 저장된 API의 주소를 바꾸는 후킹 기법이다..
IAT 후킹 전에 정상적인 호출 흐름 부터 보면
프로그램은 특정 API를 호출하려고 할 때, IAT에서 해당 API의 시작 주소를 읽는다. 예를 들어 프로그램 내의 CALLL 명령ㅇㅣ IAT에 저장된 주소를 통해 특정 API를 호출하게 된다. IAT에는 이 API 함수의 실제 메모리 주소가 저장되어 있고 이 주소를 사용해 API를 호출한다.
IAT 후킹을 적용한 후는 이렇게된다..
IAT 후킹을 위해 사용자 정의 DLL을 대상 프로세스에 인젝션한다. 이 DLL에는 후킹하고자 하는 API를 대신한 사용자 정의 함수가 포함되어있다. 후킹이 적용되면 IAT에 기록된 원래 API의 주소 대신 상요자 저의 함수의 주소로 변경된다. 후킹된 호출흐름에서 프로그램은 여전히 원래 API를 호출하는 것 처럼 보여도 실제로는 변경된 IAT의 주소를 참조하니까 사용자 정의 함수를 먼저 호출한다. 사용자 정의 함수는 필요한 작업을 다 하고 원래 API를 다시 호출한다.
소스코드 분석
DllMain()에서는 SetWindowTextW()주소 저장
case DLL_PROCESS_ATTACH :
g_pOrgFunc = GetProcAdd ress(GetModuleHandle(L"user32.dll"), "SetWindowTextW");
IAT 후킹
hook_iat("user32.dll", g_pOrgFunc, (PROC)MySetWindowTextW);
하고 IAT 언후킹까지..한다
case DLL_PROCESS_DETACH :
hook_iat("user32.dll", (PROC)MySetWindowTextW, gpOrgFunc);
SetWindowTextW()의 후킹함수는 MySetWindowTextW()
여기서는 for루프에서 lpString에 저장된 숫자를 한글로 교체함
그리고 for 루프 종료시 함수 포인터 g_pOrgFunc를 호출해서 DllMain()에서 미리 구해 둔 user32. StWindowTextW() API 시작 주소를 호출한다. 즉 원본 함수 불러서 계산기 에딧 창에 한글 문자를 출력하는거임
IAT 후킹하는 핵심 함수는 hook_iat() 이거 넘 기니까 그냥 깃헙에서 보는게 나을듯
여기서는 PE 헤더 정보를 읽어서 IAT를 따라가는 내용
이렇게 IAT 주소 찾고나면 값을 바꾸는 후킹 코드가 나온다..
인젝션된 DLL의 디버깅
올리디버거로 앞에 실습에서 후킹된거 디버깅해본다 PID 먼저 확인하고.. 올리디버거에 올려서 봄
ㄱㅖ산기에 DLL load되고 나면 올리디버거에서 해당 이벤트는 통지되고 hookiat.dll의 EP에서 실행이 멈추게된다.
dll파일 디버거로 열어본거..
여기서 SetWindowTextW() 문자열이 참조되는 코드 주소로 가면 디스어셈블리 코드 확인가능..
DllMain() 함수는 디버깅ㅅ작하고 hookiat()함수 호출 부분에서 첫 번째 파라미터(uwer32.dll)은 지워져있는걸 볼 수 있음 왜냐면 VC++ 컴파일러의 코드 최적화 때매.. 문자열 주소를 함수 파라미터 대신 하드코딩했으니까다. 초적화 현상은 디버깅 시에 자주 발생함..
hook_iat()는 실제 IAT를 후킹
- IMAGE_IMPORT_DESCRIPTOR 찾기
- IAT SetWindowTextW API 위치 찾기
-IAT 후킹 : hokiat.MySetWIndowTextW()호출한다.
IAT후킹 다 하고나면 디버깅 진행한다.: iAT 후킹하고 올리디버거로 실행해서 프로세스 정상동작하ㅗ록함
user32.SetWindowTextW()호출 코드에 BP 설치..
디버깅해서 BP에 도착
후킹된 함수의 주소 확인
후킹된 MySetWindowTextW()함수 분석..하면 한글로 변환하고 원래 함수 호출하는거 볼수 있다.
후킹 DLL 디버깅 완료
디버깅 너무 어려워요 흑흑
'공부해요 > 리버싱_핵심원리' 카테고리의 다른 글
34. 고급 글로벌 API 후킹 - IE 접속 제어 (0) | 2024.12.04 |
---|---|
33. '스텔스' 프로세스 (0) | 2024.12.04 |
31. 디버거 이야기 (0) | 2024.11.17 |
30. 메모장 WriteFile() 후킹 (0) | 2024.11.17 |
29. API 후킹: 리버싱의 '꽃' (0) | 2024.11.17 |