Search

'S/W 역공학 분석(Reversing)'에 해당되는 글 13건

  1. 2008.12.22 Anti-Reversing Code [3/4]
  2. 2008.12.21 Anti-Reversing Code [2/4]
  3. 2008.12.19 Anti-Reversing Code [1/4]

Anti-Reversing Code [3/4]

S/W 역공학 분석(Reversing) 2008. 12. 22. 11:00 Posted by TEAMCR@K
▷ 작성자 : Hong10 (hong10@a3sc.co.kr)
▷ 편집자 : 니키 (ngnicky@a3sc.co.kr)

문서 작성일 : 2008년 12월 19일
최종 수정일 : 2008년 12월 19일

Hong10님께서 작성하신 "Anti Reversing Code" 큰 주제를 바탕으로 4개로 나눠 작성하였습니다.


2.1 PEB.NtGlobalFlag
PEB은 BeingDebugged 플래그 외에도, PEB는 NtGlobalFlag라는 필드를 갖고 있는데 NtGlobalFlag는 PEB으로부터 0x68 위치에 존재합니다. LiveKD를 이용하여 PEB의 구조체 값을 확인 해보았습니다.
 


이 플러그인의 값은 디버깅 중이 아니라면 0x0 값이 담기지만 디버깅 중이라면 0x70 값이 담겨 집니다. 그와 같은 것을 이용하여 디버깅 탐지를 합니다.

다음은 NtGlobalFlag Code 부분입니다.

 .386
.model flat, stdcall
option casemap :none   ; case sensitive

include c:\masm32\include\windows.inc
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib

.data
DbgNotFoundTitle db "Debugger status:",0h
DbgFoundTitle db "Debugger status:",0h
DbgNotFoundText db "Debugger not found!",0h
DbgFoundText db "Debugger found!",0h
.code
start:

ASSUME FS:NOTHING
MOV EAX,DWORD PTR FS:[30h]
ADD EAX,68h
MOV EAX,DWORD PTR DS:[EAX]
CMP EAX,70h
JE @DebuggerDetected

PUSH 40h
PUSH offset DbgNotFoundTitle
PUSH offset DbgNotFoundText
PUSH 0
CALL MessageBox

JMP @exit
@DebuggerDetected:

PUSH 30h
PUSH offset DbgFoundTitle
PUSH offset DbgFoundText
PUSH 0
CALL MessageBox

@exit:

PUSH 0
CALL ExitProcess

end start




여기서 ASSUME FS:NOTHING 이란 구문은 세그먼트 레지스트의 주소값을 재할당 하는 것이 아니라 이 디렉티브를 맞나면 실행 시에 어셈블러가 주소를 계산하는 방법을 변경한다. 즉 FS 세그먼트에 NOTHING이라는 속성을 붙이는 의미이다.
해당 내용을 더 깊에 알아 보았는데 다음과 같은 사이트에서 친철히 설명 해주고 있었다.
http://www.winasm.net/forum/index.php?showtopic=2082

간단히 축약해서 애기하자면(맞는 애기인지도 모르겠다,필자의 영어실력은 가히 밑바닥 수준이라서…) FS:[0] 은 Exception handler를 Default를 가지고 있다. MASM 컴파일러는 기본적으로 이 레지스터를 사용할 때 ERORR를 뱉기 때문에 위와 같이 ASSUM FS:NOTHING 을 써주면 그와 같은 ERORR Check를 Remove 해준다고 설명이 되어 있다.

다음으로FS:[30] 는 PEB의 위치에서 ADD EAX,68h 에는 NtGlobalFlag 가 존재한다. 해당 코드를 올리로 열어 보았다.
 

Olly 로 확인한 NtGlobalFlag 루틴

2.2 NtGlobalFlag 우회
해당 탐지를 우회는 간단하다. 직접 코드 패치를 하여 바꾸 거나 혹은 플래그 값을 수정하거나 이다. 하지만 이것도 역시 올리에서 플러그인 형태로 지원을 하고 있다. 다음 사이트에서 다운로드 하여 쓰시면 됩니다.
http://www.openrce.org/downloads/details/241/Olly_Advanced

