티스토리 뷰

반응형

우선 프로그램을 실행시키면 "I'm the starting nag Remove me" 라는 Nag창이 뜨고, 일정시간이 흐르면 메인화면처럼 보이는 창이 뜨게된다. 이 때 Register 버튼을 눌러도 아무런 반응이 없는 것을 확인할 수 있다.

 

 

그리고 Exit 버튼을 누르면 "I'm the closing nag remove me ~~~" 라는 Nag창이 뜬다.

Register버튼을 누르면 인증이된 프로그램의 경우 Closing Nag창 없이 종료된다 뭐 그런문구를 확인할 수 있다. 그러나 우리는 인증과정없이 해당 Nag들을 제거해본다.

 

 

여기서 Tip !!!

맨날 내가 BreakPoint를 일일히 걸어가며 이 창이 어느 포인트에서 등장했는데 확인하던 과정을 "일시정지" 라는 간단한 기능을 통해 단번에 해결할 수 있다.

예를 들어서 Opening Nag 창을 호출하는 포인트를 찾고싶으면 해당 창이 떴을 때 x64dbg를 일시정지한다.
그리고 콜스택을 통해 어느 함수 호출을 통해 이 Nag 창이 띄워졌는지 확인할 수 있다.

 

 

호출스택을 확인해 보니 사용자 주소에서 호출된 함수는 하나밖에 없음을 확인할 수 있고, 해당 함수를 따라가보자.

 

0x42039A 주소에서 함수를 호출하니 mfc쪽으로 넘어가서 해당 Nag창이 띄워지는 것을 확인할 수 있다. 코드를 살펴보던 중 조금 위에 0x420379를통해 해당 함수 호출을 분기문을 통해 건너띌 수 있음을 확인할 수 있다.

 

그래서 해당 분기문을 그냥 단순하게 JNE로 패치하고 진행을 해보니 아무런 창도 뜨지않고 프로그램이 종료되는 것을 확인할 수 있었다. 그래서 해당 분기문에 Break Point를 걸고 프로그램을 진행해보니, 프로그램이 진행하는 동안 뜨는 Opening Nag, Main, Closing Nag 들은 해당 코드를 통해 화면에 띄워지는 것을 확인할 수 있었다.

 

그러면 Main일때는 분기문을 통과하지 않고, Main이 아닐때에는 해당 분기문을 통과해야 우리가 원하는 결과가 도출된다는 것을 예상할 수 있다.

 

 


인라인패치 ?

코드를 직접 수정하기에는 패킹 혹은 암호화 때문에 불가능하거나, 해당 코드를 수정할만한 공간이 없을 때 사용할 수 있는 기법이다.

 

예를들어 위와 같은 상황에서 첫 번째, 세 번째일 경우에는 분기문을 수행하고 두 번째일 경우에는 분기문을 수행하지 않도록 하고싶은데 코드패치를 할만한 공간이 충분하지 않다.

때문에 해당 프로그램의 섹션 끝 부분에 존재하는 NULL Pading 부분에 필요한 코드 및 데이터를 삽입해 내가 원하는 코드를 실행하는 방법으로 접근해야한다.

 

코드는 실행권한이 부여되어있는 .text 섹션에 작성하며 데이터는 읽기와 쓰기권한이 부여되어있는 .data 섹션에 작성해서 진행해야 한다.

 

위 사진에서 메모리 맵 태그를 통해 해당 프로그램의 각 섹션 주소(Offset)과 Size를 확인할 수 있다.

 

섹션의 마지막쪽을 확인해보면 위와같이 NULL Pading이 존재하는 것을 확인할 수 있다.

 

마찬가지로 .data 섹션의 마지막에도 위 덤프창과같이 NULL Pading이 존재하는 것을 확인할 수 있다.

단, 주의해야 할 점은 .data섹션은 해당 메모리주소가 NULL이라고 사용되지 않는 주소라고 확신할 수 없다는 점이다. 확신하기 위해서는 해당 주소를 Memory Break Point로 지정한 후 프로그램을 수행하고, 해당 Break Point가 Hit되는 순간이 있는지 없는지 확인하는 방법이 있다.

 

 

[ Solution ? ]

나는 0x4462F0의 주소를 변수 삼아 3번 분기문에 도달하는 시점에서 1씩 증가시킬 생각이다. 그리고 해당 주소의 값이 0 또는 2이면 분기문을 수행한 지점으로 JMP, 1이면 분기문을 수행하지 않은 지점으로 JMP하는 코드를 작성할 생각이다.

 

.text 섹션의 마지막 NULL Pading부분에 위와같이 코드를 작성했다. 여기서 의아한 부분이 있을텐데 0x437D75주소의 명령문은 왜 존재하는 것인지 잘 모를 수 있다. 이유는 아래와 같다.

 

우리는 0x420379의 분기문을 인라인패치를 진행한 코드부분으로 분기하는 명령으로 패치해야되는데 0x420379의 명령어는 2Byte밖에 되지않는다. 그러나 인라인패치 코드까지의 거리는 80Byte이상이므로 5Byte의 여유공간이 필요하다. 때문에 그 다음 명령어까지 덮어쓰게되는데 이 때 인라인패치 코드부분에서 다음 명령어 부분을 우선 수행하고 JMP를 수행하는 과정에서 생긴 명령어이다. (나머지는 NOP!!)

 

 

해당 분기문을 위와같이 인라인패치 코드부분으로 JMP할 수 있도록 패치했다.

 

이렇게하면 Main화면이 띄워지는 두 번째 실행중에는 0x4203BA로 분기하고 Nag가 띄워지는 첫 번째, 세 번째 실행중에는 0x42037F로 분기하며 우리가 원하는 결과를 만들어낼 수 있다.

 

 

반응형

'Reversing > Wargame' 카테고리의 다른 글

[XCZ.KR] PROB34(Reversing) - feat. C# 코딩  (0) 2019.06.28
[Reversing] AutoHot Key  (0) 2019.05.28
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함