악성코드

7주차_Jadx(2)

werty2 2026. 5. 25. 17:06

아래 코드를 이어서 분석

public final int onStartCommand(Intent intent, int i2, int i3) {
    String str;
    String str2;
    String str3;
    String str4;
    Thread thread;
    String str5;
    int iM2535 = C1032.m2535("۠ۨۨ");
    Thread thread2 = null;
    String str6 = null;
    while (true) {
        switch (iM2535) {
            case 56293:
            case 1746818:
            case 1752670:
                iM2535 = C1025.f + (C1023.f4365 / 6412) < 0 ? C1058.m2711("ۨ۟۟") : (C1050.f4392 - C1022.f4364) + 1753444;
                break;
            case 56356:
                String strM2476 = C1023.m2476(intent);
                if (C1058.f4402 * (C1075.f4419 | (-2499)) >= 0) {
                    iM2535 = C1032.m2535("ۢ۟۠");
                    str6 = strM2476;
                } else {
                    iM2535 = (C1073.f4417 / C1055.f4399) + 1751653;
                    str6 = strM2476;
                }
                break;
            case 56414:
                thread = new Thread(new RunnableC0019q(C1067.f4411 ^ (-625), this), C1051.m2668(m2663(), 492, C1020.f4362 ^ (-960), 1703));
                if ((C1050.f4392 ^ (C1040.f4382 / (-3268))) < 0) {
                    str5 = "ۣۨۨ";
                    iM2535 = C1068.m2771(str5);
                    thread2 = thread;
                } else {
                    iM2535 = C1067.m2764("ۣ۟ۧ");
                    thread2 = thread;
                }
                break;
            case 1746819:
                if (C1031.f4373 >= 0) {
                    str = "ۡۥ";
                    iM2535 = C1059.m2718(str);
                } else {
                    C1020.m2452();
                    str4 = "۟ۧ۠";
                    iM2535 = C1029.m2519(str4);
                }
                break;
            case 1747748:
                C1047.m2635(thread2);
                iM2535 = C1046.f4388 + (C1036.f4378 ^ 7498) >= 0 ? C1049.m2649("ۨۨۦ") : (C1060.f4404 | C1041.f4383) + 1750631;
                break;
            case 1747868:
                if (C1032.f4374 * (C1064.f4408 - 3537) <= 0) {
                    iM2535 = C1064.m2747("ۣۡ");
                } else {
                    C1043.f4385 = 4;
                    str3 = "ۨ۠ۨ";
                    iM2535 = C1045.m2622(str3);
                }
                break;
            case 1747936:
                if (intent == null) {
                    if (C1041.f4383 - (C1050.f4392 + 6568) < 0) {
                        iM2535 = C1067.f4411 + C1065.f4409 + 1753428;
                    } else {
                        C1041.m2594();
                        str2 = "ۣۦۤ";
                        iM2535 = C1023.m2469(str2);
                    }
                    break;
                } else if (C1031.f4373 >= 0) {
                }
                break;
            case 1749571:
                C1067.m2768(this, true);
                str3 = "ۤ۟ۡ";
                iM2535 = C1045.m2622(str3);
                break;
            case 1749573:
                if (C1048.m2641(C1051.m2668(m2663(), 504, C1047.f4389 ^ (-862), 566), str6)) {
                    iM2535 = (C1056.f4400 - C1023.f4365) ^ (-1751895);
                } else if (C1025.f + (C1023.f4365 / 6412) < 0) {
                }
                break;
            case 1750753:
                if (C1043.m2606(this)) {
                    if (C1053.m2682() > 0) {
                        str2 = "ۨۦۨ";
                        iM2535 = C1023.m2469(str2);
                    } else {
                        C1068.m2774();
                        iM2535 = C1068.m2771("ۣ۟ۦ");
                    }
                    break;
                } else if (C1032.f4374 * (C1064.f4408 - 3537) <= 0) {
                }
                break;
            case 1751494:
                if (C1021.f4363 > 0) {
                    str4 = "ۥۦ۟";
                    iM2535 = C1029.m2519(str4);
                } else {
                    C1041.m2594();
                    iM2535 = C1031.m2528("۠ۢۦ");
                }
                break;
            case 1751625:
                C1038.m2576(this);
                if (C1027.f4369 < 0) {
                    str2 = "ۦ۟ۢ";
                    iM2535 = C1023.m2469(str2);
                } else {
                    C1065.f4409 = 26;
                    iM2535 = C1049.m2649("ۢ۟ۢ");
                }
                break;
            case 1751649:
                if (C1054.m2683() < 0) {
                    str3 = "۟ۤ";
                    iM2535 = C1045.m2622(str3);
                } else {
                    iM2535 = C1040.m2588("ۦ۟ۢ");
                }
                break;
            case 1751653:
                if (C1048.m2641(C1055.m2694(m2663(), 434, C1024.f4366 ^ 384, 1670), str6)) {
                    str2 = "ۣۦۤ";
                    iM2535 = C1023.m2469(str2);
                } else if (C1055.m2692() <= 0) {
                    iM2535 = (C1033.f4375 * C1040.f4382) + 1678999;
                } else {
                    str5 = "ۣۧۡ";
                    thread = thread2;
                    iM2535 = C1068.m2771(str5);
                    thread2 = thread;
                }
                break;
            case 1751774:
                if (C1055.m2692() <= 0) {
                }
                break;
            case 1753417:
                return 1;
            case 1753538:
                return C1069.f4413 ^ 346;
            case 1755562:
                C1043.m2607(C1062.m2737(m2663(), 466, C1056.f4400 ^ 61, 3093), C1058.m2714(m2663(), 473, C1048.f4390 ^ (-163), 2338));
                if ((C1051.f4395 ^ (C1059.f4403 ^ (-5623))) < 0) {
                    str3 = "ۢ۟۠";
                    iM2535 = C1045.m2622(str3);
                } else {
                    C1068.m2774();
                    iM2535 = C1074.m2810("ۡۥ");
                }
                break;
            case 1755619:
                this.f1818b = thread2;
                if (C1042.f4384 <= 0) {
                    C1047.m2631();
                    iM2535 = C1065.m2753("ۨۦۨ");
                } else {
                    iM2535 = (C1056.f4400 / C1052.f4396) + 1747748;
                }
                break;
            case 1755622:
                if (C1039.f4381 < 0) {
                    iM2535 = C1040.m2588("۠ۨۨ");
                } else {
                    str = "ۢ۠ۤ";
                    iM2535 = C1059.m2718(str);
                }
                break;
        }
    }
}
  • case 1750753: if의 조건인 m2606 함수 안으로 들어가보면 아래와 같다.
    public static boolean m2606(Object obj) {
        if (C1020.m2452() <= 0) {
            return ((ServiceHandler) obj).f1817a;
        }
        return false;
    }
    안드로이드에서 Service는 화면이 꺼져 있거나 앱을 닫아도 백그라운드에서 계속 실행되는 컴포넌트를 말한다. 그리고 Handler는 특정 작업이나 메시지를 순차적으로 처리하는 역할을 한다. 즉, 이 함수에 들어오는 obj는 백그라운드 작업을 관리하는 객체이다. C1020.m2452() <= 0 라는 조건문이 참이어야만 정상값을 반환하는 데, 특정 환경(분석 환경)이 감지되면 정상 작동을 멈추도록 설계한 것 같다. 

 

  • case 1751625: m2576으로 들어가면, 아래와 같은 함수가 나온다.
    public static void m2576(Object obj) {
        if (C1048.m2644() <= 0) {
            ((ServiceHandler) obj).m1476e();
        }
    }
    m1476 함수로 들어가면, 아래와 같다. 