해당 플러그 인을 실행하고 NtGlobalFlag 를 체크 뒤 확인 해주면 자동적으로 리턴시 플래그 값을 수정하여 디버거 탐지를 우회 하게 됩니다. 그 외 코드 패치 등 다양한 방법 이 존재 합니다. 툴로써 좀 더 편하게 하는게 좋겠죠 ??;
 
다음은 Olly Advanced NtGlobalFlag 입니다.



3.1 Heap.HeapFlag , Heap.ForceFlags
ProcessHeap 은 PEB 에서 0x18 만큼 떨어져 있고 이 플래그는 프로세서가 디버깅 될 때 heap 이 만들어 지고 이때 설정 되는 플래그들은 HeapFlag와 ForceFlas 입니다. 처음 프로그램이 힙 영역을 만들면 ForceFlags 에는 0x0 값이 HeapFlag 에는 0x2 값이 설정 됩니다. 하지만 디버깅 중이라면 NtGlobalFlag 에 따라 두개의 플래그 값이 변경 됩니다.
만약 디버깅이 탐지 되어 변경 되었다면 FoceFlags에는 0x40000060값이 할당 되며 HeapFlag 에는 0x50000062 값이 할당 됩니다.이때 변경된 값을 체크 하므로써 디버깅의 유무를 판별합니다.

다음은 PEB 의 ProcessHeap 구조체 offset 입니다.


여기서 ProcessHeap의 구조체 를 살펴보면 언급한 두개의 값들이 존재합니다.



다음은 Process_Heap Code 부분입니다.

 .386
.model flat, stdcall
option casemap :none   ; case sensitive

include c:\masm32\include\windows.inc
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc

includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib

.data
DbgNotFoundTitle db "Debugger status:",0h
DbgFoundTitle db "Debugger status:",0h
DbgNotFoundText db "Debugger not found!",0h
DbgFoundText db "Debugger found!",0h
.code

start:

ASSUME FS:NOTHING
MOV EAX,DWORD PTR FS:[18h] ;TEB
MOV EAX,DWORD PTR [EAX+30h] ;PEB
MOV EAX,DWORD PTR[EAX+18h] ;Process_Heap
CMP DWORD PTR DS:[EAX+10h],0 ;Force_Flags
JNE @DebuggerDetected

MOV EAX,DWORD PTR FS:[18h] ;TEB
MOV EAX,DWORD PTR [EAX+30h] ;PEB
MOV EAX,DWORD PTR[EAX+18h] ;Process_Heap
CMP DWORD PTR DS:[EAX+0ch],2 ;Force_Flags
JNE @DebuggerDetected

PUSH 40h
PUSH offset DbgNotFoundTitle
PUSH offset DbgNotFoundText
PUSH 0
CALL MessageBox

JMP @exit
@DebuggerDetected:

PUSH 30h
PUSH offset DbgFoundTitle
PUSH offset DbgFoundText
PUSH 0
CALL MessageBox

@exit:

PUSH 0
CALL ExitProcess

end start


3.2 Heap.HeapFlag , Heap.ForceFlags 우회
역시 앞선 방법과 동일 하게 코드 패치 및 플래그 변조로 우회를 할수 있다. 또는 올리 플러그인 OllyAdvanced 를 이용하면 쉽게 플래그 값을 자동으로 수정 해준다.
 
다음은 Olly Advanced HeapFlag,ForceFlags 우회 부분입니다.




4.1 NtQueryInformationProcess
CheckRemoteDebuggerPresent API는 디버거가 프로세서를 attach 하는 것을 감지합니다. 이 API 는 내부적으로 NtQueryInformationProcess를 호출합니다.이 함수는 또한 내부적으로 커널 구조체인 EPROCESS의 DebugPort 플래그를 검사합니다. 가령 유저 모드 디버거가 프로세서를 attach 한 상태이면 DebugPort 플래그 값은 0이 아닌값으로 설정이 됩니다.
앞서 저희는 PEB에 대해 간략하게 알아 봤습니다. PEB은 유저모드 레벨 프로세스에 대한 추가 정보 이며 여기서 설명하는 EPROCESS는 커널에서 프로세스를 관리하기 위해 사용하는 구조체 정도가 되겠습니다. 또한 NtQueryInformationProcess 을 내부적으로 불러 낼때에는 인자 값중 ProcessInformation 값은 7이 됩니다.
또한 DebugPort의 오프셋은 0x120 위치에 존재하며 유저모드 에서 디버깅 중이라면 NtQueryInformationProcess 함수의 인자 값중 hProcess는 0xfffffff 값이 되며 그렇지 않을 경우에는 0이라는 값이 담기게 됩니다

