달력

5

« 2024/5 »

  • 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

이번 문제도 역시 아무런 힌트가 없었다.


문제를 실행시켜서 버튼을 눌러보니 아래와 같이 동작했따.



그래서 올리디버거를 켜서 분석을 진행했다.

가장 만만한 문자열 검색을 시작했고 어렵지 않게 발견할 수 있었다.

위 메시지 뿐만 아니라 조건문도 쉽게 발견할 수 있었다.



간단히 설명하면 비트맵의 래스터 데이터를 메모리로 불러와서 리소스 섹션에 있는 값이랑 비교하여 동일할 경우 승리하는 ... 뭐 그런 문제다.


이 문제 역시 처음엔 멍청한 짓을 하며 시간을 보냈다.

메모리로 복사해 온 데이터란 걸 인지하기 전에 조건문을 만족시키기 급급하여 인라인 패칭을 하여 리소스 섹션에 있는 값을 메모리로 다 복사했었다. 이렇게 하면 화면에 보이는 비트맵에 정답이 보일 줄 알았다.


이같은 짓을 몇 번이나 해본 뒤 내가 얼마나 바보같은 짓을 시도했는지 깨닫게 되었다.


그래서 변경한 방법은 리소스 섹션에 존재하는 내용을 복사하여 그림판으로 열어보는 것이었다. 그래서 API 정보를 확인하고 관련 정보를 수집했다.



GetDIBits 함수에서 사용하는 BITMAPINFOHEADER 구조체를 활용하여 관련 정보를 수집할 수 있다. 


출처 : https://msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs.85).aspx


이 문제에서 신경써야하는 변수명은 biWidth, biHeight, biBitCount, biSizeImage 정도이다.

이는 순서대로 넓이, 높이, 적용된 비트수, 이미지 크기를 나타낸다.




따라서 리소스 섹션의 래스터 데이터 영역을 바이너리로 복사한 뒤 그림판으로 위 구조체가 가리키는 정보대로 생성한 다음에 비트맵 데이터 영역에  덮어써주면 답이 나온다.



처음에 위와 같은 생각을 하고 그림판에 저장을 했는데 아래와 같은 그림이 나와서 내 접근법이 잘못된 줄 알았다(한 곳에 글자가 뭉쳐저서 이상한 그림처럼 나옴).




답을 알고보니 저렇게 뭉쳐서 나와도 답처럼 보이네.. 그래서 모자이크 ...ㅋ


어째든 시간만 엄청 잡아먹고 성취감도 떨어지는 문제였다.

그러나 뭐 누굴 탓하나.. 미숙한 내 잘못이지 제길!!ㅋ


:
Posted by einai

해당 문제는 간단한 게임으로 만들어진 리버싱 문제다.


나같은 초보자한텐 문제에 대한 힌트가 없는게 참 난감하다.

일단 게임을 동작시켜 보았다.




리버싱의 시작은 스트링 검색!! ㅋㅋ 일단 승리와 관련된 문자열을 검색해보았다.



게임을 깼을 때 화면에 나오는 텍스트 문자열을 얻으면 그게 답이겠거니 감이 왔다. 

현 시점에서 문자열은 의미없는 문자열이다.




다시 게임으로 돌아와 저 악당들을 모두 해치우면 게임이 끝나고 의미없는 문자열이 답으로 변경되겠지 싶었다. 근데 한놈당 8발씩이나 맞춰야 하고 접근하면 에너지가 달아죽었다. 


그래서 게임을 좀 편리하게 두가지 꼼수를 부렸다. 


첫번째 꼼수는 에너지 검증 로직 우회를 통해 죽지 않는 것..!!



아무리 맞아도 죽지 않게 변경하였다. 짠!



두번째 꼼수는 얘들이 너무 많아서 한마리만 탄생시키는 것이었다. 

혼란의 시작은 여기서부터였지...



일단 한마리만 나왔다. 그래서 요놈만 죽이면 끝날 줄 알았다.

하지만 이놈을 죽여도 끝나지 않았다. 이때부터 머리속이 헝클어지면서 착각했던 내용 떄문에 문제의 논질을 찾지 못하고 한참을 헤맸다.


