강의정리/Z0FCourse_Re

[x64] Chapter 6 - DLL / 6.4 SayHello.md

우와해커 2020. 1. 28. 15:05

Z0FCourse_ReverseEngineering/Chapter 6 - DLL/6.4 SayHello.md

dll.dll 리버싱, SayHello 분석

1. modules에 dll.dll이 로드될 때까지 실행(F9)
2. SayHello 클릭
3. 어떤 것도 리턴하지 않는 것으로 보임, 함수 내부로 들어감
4. XAnalyze 분석 실행해야함.
5. SayHello 내부를 쭉 훓어보면 함수이름과 관련있어 보이는 Hello 문자열을 볼 수 있음
6. 더 내려가 보면 ios_base를 참조하는 걸 볼 수 있음.

=>5,6 과정을 보고 필자는 이 함수가 std::cout이 아닐까 추측했다고 한다.
   그 이유는 ios_base는 I/O stream의 baseclass이다.

 

7. 이를 검증하기 위헤 간단한 std::cout 함수를 직접 작성하여 그래프를 이용해 두 함수를 비교하였다.

=> 우클릭>Graph>Overview
=> 그래프가 유사하다는 것을 확인함

    이것으로 SayHello()는 std::cout을 호츨하는 것으로 확신했다.

 

8. SayHello()의 함수가 끝나고 뒤에 나오는 점프 명령으로 이동하여 살펴보면

"\ n"이 사용된다. std :: cout이 호출되었다고 생각한다는 사실에 근거한 첫 번째 추측은,  
이 함수는 std::endl이라고 생각했고 std::cout의 압축된 버전처럼 보였다고 한다.

 

9. 코드 작성하여 SayHello함수 사용하기
     dll.dll과 같은 폴더에 소스코드를 release모드로 컴파일한다.

 

#include <iostream>
#include <Windows.h>

//void SayHello(); //Function declaration (for reference)
typedef void(WINAPI* ISayHello)(void); //Typedef the function for use.
// 타입 정의시 앞에 I를 붙인 이유는 실제 SayHello 함수를 Import할때, 이름 충돌을 막기 위함이다.
// 함수 이름 앞 I는 import 됬음을 의미한다.

int main()
{
	HMODULE dll = LoadLibraryA("DLL.DLL"); //Load our DLL.

	if (dll != NULL)
	{
		//Set SayHello to be the "SayHello()" function.
		ISayHello SayHello = (ISayHello)GetProcAddress(dll, "SayHello");
		
		if (SayHello != NULL) {
			SayHello();	//Call the function.
		}
		else {
			printf("Can't load the function.");
		}
	}
}

10. 이것으로 document와 lib 파일 또는 헤더 파일없이 코드를 가져 와서 DLL에서 함수를 실행하는 것에 성공했다!