Self-Improvement

MIPS 기초분석 4 (Case, for 문) 본문

MIPS

MIPS 기초분석 4 (Case, for 문)

JoGeun 2020. 9. 4. 13:09

소스코드

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
//mips-linux-gnueabi-gcc -o test5 test5.c -no-pie -z norelro
#include <stdio.h>
 
int main() {
    int n;
    printf("INput number:");
    scanf(" %d",&n);
    printf("before switch statement\n");
    switch (n) {
    case 0:printf("[zero]");
        break;
    case 1:printf("[one]");
        break;
    case 2:printf("[two]");
        break;
    case 3:printf("[three]");
        break;
    case 4:printf("[four]");
        break;
    case 5:printf("[five]");
        break;
    defaultprintf("[error]");
        break;
 
    }
    printf("after whitch statemenet\n");
    return 0;
}
cs

 

IDA

프롤로그 다음 카나리 셋팅과 printf 함수 호출로 "INput number:"를 출력하고 있다.

 

scanf 함수 호출시엔 입력받은 값을 저장할 주소를 인자로 받아야한다.

위에서는 fp+0x28+var_10에 입력값이 들어가게된다.

 

"before switch statement" 문자열을 출력하고 있다.

 

$v0에는 scanf에서 얻어온 값을 할당하고 있으며 case문이 0~5까지 임으로 6보다 작을시엔 default로 jmp하여 종료된다.

그 외의 숫자일 경우엔 $v0을 Left 쉬프트 연산자로 $v1에 할당한다.

$v0에는 jpt_4008a8의 주소를 할당하는데 확인해보면 이는 case문으로 이동할 주소를 담고 있다. 아래의 그림이다.

그리고 다시 $v0=$v1+$v0을 하여 $v0에 맞는 주소로 jmp를 하게 되어 case문을 동작한다.

 

case문을 수행하고나면 "atfer whitch stater" 문자열을 출력한후 셋팅된 카나리 값과 스택상의 카나리 값을 비교하고 종료하게 된다.

 

 

소스코드 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//mips-linux-gnueabi-gcc -o test5 test5.c -no-pie -z norelro
#include <stdio.h>
 
int func(int x, int y, int z) {
    int result;
    result = x + y + z;
    return result;
}
 
int main(void) {
    int i, n, sum, value;
    printf("step #1\n");
    sum = 0;
    for (i = 1; i <= 10; i++) {
        sum += 1;
    }
    printf("step #2\n");
    value = func(123);
    return 0;
}

 

IDA

프롤로그 다음 "step #1" 문자열을 인자로 받아 출력하고 있다.

 

2개의 변수(fp+0x30+var_10, fp+0x30+var_14)가 존재하며 0, 1의 값을 갖고 있다.

그리고 loc_4007BC로 jmp한다.

 

$v0에는 초기값으로 1이 들어가며 11보다 작으면 $v0=1 아니면 $v0=0이 된다.

11보다 작음으로 loc_4007A4로 jmp하게 되며 아닐시엔 step 2로 들어가게 된다.

 

11보다 작아서 loc_4007A4로 jmp 했으며 여기서는 각 변수에 +1씩 해주고 있다.

그리고 다시 for문 11보다 작은지 검증하는 부분을 수행하게 된다.

 

for문이 끝나면 "step #2" 문자열을 출력해주고 func 함수를 호출하는데 인자는 1, 2, 3을 가지게 된다.

 

func 로직을 보게되면 각 받은 인자들을 저장하고 모두 더하여 리턴값으로 뿌려주고 있다.

 

 

다시 메인으로 돌아오면 리턴값 6을 fp+0x30+var_c에 저장해주고 에필로그를 진행하게 된다.