'Reverse engineering'에 해당하는 글 2건

Flag Register

Reverse engineering 2011. 7. 28. 22:42

1) Flag register

 Flag register는 CPU 내부 기구중 하나로 산술 연산 결과의 상태를 보여주는 flag bit들이 모인 레지스터이다.
산술 연산시 CPU에 의해 자동적으로 세팅되며 , 프로세서의 현재 상태를 결정한다.
상태레지스터라고 불리고 기종에 따라 condition register라고 불리기도한다.


상태 플래그 (Status flag)

Carry Flag (CF)
Unsigned overflow가 발생할 때 1로 세팅된다.
Parity Flag (PF)
연산결과에 1인 bit의 개수가 짝수개이면 1 , 홀수개이면 0으로 세팅된다.
Auxiliary Flag (AF)
연산결과 하위 4bit에 Unsigned overflow가 발생했을때 1로 세팅된다.
Zero Flag (ZF)
연산결과가 0일 때 1로 세팅된다.
Sign Flag (SF)
부호를 나타내는 flag로 연산결과의 MSB(Most Significant Bit)와 같다.
연산결과가 양수이면 0 , 음수이면 1로 세팅된다.
Overflow Flag (OF)
Signed overflow가 발생할 때 1로 세팅된다.


컨트롤 플래그 (Control flag) : CPU의 동작상태를 제어하는 flag

Trap Flag (TF)
Trap flag가 1로 세팅되면 명령어를 한개 수행하고 , 0x01 inturrupt (the debug interrupt)를 발생시키게 되는데 0x01 inturrupt가 발생하면 디버거가 해당 프로세스를 attach 할 수 있는 상태가 된다.
Interrupt enable Flag (IF)
Interrupt enable Flag가 1로 세팅되면 외부 인터럽트 요구는 무시되고 , 0으로 세팅되면 외부 인터럽트요구를 받아들인다.
Direction Flag (DF)
데이터를 다른 메모리에 복사할때 방향을 결정하는 flag이다.
Direction flag가 0으로 세팅되있을동안 데이터 주소를 가르키는 레지스터가 증가하고 , 1로 세팅되있을동안 데이터 주소를 가르키는 레지스터가 감소한다.




2) 연산에 따른 flag bit

Signed
CF ZF SF OF
ADD X>0 , Y>0 , X+Y<RANGE 0 0 0 0
ADD X>0 , Y>0 , X+Y>RANGE 0 0 1 1
SUB X>0 , Y>0 , X>Y 0 0 0 0
SUB X>0 , Y>0 , X<Y 1 0 1 0
SUB X>0 , Y>0 , X=Y 0 1 0 0


Unsigned
CF ZF SF OF
ADD X>0 , Y>0 , X+Y<RANGE 0 0 0 0
ADD X>0 , Y>0 , X+Y>RANGE 1 0 1 0
SUB X>0 , Y>0 , X>Y 0 0 0 0
SUB X>0 , Y>0 , X<Y 1 0 1 0
SUB X>0 , Y>0 , X=Y 0 1 0 0

'Reverse engineering' 카테고리의 다른 글

Flag Register  (3) 2011.07.28

WRITTEN BY
pwn3r_45

트랙백  0 , 댓글  3개가 달렸습니다.
  1. 지나가다 봅니다. 2012.01.08 00:51
    3.4.3.2 DF Flag
    The direction flag (DF, located in bit 10 of the EFLAGS register) controls string instructions (MOVS, CMPS, SCAS, LODS, and STOS). Setting the DF flag causes the string instructions to auto-decrement (to process strings from high addresses to low addresses). Clearing the DF flag causes the string instructions to auto-increment (process strings from low addresses to high addresses).
    The STD and CLD instructions set and clear the DF flag, respectively.

    DF 설명이 잘못되있는 듯 하네요~~~ 여기서 clear는 DF->0
  2. 비밀댓글입니다
secret


Category : reverse engineering

Korea : 
HDD를 CD-Rom으로 인식시키기 위해서는 GetDriveTypeA의 리턴값이 무엇이 되어야 하는가 

English : 
What value must GetDriveTypeA return in order to make the computer recognize the HDD as a CD-Rom 

Summary : GetDriveTypeA API 



[+] Excute
 
 
 바이너리를 실행하면 "Make me think your HD is a CD-Rom."이란 문구가 담긴 MessageBox가 나타난다.
MessageBox를 닫으면 Error라는 이름의 MessageBox가 다시 나타난다.

< Pic.1 >

< Pic.2 >


MessageBox의 내용들로 미루어보아 문제 바이너리에서 특정 Drive의 정보를 얻어오는데 , Drive의 정보를 CD-Rom으로 인식시켜야한다고 추측해볼 수 있다.


[+] Dynamic Analyse

Ollydbg를 이용해 동적으로 분석한다.
Ollydbg로 문제바이너리를 열어보면 바로 EP를 볼 수 있다.