다음은 NtQueryInformationProcess Code 부분입니다.

 .386
      .model flat, stdcall
      option casemap :none   ; case sensitive

      include c:\masm32\include\windows.inc
      include c:\masm32\include\user32.inc
      include c:\masm32\include\kernel32.inc

      includelib c:\masm32\lib\user32.lib
      includelib c:\masm32\lib\kernel32.lib

    .data
       DbgNotFoundTitle db "Debugger status:",0h
       DbgFoundTitle db "Debugger status:",0h
       DbgNotFoundText db "Debugger not found!",0h
       DbgFoundText db "Debugger found!",0h
       ntdll db "ntdll.dll",0h
       zwqip db "NtQueryInformationProcess",0h
    .data?
       NtAddr dd ?
       MinusOne dd ?
    .code

start:

MOV [MinusOne],0FFFFFFFFh

PUSH offset ntdll ;ntdll.dll
CALL LoadLibrary

PUSH offset zwqip ;NtQueryInformationProcess
PUSH EAX
CALL GetProcAddress

MOV [NtAddr],EAX

MOV EAX,offset MinusOne
PUSH EAX
MOV EBX,ESP

PUSH 0
PUSH 4
PUSH EBX
PUSH 7
PUSH DWORD PTR[EAX]
CALL [NtAddr]

POP EAX

TEST EAX,EAX
JNE @DebuggerDetected

PUSH 40h
PUSH offset DbgNotFoundTitle
PUSH offset DbgNotFoundText
PUSH 0
CALL MessageBox

JMP @exit
  @DebuggerDetected:

PUSH 30h
PUSH offset DbgFoundTitle
PUSH offset DbgFoundText
PUSH 0
CALL MessageBox

  @exit:

PUSH 0
CALL ExitProcess

end start



위의 코드에서 ? 는 아마 변수를 선언할 때 값을 할당하지 않은 상태일꺼라 생각이 듭니다. 어째든 위의 코드에서 커널 API를 수행하기 위해서 LoadLibrary와 GetProcAddress를 이용하여 해당 함수 주소를 얻은뒤 앞서 설명한 인자값을 토대로 호출 하고 디버깅 중이라면 리턴되는 값을 체크하여 디버거 존재 유무를 판별 하고 있습니다.

다음 그림은 위의 코드를 Olly에서 확인한 장면(NtQueryInformationProcess in Olly)입니다.
 


그림에서 알수 있듯이 인자 값이 저런식으로 들어가 호출하게 되어야지 디버깅 체크를 할수 있습니다.


4.2 NtQueryInformationProces 우회
이 방법을 우회하는 방법 역시 여러가지가 존재 할수 있습니다. 다만 올리 플러그 인중 Olly Advanced 는 NtQueryInformationProcess 의 인자 값중 하나인 hProcess를 0으로 만듬으로써 해당 루틴을 우회하게 될꺼라고 생각했으나 잘 안되는군요. 일단은 그냥 주 루틴이 나오면 리턴되는 부분에 EAX값을 0을 설정하면 우회가 됩니다.
 



5.1 Debugger Interrupts

이 방법은 디버거가 하나의 소프트 브레이크 포인트를 수행하려고 할 때 INT3(0xcc)를 삽입 함으로 써 수행이된다. 인터럽터 가 수행이 된다는 말은 즉 예외처리가 일어 난다는 의미이다. 하지만 디버거가 디버깅 수행중 일 때 같은 OP 코드인 INT3을 만난 다면 예외 처리없이 수행을 하게된다.
이 Debugger Interrupts는 바로 이러한 것을 착안하여 안티 디버깅을 수행한다. 즉 Interrupt 수행중에 같은 인터럽터 코드를 만났을 때 exception을 하지 않는 경우를 디버깅 중이라고 판별하게 된다. 좀더 유연한 이해를 위해 아래 코드를 참고 한다.

다음은 Debugger Interrupts 부분입니다.

 .386
      .model flat, stdcall
      option casemap :none   ; case sensitive

      include c:\masm32\include\windows.inc
      include c:\masm32\include\user32.inc
      include c:\masm32\include\kernel32.inc

      includelib c:\masm32\lib\user32.lib
      includelib c:\masm32\lib\kernel32.lib

    .data