public final void m1476e() {
    String str;
    String str2;
    String str3;
    String str4;
    String str5;
    Thread threadM2557;
    String str6;
    ParcelFileDescriptor parcelFileDescriptor = null;
    Thread thread = null;
    String strM2778 = null;
    int iM2676 = C1052.m2676("ۣۡۢ");
    while (true) {
        switch (iM2676) {
            case 56482:
                threadM2557 = C1035.m2557(this);
                str5 = "ۣ۟ۥ";
                iM2676 = C1027.m2500(str5);
                thread = threadM2557;
                break;
            case 1746753:
                strM2778 = C1069.m2778(m2663(), 390, C1056.f4400 ^ 61, 1195);
                if (C1026.m2495() < 0) {
                    str = "ۧۦۨ";
                    iM2676 = C1054.m2688(str);
                } else {
                    C1075.m2811();
                    str = "ۨۢۤ";
                    iM2676 = C1054.m2688(str);
                }
                break;
            case 1746817:
                if (thread == null) {
                    iM2676 = (C1074.f4418 % C1040.f4382) ^ (-1754454);
                } else if ((C1049.f4391 | (C1071.f4415 ^ 2207)) < 0) {
                    iM2676 = (C1028.f4370 | C1054.f4398) + 1751723;
                } else {
                    str2 = "ۨۧ۠";
                    iM2676 = C1060.m2724(str2);
                }
                break;
            case 1746843:
                C1023.m2475(this);
                if (C1070.m2783() >= 0) {
                    C1040.m2591();
                    iM2676 = C1058.m2711("ۦۡۢ");
                } else {
                    iM2676 = C1053.f4397 + C1067.f4411 + 1750206;
                }
                break;
            case 1747653:
                C1067.m2768(this, false);
                iM2676 = (C1048.f4390 % C1027.f4369) + 1747021;
                break;
            case 1747772:
                iM2676 = C1066.f4410 > 0 ? C1069.m2781("۟۟") : C1072.m2797("ۣ۟ۡ");
                break;
            case 1747775:
            case 1755585:
                str3 = C1041.f4383 % (C1075.f4419 ^ 5134) <= 0 ? "ۡ۟ۦ" : "ۣۨ۠";
                iM2676 = C1075.m2812(str3);
                break;
            case 1748706:
                if (!C1043.m2606(this)) {
                    if (C1062.f4406 <= 0) {
                        C1028.m2503();
                        iM2676 = C1052.m2676("ۣۡۢ");
                    } else {
                        iM2676 = (C1073.f4417 / C1057.f4401) + 1748804;
                    }
                } else if (C1066.f4410 > 0) {
                }
                break;
            case 1748804:
            case 1749572:
                break;
            case 1749574:
                try {
                    C1033.m2539(parcelFileDescriptor);
                    str = "ۨۢۤ";
                    iM2676 = C1054.m2688(str);
                } catch (IOException e2) {
                    C1043.m2603(strM2778, C1054.m2689(m2663(), 412, C1030.f4372 ^ (-176), 1728), e2);
                    if (C1051.m2665() <= 0) {
                        C1074.f4418 = 93;
                        str6 = "ۣ۟ۥ";
                    } else {
                        str6 = "ۨۧ۠";
                    }
                    iM2676 = C1022.m2467(str6);
                }
                break;
            case 1750539:
                this.f1817a = false;
                if (C1030.m2526() >= 0) {
                    C1035.m2554();
                    iM2676 = C1031.m2528("۟ۤ۠");
                } else {
                    iM2676 = (C1067.f4411 % C1052.f4396) + 57118;
                }
                break;
            case 1750600:
                this.f1818b = null;
                str = "ۧۥۥ";
                iM2676 = C1054.m2688(str);
                break;
            case 1750811:
                this.f1819c = null;
                str2 = "۠۟ۤ";
                iM2676 = C1060.m2724(str2);
                break;
            case 1751530:
                C1025.m2489(thread);
                if (C1048.f4390 < 0) {
                    str3 = "ۣۡۦ";
                    iM2676 = C1075.m2812(str3);
                } else {
                    iM2676 = C1048.m2642("ۦۥۤ");
                }
                break;
            case 1751740:
                break;
            case 1753479:
                if (C1020.f4362 / (C1023.f4365 | (-9728)) != 0) {
                    C1063.f4407 = 61;
                    iM2676 = C1049.m2649("ۣۡ۠");
                } else {
                    iM2676 = C1049.m2649("ۨۢۤ");
                }
                break;
            case 1753605:
                iM2676 = parcelFileDescriptor == null ? (C1025.f ^ C1058.f4402) + 1747711 : C1023.f4365 - (C1044.f4386 ^ 5756) >= 0 ? C1074.m2810("ۥۧ") : C1030.f4372 + C1050.f4392 + 1750499;
                break;
            case 1754537:
                if (C1040.f4382 <= 0) {
                    C1061.m2726();
                    str5 = "ۥۧۥ";
                    threadM2557 = thread;
                } else {
                    str5 = "ۣۡۢ";
                    threadM2557 = thread;
                }
                iM2676 = C1027.m2500(str5);
                thread = threadM2557;
                break;
            case 1754539:
                iM2676 = (C1074.f4418 % C1040.f4382) ^ (-1754454);
                break;
            case 1754567:
                ParcelFileDescriptor parcelFileDescriptorM2734 = C1062.m2734(this);
                if (C1026.f4368 / (C1053.f4397 - 9053) != 0) {
                    iM2676 = C1053.m2677("ۣۨ۠");
                    parcelFileDescriptor = parcelFileDescriptorM2734;
                } else {
                    iM2676 = (C1047.f4389 * C1075.f4419) ^ 1574155;
                    parcelFileDescriptor = parcelFileDescriptorM2734;
                }
                break;
            case 1754601:
                C1043.m2607(strM2778, C1026.m2491(m2663(), 397, C1046.f4388 ^ 428, 2197));
                if (C1073.f4417 % (C1073.f4417 * (-5181)) >= 0) {
                    C1052.f4396 = 52;
                    str4 = "ۤ۠ۦ";
                } else {
                    str4 = "ۣ۟ۧ";
                }
                iM2676 = C1047.m2629(str4);
                break;
            case 1754661:
                iM2676 = (C1070.f4414 - C1026.f4368) ^ 1749746;
                break;
            case 1755434:
                if (C1042.f4384 / (C1020.f4362 | (-2882)) < 0) {
                    str4 = "ۣ۠ۢ";
                    iM2676 = C1047.m2629(str4);
                } else {
                    C1020.f4362 = 12;
                    iM2676 = C1029.m2519("ۧۤۨ");
                }
                break;
        }
        return;
    }
}

 

