이 소스를 실행하면 Hello World 라는 문자를 출력하는 메세지 박스 창이 뜹니다.
이 메세지를 다른 메세지로 패치해볼게요.
우선 ollydbg를 실행해서 이 exe파일을 엽니다.
메인함수를 찾아보도록 합시다.
우클릭 눌러서 search for 에서 name in all modules를 누릅니다.
그리고 messageboxw를 타이핑 하면,
이렇게 찾을 수 있습니다. 여기에 f2를 눌러 브레이크포인트를(bp) 설정하고, f9를 눌러 실행합니다.
오른쪽 아래에 보면 이런 내용이 있습니다.
첫 번째는 address , 두 번째는 value, 3번째는 comment 입니다.
meesageboxw는 0D1758 에서 호출 되었고, 함수 실행이 종료되면 0D175E주소로 리턴한다는 뜻입니다.
이제 패치해보도록 할게요.
위에서 Hello World 의 주소와 meesageboxw가 호출되는 주소를 찾았습니다.
main 함수 시작 주소(0D174A)까지 실행합니다. (bp설정하고 실행하면 됩니다.)
문자열을 패치하는 방법에는 2가지 방법이 있습니다.
- 문자열 버퍼를 직접 수정
- 다른 메모리 영역에 새로운 문자열을 생성하여 전달
1) 문자열 버퍼를 직접 수정
덤프 창(왼쪽 아래)에서 문자열의 주소인 0D7B58주소로 찾아갑니다.(컨트롤+g)
선택하고 컨트롤 + e키를 눌러 edit 다이얼로그 창을 띄웁니다.(유니코드는 한 글자당 2바이트가 필요합니다. null도 고려해야되요)
여기서 unicode의 문자열을 hello reversing으로 수정할게요. keep size 체크 풀어주세요! 그리고 유니코드에선 null을 입력할 수가 없어요. 그래서 그 아래에 hex창에서 00 00 을 끝에 입력해줍시다.
메인함수로 다시 돌아가서 실행해보면,
성공적으로 수정됬습니다.
뒤에 reversing의 길이가 world보다 더 깁니다. 보통 원본 문자열 뒤에 다른 데이터가 있을 수 있기 때문에 원본 길이를 넘는 문자열로 덮어 쓰는 것은 위험합니다.
이 방법의 장점은 간단하지만, 단점은 기존 문자열 버퍼 크기 이상의 문자를 입력하기 어렵습니다.
파일로 생성하기
위에서 한 것은 메모리에 임시적으로 한 것이라 디버거가 종료되면 패치했던 내용은 사라집니다.
영구히 보존하려면 별도의 실행파일로 저장해야 됩니다.
변경된 내용(hello reversing)을 선택하여 마우스 우측 버튼을 누르고 copy to executable file 메뉴를 선택하고, 다시 우측 버튼을 눌러 save file 버튼을 눌러 저장 할 수 있습니다.
2) 다른 메모리 영역에 새로운 문자열을 생성하여 전달
위의 경우처럼 원본 문자열보다 더 긴 문자열로 패치해야 될 경우에는 위의 방법은 알맞지 않습니다.
이런 경우 사용할 수 있는 방법을 알아보겠습니다.
컨트롤 + f2로 다시 실행 후, 아까 설정한 main 함수(0D174A)로 갑니다.
아래 사진처럼 MessageBoxW가 호출 되는 지점으로 가면, 주소 수정해도 안되요!
0D1751 주소의 push 명령은 0D7B58의 hello world 문자열을 파라미터로 전달합니다.(MessageBoxW() 함수)
이 함수는 파라미터로 입력된 주소의 문자열을 출력 해줍니다. 만약 이 문자열 주솔르 변경해서 전달하면, 메시지 박스 에는 변경된 문자열이 출력됩니다.
적당한 메모리 영역에 패치하고 싶은 긴 문자열을 적고, 그 주소를 파라미터로 넘겨줍니다. (지금은 임의의 영역을 고를게요. 더 자세한 방법은 더 공부하고 올릴게요)
dump 창에서 hello world 문자열 주소로 이동합니다. 스크롤을 밑으로 내리다 보면 NULL padding 으로 끝납니다.
이곳은 프로그램이 사용하지 않는 NULL padding 영역입니다.
적당 한곳에 패치 문자열을 씁시다.
이 새로운 주소를 이제 파라미터로 전달 해야겠죠?
아까 코드에 마우스를 올리고 우클릭 누른 뒤 assemble 명령을 사용해주세요.(단축기 space)
그리고 코드를 변경해줍시다.
문자열을 새로 쓴 주소를 파라미터로 전달해줍시다.