3주차 리버싱

민채은·2025년 4월 6일

ECOPS 16th

목록 보기
3/5
post-thumbnail

이론

리버싱

  • 완성된 제품을 역으로 분석해 제품의 제조 과정이나 설계 구조를 파악하는 것 (역공학)
    → 완성된 프로그램을 역으로 분석해서 소스 구조를 파악하는 것
  • 프로그램의 보안성을 평가하거나 악성코드를 분석할 때 주로 사용함

어셈블리어

  • 기계어와 일대일 대응되는 컴퓨터 프로그래밍의 저급 언어 -> 기계어를 사람이 이해하기 쉽게 기호로 표현한 언어
  • 리버싱을 하기 위해서 꼭 알아야 함

디스어셈블러

  • 실행 파일을 분석해서 기계어 코드를 어셈블리어로 바꿔주는 프로그램

디컴파일러

  • 어셈블리 코드를 사람이 읽기 쉬운 C 스타일 코드로 변환해줌

리버스 엔지니어링 툴

  • IDA
    : 디스어셈블러와 디버깅을 지원하는 프로그램
    • 기본 명령어
      • [Shift] + [F12] : 바이너리에 포함된 문자열 나타난 String 창
      • [F5] : 디컴파일
      • [F2] : 줄 클릭 후 f2 누르면 종단점 생성
      • [F9] : 코드를 종단점까지 실행
  • GHIDRA
    : 미국 국가안보국에서 개발한 오픈소스 리버스 엔지니어링 도구
  • x64 Dibugger
    : 윈도우에서 사용할 수 있는 무료 오픈 소스 디버깅 소프트웨어
  • Immunity Dibugger
  • OllyDbg
    : 가장 처음 나온 리버스 엔지니어링 툴 -> 업데이트 종료 후 OllyDbg의 소스코드를 변형해 다른 리버스 엔지니어링 툴이 만들어짐
    • 기본 명령어
      • Restart : [Ctrl] + [F2]
      • Step Into : [F7]
      • Step Over : [F8]
      • Execute till Return : [Ctrl] + [F9]
  • GDB
  • Cheat Engine
    • 오픈 소스 메모리 스캐너 및 디버거 도구 -> 프로세스의 메모리 값을 변조할 수 있음
    • 주로 게임에서 값을 조작하거나 디버깅 용도로 사용됨

과제 - Cheat Engine

step 1

step 2



Scan Type을 Exact Value로 설정하고 초기값(100)을 입력한 후 First Scan을 시행함
→ Hit me를 실행하고 변화한 값을 Value에 입력하고 Next Scan을 시행해서 변수를 찾아냄

찾아낸 변수를 더블 클릭해서 List에 넣고, list에 있는 변수의 value 값 부분을 더블 클릭해서 1000으로 값을 변경함

step 3


초기값을 모르기 때문에 Scan Type을 Unknown initial value로 설정하고 First Scan을 한 후 Hit me를 누르고 Next Scan을 해서 변수를 찾아냄

범위가 0~500이라고 주어졌으므로 Value 값이 0~500인 변수를 찾아 list에 추가하고 값을 5000으로 바꿈

step 4


Health와 Ammo를 모두 5000으로 만들어야 하고, 각각의 Value Type이 지정되어 있음
Scan Type은 Exact Value, Value Type은 Float(→Health), Double(→Ammo)로 설정한 후 step 2와 같은 일을 반복해서 Value 값을 5000으로 변경함

step 5


step 2의 과정으로 변화되는 값에 대한 변수를 찾고, Find out what writes to the address를 실행함

'mov [eax], edx'라는 명령어는 edx 레지스터 값을 eax가 가리키는 메모리 주소에 저장하라는 의미
→ 이 명령어를 이용해서 value를 변경

Show disassembler에서 해당 명령어를 NOP으로 변경해서 값이 변하지 않도록 함

step 6


포인터가 변하지 않도록 하는 것이 목적
step 2에서 한 것처럼 Change value를 이용해서 변수를 찾아냄

변수에서 Find out what writes to the address를 실행한 후 Change value를 실행하면 해당 주소에 값을 쓰는 명령어를 찾아줌
→ mov [edx], eax이므로 eax에 있는 값을 edx의 주소에 저장

→ edx의 주소에 값이 저장될 것이므로 edx의 값을 구함

→ edx 값을 이용한 포인터 변수를 생성하고 active로 바꾼 후 Change pointer을 누르면 pointer가 바뀌지 않음

step 7


step 2의 과정으로 변수를 찾고 Find out what writes to this address를 실행함

sub dword ptr [ebx+000004A8], 01이므로, Hit me를 누를 때마다 값이 1씩 줄어들게 됨

add dword ptr [ebx+000004A8], 02로 바꿔서 Hit me를 누를 때마다 값이 2씩 증가하도록 바꿈

step 8

4중 포인터를 찾아내서 값을 5000으로 고정하는 것이 목적

맨 처음 value를 step 2의 과정으로 찾고, Find out what writes to this address를 실행해서 관련 명령어를 찾아봄
→ mov [esi+18], eax이므로 esi의 주소를 찾아서 Hex 값으로 검색해 첫번째 포인터 변수를 찾음

첫번째 포인터 변수에서 Find out what accesses to this address를 이용해서 명령어를 찾음
→ cmp dword ptr [esi], 00이므로 해당 변수의 address를 Hex 값으로 해서 검색해 두번째 포인터 변수를 찾음

→ cmp dword ptr [esi+14], 00이므로 esi의 주소를 찾아서 Hex 값으로 검색해서 세번째 포인터 변수를 찾음

→ cmp dword ptr [esi+0C], 00이므로 esi 주소로 Hex 값으로 검색해서 마지막 포인터 변수를 찾음

네번째 포인터에서 Add Address Manually를 이용해서 포인터 변수를 생성하고 Active를 누르면 포인터를 고정할 수 있다

step 9

autoplay 이후 우리 팀인 Dave와 Eric 중 하나라도 살아남으면 통과

step 2의 과정으로 변수를 찾고, Find out what writes to this address로 포인터 변수를 찾아봄

해당 포인터에서 Find out what accesses to this address를 실행해서 mov [ebx+04], eax라는 명령어를 찾음

Show disassembler - Tools - Auto Assemble - Template - Code Injection으로 코드를 편집할 수 있음

mov [ebx+04], eax 대신 add [ebx+04], 01로 Dave의 Attack을 누르면 1씩 Health가 1씩 증가하도록 변경함

Restart game and autoplay를 실행하면 모든 Player의 Health가 증가함 => 실패

위의 과정을 반복해서 포인터 변수를 찾고, Show disassembler를 이용해서 오프셋으로 Player의 이름이 시작하는 곳을 찾음
cmp byte ptr [ebx+15], 'D' → 플레이어의 이름이 'D'로 시작하는 경우에만 실행
⇒ 플레이어 이름이 'Dave'인 경우에 Attack이 실행되면 Health를 1씩 증가시키도록 변경

코드를 이렇게 변경한 후 Execute를 누르고 Restart game and autoplay를 하면 다른 플레이어는 Attack이 실행되면 Health가 감소하고, Dave는 Health가 증가하므로 승리할 수 있다

0개의 댓글