본문으로 바로가기

ASM to C with IDA - 056 (strcat)

category Reversing/ASM to C 2018. 7. 16. 11:18

C300_056



C300_소스코드



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>
 
void main(void)
{
    char string1[100];
    char string2[100];
 
    printf("첫 번째 단어를 입력하세요 !\n");
    gets(string1);
 
    printf("두 번째 단어를 입력하세요 !\n");
    gets(string2);
 
    strcat(string1, string2);
 
    puts(string1);
}
 
cs




IDA - Layout Graph





IDA - Text View





pseudo code - 의사코드



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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <stdio.h>
 
void main(void)
{
    char var_1;
    char var_2;
    char var_8[6];
    int var_C;
    int var_10;
    int var_14;
    int var_18;
    char string1[100];
    char string2[100];
 
    printf(_Format);
    eax = string1;
    gets(eax);
    
    printf(byte_403020);
    ecx = string2;
    gets(ecx);
 
    edx = string2;
    var_8 = edx;
    eax = var_8;
    var_10 = eax;
 
    do{
        ecx = var_8
        dl = [ecx];
        var_1 = dl;
        var_8 = var_8 + 1;
    }while(var_1 != NULL)
    
    eax = var_8;
    eax = eax - var_10;    // eax에 string2의 길이 저장
    ecx    = var_10;
    var_14 = ecx;
    var_18 = eax;
    edx = string1;
    edx = edx + 0xFFFFFFFFh;
    var_C = edx;
    
    do{
        eax = var_C;
        cl = [eax+1];
        var_2 = cl;
        var_C = var_C + 1;
    }while(var_2 != NULL)
 
    edi = var_C;
    esi = var_14;
    edx = var_18;
    ecx = edx;
    ecx = ecx >> 2;
    rep movsb;

    ecx = edx;
    ecx = ecx && 3;
    rep movsb;

    eax = string1;
    puts(eax);
 
    eax = 0;
}
 
cs


shr(shift right): 오른쪽으로 비트를 민다.


rep movsd(move data from String to String): ecx에 저장된 수 만큼 esi에서 edi로 4바이씩 복사한다.


rep movsb(move data from String to String): ecx에 저장된 수 만큼 esi에서 edi로 1바이씩 복사한다.


23줄 var_18 = string2 - var_8을 해석해보자.


while문에 의해 string2는 문자열의 끝인 NULL을 가리키고 있다.

var_8은 원래 while문 전의 string2 문자열의 시작 주소를 가지고 있다.

C문법에서는 주소값끼리의 연산이 불가능하다.

하지만 어셈블리에서는 가능하기 때문에 주소값의 차를 이용해 string2의 문자열의 길이를 구했다.


32줄 ecx = ecx >> 2를 해석해보자.


ecx는 우리가 얼마만큼 반복해서 데이터를 옮겨야하는지에 대한 수가 저장되어 있다.

우선 4바이트씩 복사하기 때문에, 4로 나누어 진행하는 모습이다.


36줄 ecx = ecx && 3을 해석해보자.


4바이트씩 복사한 후 4의 나머지로 인해 복사되지 않은 부분이 있을 수 있다. 

예를 들어 7바이트 문자열이면 4바이트씩 복사하기 때문에 3바이트가 복사되지 않았다. 

효율성을 위해 4바이트씩 복사한 후 나머지를 1바이트씩 복사할 것이다.

따라서 우리는 4로 나눈 나머지를 구해야한다. 이것을 and 연산을 이용해 구할 수 있다.

7 && 3 = 3이다. 따라서 and 3을 통해 항상 4로 나눈 나머지를 구할 수 있다.


어떤 수의 나머지를 구할 때 %, &를 이용하여 구할수 있다.


m % n = x

m & (n-1) = x



pseudo code - 의사코드



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
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
void main(void)
{
    char var_1;
    char var_2;
    char var_8[6];
    int var_C;
    int var_10;
    int var_14;
    int var_18;
    char string1[100];
    char string2[100];
 
    printf(_Format);
    gets(string1);
    
    printf(byte_403020);
    gets(string2);

    var_8 = var_10 = string2;
    while(*string2++ != NULL)
    
    var_18 = string2 - var_8;                // string2 의 길이 저장
    var_14 = var_8;
    var_C = string1 + 0xFFFFFFFFh;
    
    while(*string1++ != NULL)
    edi = var_C;                             // var_C는 string1에 저장된 문자열의 끝을 가리킨다.
    esi = var_14;                            // var_14는 string2가 저장된 문자열의 처음을 가리킨다.
    edx = var_18;                            // var_18은 stsring2의 문자열 길이가 저장되어있다.
    ecx = edx;
    ecx = ecx >> 2;
    rep movsd                                // ecx에 저장된 수 만큼 4바이트씩 esi에서 edi로복사한다.
 
    ecx = edx;                               // edx는 stsring2의 문자열 길이가 저장되어있다.
    ecx = ecx && 3;                          // ecx && 3을 하면, ecx를 4로 나눈 나머지가 저장된다.
    rep movsb                                // ecx에 저장된 수 만큼 1바이트씩 esi에서 edi로복사한다.
 
    puts(string1);
    return 0;
}
 
cs













'Reversing > ASM to C' 카테고리의 다른 글

ASM to C with IDA - 058 (strstr)  (0) 2018.07.16
ASM to C with IDA - 057 (strlen)  (0) 2018.07.16
ASM to C with IDA - 055 (strncmp)  (0) 2018.07.12
ASM to C with IDA - 054 (strcmp)  (0) 2018.07.12
ASM to C with IDA - 053  (0) 2018.07.12