msgTitle db "Execution status:",0h
msgText1 db "No debugger detected!",0h
msgText2 db "Debugger detected!",0h
    .code

start:

ASSUME FS:NOTHING
PUSH offset @Check
PUSH FS:[0]
MOV FS:[0],ESP

; Exception
INT 3h

PUSH 30h
PUSH offset msgTitle
PUSH offset msgText2
PUSH 0
CALL MessageBox

PUSH 0
CALL ExitProcess

; SEH handleing
@Check:
POP FS:[0]
ADD ESP,4

PUSH 40h
PUSH offset msgTitle
PUSH offset msgText1
PUSH 0
CALL MessageBox

PUSH 0
CALL ExitProcess

end start


위에 코드에서 @Check는 exception이 일어 날 때 등록되는 SEH 이다. INT 3이 수행될 때 익셉션이 일어 나지 않는다면 Debuger dectect 메시지가 출력 될것이다.다음은 올리(Debugger Interrupt in Olly)에서 살펴본 모습이다.

 


저기에서 INT3을 유심히 살펴 보면 저기가 분기문이라고 이해하시는 편이 더 수월 할수도 있습니다 INT3이 exception을 일으킨다면 0x0040103e로 향하게 될것이며 그렇지 않을경우 0x00401024코드로 향하게 될것입니다.


5.2 Debug Interrupts 우회
우회 방법은 간단합니다. 올리에서 디버깅 옵션에 보면 INT 3 을 만났을 때 무시하지 않고 SEH를 following 하라는 옵션을 선택하여 줍니다.




다음과 같이 우회를 하게 된다면 Exception Handle로 빠지는 루틴(Exception Handle 을 호출하는 루틴)을 보실수 있습니다.



[계속...]

참고사이트 및 문서
EDIT PLUS 를 이용한 MASM 환경 구축
http://mysilpir.net/entry/EditPlus-Assembly-%EC%84%A4%EC%A0%95-MASM
ANTI REVERSE
http://zesrever.xstone.org/
http://slaxcore.tistory.com
http://beist.org/research/public/artofunpacking/artofunpacking.pdf
http://openrce.org
정덕영님의 윈도우 구조와 원리
THX to zersrever,slaxcore,ashine,ap0x,정덕영FROM Hong10


Copyright(c) 1998-2008 A3 Security ,LTD


Disclaimer
※ 현재 ㈜에이쓰리시큐리티에서 테스트 및 분석 중에 있으며, 이 문서는 계속 업데이트될 것입니다. 본 문서는 보안취약점으로 인한 피해를 최소화하는 데 도움이 되고자 작성되었으나, 본 문서에 포함된 대응방안의 유효성이나 기타 예상치 못한 시스템의 오작동 발생에 대하여서는 ㈜에이쓰리시큐리티에서는 일체의 책임을 지지 아니합니다.



Anti-Reversing Code [2/4]

S/W 역공학 분석(Reversing) 2008. 12. 21. 21:24 Posted by TEAMCR@K
▷ 작성자 : Hong10 (hong10@a3sc.co.kr)
▷ 편집자 : 니키 (ngnicky@a3sc.co.kr)

문서 작성일 : 2008년 12월 19일
최종 수정일 : 2008년 12월 19일

Hong10님께서 작성하신 "Anti Reversing Code" 큰 주제를 바탕으로 4개로 나눠 작성하였습니다.



Anti-Reverse
개인적으로 많은 리버서들을 짜증나게 하는 것 이 이 안티리버싱 기법이라고 생각합니다. 언팩을 하든 프로그램을 분석하든 이 안티리버싱 코드가 있으면 어떻게든 리버서들을 방해하고 혼란을 가중 시키기 위하여 여러가지 방법을 동원하여 괴롭힙니다. 물론 방어자 입장에서는 자신의 코드가 쉽게 분석 당하지 않기 위하여 더없이 고마운 기법이긴 하지만 말입니다.