결국 검색의 도움을 조금 받았다. ㅠㅠㅠㅠ

악당 한놈 죽일때마다 한글자씩 변경된다는 것!!

난 악당이 없을 때 이벤트가 발생하며 글자가 변경될 것이라 착각했다.

미숙한 분석 실력과 추측을 기반으로 하다보니 ㅠㅠㅠ 



진즉에 검증 로직은 확인했었는데 내가 악당을 한놈으로 만들어버리니 그 부분이 호출이 거의 안되 이해하는데 난항을 겪었다. 제길 ㅋㅋㅋ 꼼수가 오히려 분석을 어렵게 만든 꼴이 되었다.


위 사실을 확인하고 검증 로직으로 BP를 걸고 악당을 한마리씩 처치해보았다. 




악당 인스턴스의 특정 위치에 있는 값을 가지고 와서 승리시 발생하는 문자열과 XOR 연산을 진행한다. 악당 인스턴스의 특정 위치에 있는 값은 4의 배수이고 악당 인스턴스 순서에 따라 승리시 발생하는 문자열과 연산을 진행한다. 


그래서 승리시 발생하는 문자열을 4의 배수 값과 XOR 연산을 진행하면 정답이 나온다.

첫번째 글자 = (0*4) ^ 첫번째 글자

두번째 글자 = (1*4) ^ 두번째 글자 

....... 



:
Posted by einai


 문제를 풀기 전에 ReadMe.txt 파일을 보도록 하자 .




문제의 요지는 프로그램에서 시리얼 넘버가 76876-77776 과 같을 때의 이름을 찾아라.

위의 파일로 보아 끝자리는 p로 끝나며 총 4글자임을 짐작해볼 수 있겠다. 



일단 시리얼 넘버를 넣어놓고 분석을 진행해보자. 

우선 이름을 입력하는 곳에 이름을 입력할 경우 기본적인 검증을 진행한다. 



복잡하지 않으니 그냥 말로만 간단히 적도록 하겠다.

1. 문자열이 4개로 구성되어 있는가 ? 

2. 입력된 글자가 알파벳 소문자로 구성되어 있는가 ?

3. 입력된 문자열 중 중복된 문자가 존재하는가 ?


위 사항을 만족하면 입력된 이름을 기준으로 시리얼과 매칭 작업을 진행하게 된다. 


로직은 첫번째 글자와 세번째 글자가 동일하게 적용되고

두번째 글자와 네번째 글자가 동일하게 적용된다. 



이것이 첫번째/세번째 글자를 이용한 로직 


EBP-20 = (CL & 1) + 5;           - 1 

EBP-1D = ((BL >> 3) & 1) + 5  - 2

EBP-1F = ((CL >> 1) & 1) + 5  - 3

EBP-1E = ((DL >> 2) & 1) + 5  - 4

EBP-1C = ((AL >> 4) & 1) + 5  - 5




이것이 두번째/네번째 글자를 적용한 로직 


BL       = (((BL >> 2) & 1) +1)   - 1

EBP-25 = ((DL >> 3) & 1) + 1   - 2

EBP-24 = ((AL >> 4) & 1) + 1   - 3

EBP-28 = (CL & 1) + 1   - 4

EBP-27 = ((CL >> 1) & 1) + 1   - 5



위에 나온 순서대로 첫번째 글자와 두번째 글자, 세번째 글자와 네번째 글자를 통해 나온 값을 더해서 시리얼 넘버를 생성하고 입력된 시리얼 넘버와 비교한다.

단순 3글자라서 브루트포스도 가능할 거 같긴 한데 (최대 약 3^26승 , 동일 문자열 제외/맞나?- -) 그럼 의미가 없으니 이렇게 진행해보았다.

사실 애플리케이션에 브루트포싱을 자동화돌리는 건 나한텐 의미있을수도 있겠다. 

해본적이 없기 때문에 이 또한 도전이 되리..


위의 경우의 수를 직접 판단해서 답을 작성해도 되지만,

간단히 프로그램 하나짜면 금방 답을 얻을 수 있다.



:
Posted by einai