switch-case로 난독화가 되어있어서 보기가 어렵다. 중요한 부분만 보자면, ParcelFileDescriptor parcelFileDescriptorM2734 = C1062.m2734(this); 이 부분에서는 이 앱이 기기 내부의 특정 파일, 데이터베이스, 혹은 외부 서버와 연결된 통신 통로를 연다는 것을 알 수 있고, threadM2557 = C1035.m2557(this); 이 코드를 통해 스드를 생성하고 뒤에서 실행한다는 것을 알 수 있다. 마지막에 열었던 파일을 닫으려면 this.f1817a = false;을 통해 흔적을 지우며 서비스를 종료한다는 것을 알 수 있다. 간단하게 보면, 이 함수는 조용히특정 파일을 열어서 백그라운드 스레드를 띄워 가동한 뒤, 목적을 달성하면 흔적을 지우고 꺼지는 일련의 백그라운드 동작 프로세스를 실행한다.

 

  • case 1751653: m2641함수로 들어와보면 아래와 같다.
public static boolean m2641(Object obj, Object obj2) {
    if (C1035.m2554() <= 0) {
        return ((String) obj).equals(obj2);
    }
    return false;
}

인자로 들어온 두 값이 같으면 true, 다르면 false를 반환한다. 그러면 인자는 어떤 코드일까. 인자 안의 m2694 함수로 들어가보면 아래와 같다. 