1.1 IsDebugerPresent()
대부분의 기초적인 디버거 탐지 기법에는 PEB의 BeingDebugged 값을 체크를 하는 기법을 가지고 있습니다. PEB(Process Environment Block)의 위치는 TEB(Thread Environment Block)에서 0x30 만큼 떨어진 곳에 존재 합니다.
IsDebugerPresent는 유저모드의 디버거가 프로세서를 디버깅하고 있는지 flag 값을 체크 하여 확인합니다. 여기서 간단히 PEB과 TEB에 대해서 알아 보겠습니다. PEB은 유저레벨 프로세서의 대한 추가적인 정보를 가지고 있는 구조체이고 TEB은 쓰레드에 대한 정보를 가지고 있다고 말할 수 있습니다

이 구조체를 어떻게 구동되며 핸들링 하는지는 애기가 길어 지므로 생략합니다. 여기서는 PEB의 구조체 값중 BeingDebugged값을 체크하여 디버깅 유무를 판별 한다고 생각 하시면 될꺼 같습니다. 그 외 에도 PEB 구조체 값을 이용하여 판별 할수 있습니다. 그건 추후에 나오는 기법에 대하여 언급 하겠습니다. 아래의 코드를 바탕으로 기본적이 MASM 문법과 IsDebugerPresent 의 기능을 살펴 보겠습니다.

IsDebugerPresent 소스를 EDIT-PLUS stx에 적용한 코드입니다.

 .386
.model flat, stdcall
option casemap :none   ; case sensitive

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
DbgNotFoundTitle db "Debugger status:",0h
DbgFoundTitle db "Debugger status:",0h
DbgNotFoundText db "Debugger not found!",0h
DbgFoundText db "Debugger found!",0h
.code
start:

CALL IsDebuggerPresent

CMP EAX,1
JE @DebuggerDetected

PUSH 40h
PUSH offset DbgNotFoundTitle
PUSH offset DbgNotFoundText
PUSH 0
CALL MessageBox

JMP @exit
@DebuggerDetected:

PUSH 30h
PUSH offset DbgFoundTitle
PUSH offset DbgFoundText
PUSH 0
CALL MessageBox

@exit:

PUSH 0
CALL ExitProcess

end start


.386 은 어떠한 인스트럭션 를 가질 것인까에 대한 정의 정도가 되겠습니다 위와 같이 .386이 되어 있다면 386의 인스트럭션을 가질 것이며 .486 .586 등이 존재 합니다 이와 같은 정의는 각각의 사양에 따른 아키텍쳐가 조금씩 차이가 나기 때문입니다.
(가령 386에서는 32비트 레지스터와 32비트 주소 버스 및 외부 데이터 버스의 특징을 가지고 있으며 펜티엄 계열 에서는 실행 속도를 향상시킨 새로운 마이크로 구조 설계를 기반 하는 차이 입니다 이에 대한 설명은 대부분의 어셈블리어 책에 초반부에 설명이 되어 있습니다)

다음은 .model 지시자은 메모리 모델에 해당하는 지시자 입니다. 윈도우는 항상 flat 모델을 쓰고 있으므로 flat이라 지정해주며 뒤에 stdll은 콜링컨베션중 스탠다드 콜에 해당하는 정의 입니다. Flat의 간단한 정의는 no segment, 32bit address,protected mode only 라고 정의 되어 있습니다. Option에 대해서는 잘 모르겠군요. 다음으로는 include입니다 이건 조금이라도 프로그래밍을 하신분들이 라면 아실꺼라 생각하고 생략합니다.
.data 지시자는 데이터 세그먼트를 지정하는 지시자 입니다. DB(Define Byte) 라고 해서 원바이트 형으로 데이터를 정의 하겠다는 뜻입니다. C에서는 char 형에 해당합니다. .code 지시자는 이제부터 코드 세그먼트를 지시하고 있다는 뜻입니다. 그뒤 start 는 일종의 코드 엔트리를 가리키는 레이블입니다.
코드 중에 @exit: 라고 정의 된 부분이 있고 그것을 호출하는 부분을 쉽게 정의 하기 위한 형태라고 생각 하시면 되겠습니다. 다른 부분은 일반적인 어셈 코드와 다를 바가 없습니다.

이제는 PEB 구조체와 TEB 구조체의 값을 간단히 살펴보겠습니다. 주로 windbg를 이용하여 확인 하지만 간단히 값을 확인 할때는 likekd를 이용하면 편합니다. Livekd는 다음 사이트에서 다운로드 받을수 있습니다.