00401000 >/$ 6A 00          PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
00401002  |. 68 00204000    PUSH Reverse_.00402000                   ; |Title = "abex' 1st crackme"
00401007  |. 68 12204000    PUSH Reverse_.00402012                   ; |Text = "Make me think your HD is a CD-Rom."
0040100C  |. 6A 00          PUSH 0                                   ; |hOwner = NULL
0040100E  |. E8 4E000000    CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
00401013  |. 68 94204000    PUSH Reverse_.00402094                   ; /RootPathName = "c:\"
00401018  |. E8 38000000    CALL <JMP.&KERNEL32.GetDriveTypeA>       ; \GetDriveTypeA
0040101D  |. 46             INC ESI
0040101E  |. 48             DEC EAX
0040101F  |. EB 00          JMP SHORT Reverse_.00401021
00401021  |> 46             INC ESI
00401022  |. 46             INC ESI
00401023  |. 48             DEC EAX
00401024  |. 3BC6           CMP EAX,ESI
00401026  |. 74 15          JE SHORT Reverse_.0040103D
00401028  |. 6A 00          PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
0040102A  |. 68 35204000    PUSH Reverse_.00402035                   ; |Title = "Error"
0040102F  |. 68 3B204000    PUSH Reverse_.0040203B                   ; |Text = "Nah... This is not a CD-ROM Drive!"
00401034  |. 6A 00          PUSH 0                                   ; |hOwner = NULL
00401036  |. E8 26000000    CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
0040103B  |. EB 13          JMP SHORT Reverse_.00401050
0040103D  |> 6A 00          PUSH 0                                   ; |/Style = MB_OK|MB_APPLMODAL
0040103F  |. 68 5E204000    PUSH Reverse_.0040205E                   ; ||Title = "YEAH!"
00401044  |. 68 64204000    PUSH Reverse_.00402064                   ; ||Text = "Ok, I really think that your HD is a CD-ROM! :p"
00401049  |. 6A 00          PUSH 0                                   ; ||hOwner = NULL
0040104B  |. E8 11000000    CALL <JMP.&USER32.MessageBoxA>           ; |\MessageBoxA
00401050  \> E8 06000000    CALL <JMP.&KERNEL32.ExitProcess>         ; \ExitProcess
00401055   $-FF25 50304000  JMP DWORD PTR DS:[<&KERNEL32.x>;  kernel32.ExitProcess
00401061   $-FF25 5C304000  JMP DWORD PTR DS:[<&USER32.MessageBoxA>] ;  USER32.MessageBoxA 

첫 번째 Challenge라 그런지 코드가 매우 간결하다.

문제바이너리는 "Make me think your HD is a CD-Rom."이란 문구를 Text 인자로 사용하여 MessageBoxA API함수를 호출한다.


00401000 >/$ 6A 00          PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
00401002  |. 68 00204000    PUSH Reverse_.00402000                   ; |Title = "abex' 1st crackme"
00401007  |. 68 12204000    PUSH Reverse_.00402012                   ; |Text = "Make me think your HD is a CD-Rom."
0040100C  |. 6A 00          PUSH 0                                   ; |hOwner = NULL
0040100E  |. E8 4E000000    CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA

MessageBox가 닫히면 "C:\"라는 문자열을 인자로 사용하여 GetDriveTypeA API함수를 호출한다.
GetDriveTypeA 함수는 인자로 Drive이름을 받아 해당 Drive의 Type를 돌려준다.
GetDriveTypeA 함수가 돌려주는 값은 아래표와 같다. 


Return code/value Description
DRIVE_UNKNOWN
0

The drive type cannot be determined.

DRIVE_NO_ROOT_DIR
1

The root path is invalid; for example, there is no volume mounted at the specified path.

DRIVE_REMOVABLE
2

The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader.

DRIVE_FIXED
3

The drive has fixed media; for example, a hard drive or flash drive.

DRIVE_REMOTE
4

The drive is a remote (network) drive.

DRIVE_CDROM
5

The drive is a CD-ROM drive.

DRIVE_RAMDISK
6

The drive is a RAM disk.


분석을 이어서 진행해보면 , GetDriveTypeA함수 호출후에 아래의 루틴이 이어져있다.
 

0040101D  |. 46             INC ESI
0040101E  |. 48             DEC EAX
0040101F  |. EB 00          JMP SHORT Reverse_.00401021
00401021  |> 46             INC ESI
00401022  |. 46             INC ESI
00401023  |. 48             DEC EAX
00401024  |. 3BC6           CMP EAX,ESI
00401026  |. 74 15          JE SHORT Reverse_.0040103D
 

이 루틴은 ESI를 3을 증가시키고 , EAX는 2를 감소시켜 EAX와 ESI를 비교하여 두 값이 같다면 0x0040103D로 분기한다.
분기하지 않는다면 "Nah... This is not a CD-ROM Drive!"라는 문구를 가진 MessageBox가 나타난 후 종료되고 ,
분기에 성공했다면 0x0040103D에 있는 "Ok, I really think that your HD is a CD-Rom! :p"이란 문구를 가진 MessageBox가 나타나고 종료되는 루틴이 있다.
 "Ok, I really think that your HD is a CD-Rom! :p" 문자열을 가진 MessageBox 나타나도록 해본다.


그러기위해선 GetDriveTypeA 함수 호출 직후의 ESI + 3 과 EAX - 2이 같아야하는데 , 호출 직후의 ESI 값은 0x00000000이고 EAX에는 GetDriveTypeA함수에서 돌려준 값이 담겨있다.
즉 , EAX - 2가 3이라면 분기하게된다. 따라서 EAX - 2 가 3이 되기위해선 EAX는 5여야한다.
GetDriveTypeA 함수는 위의 표에 나와있듯이 Drive의 Type가 CD-Rom 일때 5를 돌려준다.
이를 통해 위 루틴은 C:\ Drive가 CD-Rom인지를 검사하는 루틴임을 알 수 있다.

그러므로 GetDriveTypeA 함수 호출직후에 EAX를 5로 변경해준다면 분기할 수 있다.

< Pic.3 GetDriveTypeA 호출직후 EAX를 5로 변경>

함수호출 직후 EAX를 5로 조작해주고 진행하면 아래와 같은 화면을 볼 수 있다.

 


 
답 : 5



'Reverse engineering > CodeEngn' 카테고리의 다른 글

CodeEngn BasicRCE01  (0) 2011.07.02

WRITTEN BY
pwn3r_45

트랙백  0 , 댓글  0개가 달렸습니다.
secret