티스토리 뷰
IDA에서 Switch-Case 문이 깨져서 나올때
가끔씩 IDA로 바이너리를 분석하다 보면 분명히 switch-case
인데 JUMPOUT()
혹은 jmp rax
표시될 때가 있다.
기드라로 열면 디컴파일이 잘 되긴 하지만 기드라가 익숙치 않기도 하고, 아이다로 분석하던걸 다시 기드라로 옮기기에는 스트레스도 생긴다.
이럴때 jmp rax
를 IDA
위에서 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 )가 오는데, 그 주소를 넣어주면 된다.