http://www.sysinternals.com/utilities/livekd.html  이 툴의 동작  방식은 커널 메모리 덤프를 실시간으로 떠서 동작합니다. 단지 메모리 덤프를 통하여 커널을 분석할 때 유용한 툴입니다. 그전에 Debugging Tools for Widows가 먼저 설치 되어 있어야 합니다.참고로 dt명령어는 커널 구조체의 값을 확인할 때 쓰이는 명령어 입니다.

아래는 TEB 구조체 입니다.
 


 
아래는 PEB 구조체 입니다.

여기서는 0x030 오프셋 만큼의 위치에 PEB의 포인터가 하며 PEB의 0x002 오프셋 위치에 BeingDebugged 가 존재합니다. EDIT-PLUS 에서 설정한 컴파일 환경을 이용하여 위의 코드를 컴파일 하여 OLLY로 좀더 디테일 하게 알아 보겠습니다.
 
아래는 OLLY 로 열어본 IsDebugerPresent 입니다.



위의 코드에서 IsDebugerPresent()가 호출된뒤에 리턴값이 1이라면 디버거를 찾았다는 메시지를 띄워 준다는 걸 알 수 있습니다. 좀더 자세히 콜문의 어셈루틴을 알아 보겠습니다.
 
아래는 IsDebugerPresent call 세부 루틴 입니다.



위의 달랑 세줄에서 위에 설명한 것들에 대한 것을 실행합니다. 일반적으로 FS 세그먼트 영역은 데이터 세그먼트 일종이다. FS:[18]은 TEB의 위치를 가르키며 그 주소값을 EAX에 담고 Eax+0x30 은 PEB의 위치를 다시금 EAX 에 담고 다시 EAX+0X2 값 BeingDebugged 값을 담아서 리턴 하고 있다. Livekd를 이용하여 TEB의 주소와 올리에서 뿌려주는 주소값이 일치 함을 알수있다.


1.2 IsDebugerPresent 우회
이를 우회 하는 방법에는 여러 가지 방법이 존재합니다 우선 해당 플래그 값을 수정 하면 됩니다. 하지만 올리에서 해당 안티 디버깅 에 대한 플러그인 이 존재 합니다. 해당 플러그인은 다음 사이트에서 다운로드 받을수 있습니다.
http://www.openrce.org/downloads/details/111/IsDebuggerPresent
올리의 플러그인 폴더에 압축을 풀면 다음과 같은 플러그가 생기는 걸 확인 할 수 있습니다.



위 그림에서 Hide는 IsDebugPresent를 우회 한다는 말이고 Restore은 다시금 복원 한다는 의미 입니다. 각자 실행하여 정말로 돌아가는지 확인 해보시길 바랍니다.

[계속...]

참고사이트 및 문서
EDIT PLUS 를 이용한 MASM 환경 구축
http://mysilpir.net/entry/EditPlus-Assembly-%EC%84%A4%EC%A0%95-MASM
ANTI REVERSE
http://zesrever.xstone.org/
http://slaxcore.tistory.com
http://beist.org/research/public/artofunpacking/artofunpacking.pdf
http://openrce.org
정덕영님의 윈도우 구조와 원리
THX to zersrever,slaxcore,ashine,ap0x,정덕영FROM Hong10


Copyright(c) 1998-2008 A3 Security ,LTD


Disclaimer
※ 현재 ㈜에이쓰리시큐리티에서 테스트 및 분석 중에 있으며, 이 문서는 계속 업데이트될 것입니다. 본 문서는 보안취약점으로 인한 피해를 최소화하는 데 도움이 되고자 작성되었으나, 본 문서에 포함된 대응방안의 유효성이나 기타 예상치 못한 시스템의 오작동 발생에 대하여서는 ㈜에이쓰리시큐리티에서는 일체의 책임을 지지 아니합니다.

Anti-Reversing Code [1/4]

S/W 역공학 분석(Reversing) 2008. 12. 19. 13:20 Posted by TEAMCR@K

▷ 작성자 : Hong10 (hong10@a3sc.co.kr)
▷ 편집자 : 니키 (ngnicky@a3sc.co.kr)

문서 작성일 : 2008년 12월 19일
최종 수정일 : 2008년 12월 19일

Hong10님께서 작성하신 "Anti Reversing Code" 큰 주제를 바탕으로 4개로 나눠 작성하였습니다.



