김승현

KISA Academy - 리버스 코드 엔지니어링 중급 (24~26강) 본문

교육/KisaGym

KISA Academy - 리버스 코드 엔지니어링 중급 (24~26강)

kshind 2024. 7. 13. 17:27

24강 [이론] 컴파일된 코드의 패턴 식별 - 순환문 패턴 식별 (For, While)

컴파일된 순환문은 일반적으로 세 개의 영역으로 나눌 수 있음

  1. 순환문 탈출조건 점검 영역
  2. 순환코드 바디 영역
  3. 조건 값 변화 영역

예제 코드 - while

int a = result = 0;

while(a<10) {  // 순환문 탈출조건 점검
	result += a;  //순환코드 바디 영역
    printf("result = %d\n", while loof result);  // 순환코드 바디 영역
    ++a;  //조건 값 변화
}

예제코드 - for

int a = result = 0;

for(; a < 10; a++) {  // 순환조건 탈출 영역 + 순환 조건 변화
	result += a;  // 순환구문 바디 영역
    printf("result = %d\n", for loop result);  // 순환구문 바디 영역
}

 

gcc의 경우 어셈블리어로 했을 때 for문과 while문의 차이가 나타나지 않음

visual studio의 경우 while일 때 조건 값 변화가 젤 아래에 있지만 for일 때는 조건값이 젤 위로 올라옴

visual studio 컴파일의 경우 gcc의 형태와 비슷한 형태로 컴파일 됨

 

이런 코드들을 Ghidra같은 디컴파일러 같은 도구를 쓰면 for.c while.c를 컴파일을 각각 해서 Ghidra를 사용해서 디컴파일 해보면 동일한 코드로 보여줌 -> for인지 while인지 중요하지 않기 때문

 

  • gcc의 경우
    • 순환코드 바디 -> 조건 값 변화 -> 순환문 탈출 조건 점검
  • visual studio의 경우
    • while문
      • 순환문 탈출 조건 점검 -> 순환코드 바디 -> 조건 값 변화
    • for문
      • 조건 값 변화 -> 순환문 탈출 조건 점검 -> 순환코드 바디

 


25강 [실습] 컴파일된 코드의 패턴 식별 - 순환문 패턴 식별 실습 (For, While)

사용 툴 

IDA 

 

Ghidra - 디컴파일러 

 

for.c while.c 모두 순환문을 어떤 걸 썼냐만 다르지 내용은 완벽히 동일함

 

IDA를 통해 확인을 해봐도 for문과 while문 컴파일 결과의 차이가 그렇게 크지 않은 것을 알 수 있음 

 

Ghidra의 경우 MZ가 나타나는 헤더부분들도 보여줌

 

 

 


26강 [실습] 컴파일된 코드의 패턴 식별 -악성코드의 순환문 사용 예제 분석 실습

IDA 사용 

악성코드 수행 행위 분석 실습

heap 영역을 할당함 - 무작위로 생성할 파일을 저장할 영역 할당 - eax에 할당한 영역의 포인터를 저장

그 아래에 ebp+Destination을 통해 지역변수 공간에 저장함

 

memset은 메모리를 세팅하는 것인데 push 0을 통해 0으로 초기화함을 알 수 있음 

 

그 아래 time, srand가 있는데 이는 무작위를 가져오기 위해 실행시마다 다른 시드값을 갖기 위한 코드들임

분기한 후 바로 탈출 조건을 점검함 arg_0은 파라미터 값을 의미

이 부분 더블클릭시 해당 함수를 호출한 caller함수 접근 가능

함수 호출 전 8을 push하는 것을 보아 8로 생각할 수 있는데 callee에서 eax에 1을 add하는 연산이 있었으니

9만큼 malloc을 통해 영역을 할당함 결국 9만큼 반복하는 걸 알 수 있음

 

 

요약

malloc을 통해 heap 영역 할당함 일단

16+10= 26인데 이건 알파벳 개수고 이걸 ecx 레지스터에 넣음. 이후 edx엔 61h를 넣는데 이건 a(0x61)

 

call했던 rand함수의 값은 eax에 보관 (랜덤한 값 120246123처럼 엄청 큰 값일 수도 있는 랜덤 값)

근데 이 값을 idiv ecx를 통해 모듈러 연산 (%) 를 시킴 eax % 26 = 0~25 값이 나옴

 

이 연산 값을 EDX에 저장하는데 여기에 + 061을 더함 => 61값은 base값이고 기존 값은 offset (a ~ z)

이 연산한 값을 strcat을 통해 이어붙임

 

Ghidra에선 오른쪽에 가상으로 코드를 짜서 보여줌