public static String m2694(short[] sArr, int i2, int i3, int i4) {
    char[] cArr = new char[i3];
    for (int i5 = 0; i5 < i3; i5++) {
        cArr[i5] = (char) (sArr[i2 + i5] ^ i4);
    }
    return new String(cArr);
}

암호화되어 있던 short형 정수 배열을 우리가 읽을 수 있는 String으로 변환해 주는 아주 전형적인 XOR 복호화 함수가 나온다. i3 크기만큼의 새로운 char 배열을 만들고 암호화된 배열의 특정 시작 위치(i2)부터 값을 하나씩 가져와서 복호화 키 값(i4)과 XOR 연산을 한다. 계산된 숫자를 다시 char로 변환 후, cArr 이라는 새로운 문자열을 반환한다. 

위의 함수들과 연관지어서 해석하면, 

  1. m2663() 메서드로 암호화된 전체 데이터 배열을 가져옴
  2. 434번째 위치부터 시작
  3. C1024.f4366 ^ 384 글자 수만큼 1670이라는 키를 이용해 XOR 복호화를 수행
  4. 복호화되어 나온 진짜 텍스트가 다른 값(str6)과 일치하는지(equals) 비교

위와 같다. 만약 일치한다면 다른 곳으로 분기하도록 한다. else if일 때는 C1055.m2692() <= 0를 만족하면 실행되는데, 들어가면 764^881의 값을 반환하는 것을 알 수 있다. 그래서 일치하지 않는다면, else까지는 가지않고 else if에서 다른 분기 위치가 정해지는 것을 알 수 있다.

 

  • case 1755562:m2607 함수로 들어가보면 아래와 같다.
    public static int m2607(Object obj, Object obj2) {
        if (C1051.m2665() >= 0) {
            return Log.i((String) obj, (String) obj2);
        }
        return 0;
    }
    obj를 태그로 하고, obj2가 그 내용으로 로그를 만든다. 공격자가 원하는 행동을 시작할 때 로그를 남기는 것 같다. 그러고 다른 곳으로 분기하도록 한다. 

 

  • case 1755619: 현재 떠 있는 스레드(thread2) 정보를 클래스 내부 변수(this.f1818b)에 백업 후 C1042.f4384 <= 0이면, m2631 실행. f4384는 882로 실행되지 않음. 무조건 else의 코드가 실행됨. else에서는 (58)/(-759)+1747748으로 case 1747748로 분기된다. 1747748은 아래 코드이다. 
case 1747748:
    C1047.m2635(thread2);
    _go = C1046.f4388 + (C1036.f4378 ^ 7498) >= 0 ? C1049.m2649("ۨۨۦ") : (C1060.f4404 | C1041.f4383) + 1750631;
    break;

 

m2635 함수의 내용이 m2480 변수가 0보다 크면 ((Thread) obj).start(); 로 인자로 받은 스레드(thread2)를 실제로 구동하는 것인데, m2480이 ( -835)^(-739)으로 0보다 큰 값이 나와 백그라운드 작업(thread2)을 시작시키고, 삼항 연산자로 다음 case에 분기하도록 한다. 

 

'악성코드' 카테고리의 다른 글

6주차_Jadx(1)  (0) 2026.05.18
5주차_Frida(1)  (0) 2026.05.11
4주차_학습용 악성코드 동적분석  (0) 2026.04.02
3주차_학습용 악성코드 정적분석  (0) 2026.03.29
2주차_악성코드 분석 툴  (0) 2026.03.23