티스토리 뷰

IDA에서 Switch-Case 문이 깨져서 나올때

가끔씩 IDA로 바이너리를 분석하다 보면 분명히 switch-case인데 JUMPOUT() 혹은 jmp rax 표시될 때가 있다.

기드라로 열면 디컴파일이 잘 되긴 하지만 기드라가 익숙치 않기도 하고, 아이다로 분석하던걸 다시 기드라로 옮기기에는 스트레스도 생긴다.

이럴때 jmp raxIDA위에서 switch-case문으로 변환해줄 수 있다.

specify-switch-idiom

아이다의 디스어셈창에서 Edit -> Other -> Specify-switch-idiom옵션을 실행하면 다음과 같이 나온다.

하나하나 어떤값들을 채워야하는지 알아보자.

Address of jump table

jmp rax를 통해 플로우가 바뀌므로 얼마만큼 점프해야하는지, 그 길이를 표시해둔 테이블이 존재한다.

일반적으로 jmp rax가 일어나는 어셈부분을 보면 해당 테이블을 쉽게 구할 수 있다.

 

. . .
lea rax, jpt_15d6
mov eax, [rdx+rax]
. . .
lea, rdx, jpt_15d6
. . . 

이 테이블의 주소를 넣어주면 된다.

Number of elements

j_table의 속성개수를 물어보는데, 그냥 얼마나 분기하는지 확인해서 넣어주면 된다.

여기서는 0x19만큼분기하므로 26을 넣어주자.

Size of table elements

j_table의 속성들의 데이터 타입의 크기를 묻는다.

여기서는 0xffffd???와 같이 4바이트 배열이므로, 4를 넣어줬다.

Element shift amount

뭔지는 모르지만 일단 완전 특이한 경우를 제외하고는 쓸일이 없을 거 같다.

기본값 0으로 냅두자.

Element Base value

j_table의 주소와 같은값을 넣어주면 된다.

Start of Switch idiom

switch 문의 시작주소이다. 변수를 로드하고 switch연산을 하는 부분이다.

cmp     [rbp+var_2C], 19h
ja      loc_19AC
mov     eax, [rbp+var_2C]
lea     rdx, ds:0[rax*4] ; switch 26 cases
lea     rax, jpt_15D6
mov     eax, [rdx+rax]

저 주소들중 아무거나 대충 찍어주자

나는 switch(var) 로딩하는 0x15d3(mov eax, [rbp+var_2c]) 주소를 넣어줬다.

Input Register of Switch

분기하는 레지스터를 넣어주면 된다.

jmp rax로 분기하기때문에 rax를 넣어주면 된다.

First Input Value

뭔지는 모르겠지만 일단 기본값 0으로 두었다.

Default Jump Address

default일때 어디로 뛸지 묻는거 같다.

cmp로 분기를 위한 비교를 하면, 그 뒤에 ja loc_???? ( case - default )가 오는데, 그 주소를 넣어주면 된다.

댓글
  • 프로필사진 D0hwQ1 jmp rax로 깨졌을 때, 어떻게 해야할 지 몰랐는데 각각의 입력값마다 상세하게 설명해주셔서 감사합니다ㅜㅠㅠㅠ 2021.11.06 10:49
댓글쓰기 폼
공지사항
Total
7,033
Today
1
Yesterday
4
TAG
more
«   2021/12   »
      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  
글 보관함