문제: OEP를 구한 후 '등록성공' 으로 가는 분기점의 OPCODE를 구하시오.
정답인증은 OEP + OPCODE <- 지금은 인증할 수 없음
EX) 00400000EB03
일단 본격적인 문제 풀이에 앞서, 패킹 여부를 확인하자
UPX가 아닌, ASPack방식으로 패킹이 되어 있다.
이제 디버거로 열어보자
이 문제의 관건은 언패킹을 할 수 있느냐이다.
나도 이번에 처음 공부했기에, 내용이 완벽하지는 않다. 독자들에게 도움이 되었으면 좋겠다.(내 설명이 부족하면 구글링 하기..)
실행하면, EntryPoint는 잡히는데, 밑에 패킹되었기에 우리가 스스로 여기부터 매뉴얼 언패킹을 진행해야 한다.
0045600 | 60 | pushad |
부분을 보면, pushad라는 명령어가 있는 것을 볼 수 있는데, push명령어중 하나로, 모든 레지스터 값을 스택에 넣는 것을 목표로 한다.
이 부분 때문에 나중에 언패킹이 되었을때, popad명령어를 통해 초기의 레지스터 값을 가져올 수 있다.
pushad를 통해 레지스터값 저장
esp레지스터의 주소를 덤프로 따라가 하드웨어 BreakPoint를 만든다
(ESP 주소 - 덤프에서 따라가기 - 덤프주소의 옆에 위치한 16비트를 드래그한 후 우클릭 - 분기점 - 하드웨어 - Dword )
esp레지스터의 주소를 Hardware BP(Dword)로 만드는 이유
이 레지스터는 스택의 top부분을 가리키고 있는데, 나중에 현재 저장된 값들(초기 레지스터값들)이 언제 pop되는지 알기 위해서이고, 하드웨어 포인트로 만드는 이유는, 코드가 변형되는 문제가 발생할 수 있기 때문이다.
f9을 하면, 특정 코드에서 멈추게 된다.
004564F | 75 08 | jne 10.4564FC |
그 후, f8을 통해 코드를 따라가면
0045650 | C3 | ret |
라는 것을 통해 특정한 주소로 넘어간다.
0044583 | 55 | push ebp |
위의 ret명령어 후, 이동되는 주소가 위의 주소이다. 이것이 이 파일의 OEP이다.
x32dbg툴을 쓰고 있다면 지원하는 툴중 하나를 사용해서 덤프파일을 만든다.
위의 그림처럼 s기호를 누르면, 창이 하나 뜨는데
위의 순서대로 누르면 되는데, Dump 버튼은 덤프 파일을 생성할 위치를 지정하는 키이며 Fix Dump를 누를때는 만들어진 10_Dump 파일을 다시 눌러 최종적으로 언패킹 된다.
두개 파일이 만들어지면 성공한것
그럼 이제 만들어진 10_dump_SCY라는 파일을 디버거로 열어준다.
늘 그렇듯, F9을 눌러주면 이제 entrypoint가 push ad가 아닌 다른 것으로 잡힌것을 볼 수 있다.
우리의 목표는 등록 성공에 도달하는 분기점의 OPCODE와 OEP를 구하는 것이다.
OEP는 Entry Point을 주소값인 00445834이다.
등록 성공하는 OPCODE는 문자열 검색을 통해 성공문을 일단 찾아보는 것부터 시작하자.
딱봐도 성공 문구인것 같다.
따라가보면...
jne 분기점 옆에 7555 opcode가 적혀있다.
정답은 004458347555이다.
답은 구했지만, Well Done문구도 출력할 수 있다.(thx to 친구,,)
이부분은 친구의 도움을 받은거라, 설명이 부족할 수 밖엔 없다.
지금 현재로는 분기를 바꿔도 아예 포인터가 그 분기쪽으로 접근을 하지 않는다.
그래서 포인터가 이쪽으로 오지 않는 이유를 찾다가 cm5.dat라는 파일을 읽어오는 것을 확인했고, 그 파일을 메모장으로 만들어서 문제를 풀 수 있다.
004453F | 8D85 2CFEFFFF | lea eax,dword ptr ss:[ebp-1D4] |
004453E | BA 1C564400 | mov edx,<10_dump_scy.sub_44561C> | edx:EntryPoint, 44561C:"cm5.dat"
lea 명령어:A의 값에 B의 주소값을 저장한다. ex> lea A, B
메모장으로 cm5.dat라는 파일을 만들어서 같은 경로에 저장한다.
그렇게 되면 F9을 해서 진행하면 well done이 잘 출력되는 것을 알 수 있다.