1. EDIT PLUS 를 이용한 MASM32 컴파일 환경 구축
MASM32 어셈블러를 이용한 Anit-Reversing Code 구현에 앞서 간단히 MASM32 이란 무엇이며 어떻게 환경을 구축하여 테스트를 하는지 에 대한 설명을 할 것이다. MASM32이란 마이크로소프트사의 어셈블러 툴이다 그외 여러가지 어셈블러들이 존재하지만 일반적으로 API를 쓰기 위한 어셈블러로 MASM을 이용하게 된다.

MASM은 어디서 구할수 있으며 환경설정은 어떻게 할것인가? 다음 사이트에서 MASM을 구할수 있다.
http://www.masm32.com/masmdl.htm

현재 최신 버전은 9버전으로 파일명은 m32v9r.zip 으로 존재한다. 참고로 필자의 Visual Studio 의 버전은 6을 쓰며 또한 필요한 툴은 EDIT PLUS 가 있어야 한다 각자의 툴은 알아서 구하길 바란다. 먼저 MSAM을 설치해 본다.

 



간단히 Enter 키를 누름으로 써 설치를 할 수 있다.
다음은 EDIT-PLUS에서 설정이다. 도구->기본설정->사용자도구 에서 그룹 과 도구 항목을 설정 할 수 있다.
 



아래는 이와 같은 설정을 나열 해 보여주고 있다.

Edit-Plus Assembly 설정 (MASM32)

 

1. Assemble
명령 : C:\masm32\bin\ml.exe /c /coff /Zi,인수 : $(FileName),디렉토리 : $(FileDir),출력 내용 캡쳐 : 체크

2. Link (Console)
명령 : C:\masm32\bin\link.exe /SUBSYSTEM:CONSOLE /DEBUG,인수 : $(FileNameNoExt).obj,디렉토리 : $(FileDir)
출력 내용 캡쳐 : 체크

3. Link (Windows)
명령 : C:\masm32\bin\link.exe /SUBSYSTEM:WINDOWS /DEBUG,인수 : $(FileNameNoExt).obj,디렉토리 :$(FileDir)
출력 내용 캡쳐 : 체크

4. Debug
명령: C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\MSDEV.EXE,인수
: $(FileNameNoExt).exe
디렉토리
: $(FileDir)
5. Execute
명령 : $(FileNameNoExt).exe,디렉토리 : $(FileDir)


또한 EDIT-PLUS 에서는 MASM 문법에 대한 구문강조 파일이 존재한다. 해당 파일은 아래 사이트에서 받을수 있다.

http://www.editplus.com/dn.cgi?asm2.rar 여기서 다운 받은뒤 EDIT-PLUS 가 설치된 폴더에 복사 하면 된다 다음은 해당 구문강조에 대한 설정을 하는 장면이다.



해당 설정을 끝 마쳤다면 이제 실질적인 ASM 코드를 작성 하는 시간이다. 처음에는 간단한 문법 설명을 위하여 IsDebuggerPresent 라는 안티 디버깅 코드를 대상 으로 설명 하고 그외 안티 코드들을 설명할 때 덧붙이는 형식으로 진행한다. 이제 아래 그림처럼 새 파일을 하나 생성 하여 본다.

[계속...]


참고사이트 및 문서
EDIT PLUS 를 이용한 MASM 환경 구축
http://mysilpir.net/entry/EditPlus-Assembly-%EC%84%A4%EC%A0%95-MASM
ANTI REVERSE
http://zesrever.xstone.org/
http://slaxcore.tistory.com
http://beist.org/research/public/artofunpacking/artofunpacking.pdf
http://openrce.org
정덕영님의 윈도우 구조와 원리
THX to zersrever,slaxcore,ashine,ap0x,정덕영FROM Hong10


Copyright(c) 1998-2008 A3 Security ,LTD


Disclaimer
※ 현재 ㈜에이쓰리시큐리티에서 테스트 및 분석 중에 있으며, 이 문서는 계속 업데이트될 것입니다. 본 문서는 보안취약점으로 인한 피해를 최소화하는 데 도움이 되고자 작성되었으나, 본 문서에 포함된 대응방안의 유효성이나 기타 예상치 못한 시스템의 오작동 발생에 대하여서는 ㈜에이쓰리시큐리티에서는 일체의 책임을 지지 아니합니다.