Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
dconstruct — TLOU2 DC 스크립트용 디스어셈블러 & 실험적인 디컴파일러. | Kitploit
도구/GitHubGitHub/deepquantum/dconstruct
Static AnalysisReverse EngineeringDebuggersBinary AnalysisFirmware Analysis
GitHubdeepquantum/dconstruct

dconstruct

TLOU2 DC 스크립트용 디스어셈블러 & 실험적인 디컴파일러.

저장소 보기
23215일 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Version License: CC BY-NC-ND 4.0

dconstruct

전체 디스어셈블리 및 디컴파일 애니메이션

소스 MP4 열기

dconstruct는 The Last of Us Part II에 사용된 DC-Script 파일을 위한 리버스 엔지니어링 도구입니다. 디스어셈블러와 디컴파일러를 갖추고 있습니다.

디스어셈블된 구조와 바이트코드가 포함된 .asm 파일과, C 유사 의사 코드가 포함된 .dcpl (DC Pseudo Language) 파일을 출력합니다.

명령줄을 통해 파일을 편집할 수도 있으며, 전체 구조를 최소한의 노력으로 교체할 수 있습니다. 이는 .bin 파일 내부의 몇 가지 값을 간단히 변경하는 모드를 매우 쉽게 만듭니다.

주요 기능

  • 속도에 최적화됨. 파일 디스어셈블 및 디컴파일이 매우 빠릅니다.
  • 원본 소스 코드, 특히 제어 흐름의 정확한 재구성
  • 디스어셈블에서 모든 구조의 정확한 자동 해석
  • 여러 파일을 동시에 디스어셈블 및 디컴파일. 게임 내 모든 .bin 파일을 디컴파일하는 데 몇 초밖에 걸리지 않습니다.
  • -e 플래그를 통해 편집 수행, 모드에 사용할 새 파일 생성
  • 디스어셈블에 사용할 사용자 정의 sidbase 로드

사용 방법

먼저, 압축을 푼 dconstruct 디렉토리를 C:\Program Files와 같은 안전한 위치로 이동하는 것이 좋습니다.

dconstruct를 최대한 쉽게 사용하려면 dconstruct 폴더 안의 .\bin 디렉토리를 PATH에 추가하는 것이 좋습니다. 자세한 내용은 여기에서 확인하거나, 다음 빠른 단계를 따르세요:

  • Windows 검색창에 "환경 변수"를 입력하면 "시스템 환경 변수 편집"이라는 옵션이 나타납니다.
  • 해당 옵션을 선택하면 "시스템 속성"이라는 제목의 창이 나타납니다. "확인", "취소", "적용" 버튼 위에 "환경 변수..." 버튼이 있습니다.
  • 이 버튼을 클릭하면 다른 창이 나타납니다. 여기서 두 번째 표( "시스템 변수" 제목)로 이동하여 변수 이름이 "Path"인 항목을 찾아 더블 클릭합니다.
  • 이 대화 상자에서 오른쪽의 "새로 만들기" 옵션을 선택합니다. 이제 .\bin 디렉토리의 경로를 붙여넣습니다. 다음과 같이 보일 것입니다:

a

  • 경로가 "\bin"으로 끝나고 "\dconstruct"로 끝나지 않도록 하십시오.

  • 열려 있는 모든 대화 상자에서 '확인'을 클릭합니다.

  • 작동하는지 확인하려면 새 명령 프롬프트를 열고 dconstruct --about을 입력하십시오. 프로그램의 출력이 표시되고 오류 메시지가 없어야 합니다.

명령줄에서 다음과 같은 명령을 실행하여 첫 번째 디스어셈블 파일을 생성하세요:```shell dconstruct my_bin_file.bin

root@kitploit:~
그러면 입력 파일과 동일한 디렉토리에 `my_bin_file.bin.asm` 파일이 출력됩니다. 그런 다음 텍스트/코드 편집기를 사용하여 해당 파일을 열 수 있습니다. 고급 검색 기능을 제공하고 대용량 파일을 잘 처리할 수 있는 VSCode와 같은 프로그램을 추천합니다. 표준 Windows 메모장은 권장되지 않습니다.

파일을 디컴파일하려면 명령을 실행할 때 `--decompile` 플래그를 추가하세요.

# 명령줄 인수

- `-i` - 입력 파일 또는 폴더. 입력 경로를 첫 번째 인수로 전달하는 경우 생략할 수 있습니다.

- `-o` - 출력 경로. 입력 경로가 폴더인 경우 파일로 지정할 수 없습니다. 출력이 지정되지 않으면 .txt 파일이 입력 파일 옆에 배치됩니다. 입력이 폴더이고 출력이 지정되지 않은 경우 프로그램은 현재 작업 디렉토리에 "output" 디렉토리를 생성하고 모든 파일을 그곳에 배치합니다.

- sidbase는 실행 파일 옆에 있는 `sidbase.bin`에서 로드됩니다.

- `--no_decompile` - 디컴파일된 의사 코드를 .dcpl 파일로 내보내지 않습니다. 파일은 .asm 파일 옆에 배치됩니다. 기본값은 false입니다.

- `--no_optimize` - dcpl 코드를 최적화하고 정리하지 않습니다. 여기에는 함수 호출 인라인화, 사용되지 않는 변수 제거, 호환 가능한 for 루프를 foreach 루프로 변환, 일부 if-else 체인을 match 표현식으로 변환하는 작업이 포함됩니다.

- `--pascal_case` - 게임 함수 이름을 dcpl 출력에서 파스칼 표기법으로 변환합니다. 예: get-boolean -> GetBoolean.

- `--graphs` - 디컴파일된 모든 함수에 대한 제어 흐름 그래프가 포함된 .svg 파일을 내보냅니다. 각 .bin 파일은 모든 그래프가 포함된 자체 폴더를 얻습니다. 이는 디컴파일 속도를 **크게** 저하시키므로 동시에 많은 파일을 디컴파일할 때는 권장되지 않습니다.

- `--emit_once` - 동일한 구조가 디스어셈블리에서 두 번 내보내지는 것을 금지합니다. 구조가 여러 번 나타나면 첫 번째 인스턴스만 완전히 내보내지고 다른 모든 경우는 `ALREADY_EMITTED` 태그로 대체됩니다. 이렇게 하면 파일 크기를 크게 줄일 수 있습니다.

- `-e` - 편집을 수행합니다. 자세한 내용은 아래 섹션을 참조하세요.

- `--edit_file` - 편집 파일을 제공합니다. 편집 파일에는 한 줄에 하나의 편집이 포함됩니다. `-e` 플래그와 동일한 구문을 사용합니다.

# 디스어셈블러란?

[디스어셈블러](https://en.wikipedia.org/wiki/Disassembler)는 바이너리 명령어([바이트코드](https://en.wikipedia.org/wiki/Bytecode) 또는 [기계어](https://en.wikipedia.org/wiki/Machine_code)라고도 함)를 읽고 각각을 [니모닉](https://en.wikipedia.org/wiki/Assembly_language#Mnemonics)이라고 하는 사람이 읽을 수 있는 버전으로 변환하는 도구입니다. 디스어셈블러는 일반적으로 이러한 명령어의 의미에 대해 많이 해석하려고 하지 않고 단순히 1:1로 읽을 수 있는 버전으로 변환합니다. 예를 들어, 명령어:```arm
15 00 00 00
4A 01 01 00
43 31 01 00
1C 00 00 01

다음과 같은 사람이 읽을 수 있는 버전으로 분해됩니다:```arm LookupPointer r0, 0 LoadStaticU64Imm r1, 1 Move r49, r1 CallFf r0, r0, 1

root@kitploit:~
바이트코드의 모든 숫자는 [16진수](https://en.wikipedia.org/wiki/hexadecimal)로 작성됩니다. 각 행의 첫 번째 열은 실행할 명령어 유형인 `opcode`를 나타냅니다. 다음 열은 연산 결과가 저장될 대상 레지스터입니다. 마지막 두 열은 연산을 수행할 피연산자 1과 2로, 레지스터 또는 리터럴 숫자입니다. 모든 명령어가 4바이트를 모두 사용하는 것은 아닙니다. 예를 들어, 첫 번째 `LookupPointer` 명령어는 피연산자가 하나만 필요합니다.

dconstruct 디스어셈블러는 명령어를 읽기 쉽게 하기 위해 몇 가지 추가 정보를 제공합니다. 또한 코드의 분기를 쉽게 추적할 수 있도록 레이블(예: `L_0`)을 삽입합니다.```arm
15 00 00 00   LookupPointer        r0, 0         r0 = ST[0] -> <is-player-abby?>
4A 01 01 00   LoadStaticU64Imm     r1, 1         r1 = ST[1] -> <player>
43 31 01 00   Move                 r49, r1       r49 = player
1C 00 00 01   CallFf               r0, r0, 1     r0 = is-player-abby?(player)
2F 0D 00 00   BranchIfNot          r0, 0xD       IF NOT r0 => L_0

이는 프로그램이 과도한 추측을 하지 않고 파일의 원시 내용을 보고 싶을 때 유용합니다. 하지만 구조가 전혀 없기 때문에 큰 코드 블록의 경우 읽기가 어려울 수 있습니다. 이때 디컴파일러가 필요합니다.

디컴파일러란 무엇인가?

디컴파일러는 컴파일러의 역입니다. 컴파일러는 사람이 작성한 코드(C, Java, C++ 등)를 받아 머신 명령어로 변환하는 프로그램입니다. TLOU2와 다른 많은 ND 게임의 경우, 사용되는 스크립팅 언어는 'DC'라고 불리며, 이는 기본적으로 프로그래밍 언어 Racket의 한 버전에 불과하며, "머신"은 게임 실행 중 명령어를 실행하는 게임 자체입니다. 본질적으로 프로그래머는 DC를 작성하고 컴파일러를 사용하여 해당 코드를 게임과 함께 제공되는 .bin 파일로 변환합니다.

디컴파일러는 위에서 디스어셈블된 코드를 가져와 의사 코드(pseudo code)라고 알려진 것을 생성합니다. 의사 코드는 원시 명령어를 생성하는 데 사용된 원본 소스 코드를 재구성하려는 _시도_입니다. 이는 코드 이해를 훨씬 쉽게 만들기 위한 것이지만, 의사 코드를 생성하는 과정은 최종 바이트 코드를 생성할 수 있는 다양한 소스 코드 버전과 컴파일 중 이루어지는 최적화로 인해 상당히 복잡합니다.

현재 dconstruct 디컴파일러의 출력은 원본 DC와 구문적으로 유사하지 않습니다. DC(즉, Racket)는 고유한 구문을 가진 함수형 프로그래밍 언어로, 이에 익숙하지 않은 프로그래머에게는 엄청나게 읽기 어렵습니다. 이러한 이유로 현재는 의사 코드가 대부분의 사람들이 더 읽기 쉬운 C처럼 보이도록 선택했습니다. 그러나 Racket 및 Python 버전을 포함한 더 많은 구문을 만드는 것이 계획되어 있습니다.

예제

sqrt-sign() 함수

원본 바이트```arm

43 00 31 00 15 01 00 00 43 02 00 00 43 31 02 00 1B 01 01 01 43 02 00 00 40 03 01 00 24 02 02 03 2F 0B 02 00 40 02 02 00 2D 0C 00 00 40 02 03 00 43 03 02 00 15 04 04 00 43 05 01 00 43 31 05 00 1C 04 04 01 07 03 03 04 43 01 03 00 00 01 01 00

root@kitploit:~
이것만으로는 코드가 무엇을 하는지 거의 알 수 없습니다.

## 역어셈블된 코드와 레이블 및 심볼 테이블```arm
sqrt-sign = script-lambda [0x9A8D8] {
    [1 args]
    0000   0x09A928   43 00 31 00   Move                 r0, r49       r0 = arg_0
    0001   0x09A930   15 01 00 00   LookupPointer        r1, 0         r1 = ST[0] -> <absf>
    0002   0x09A938   43 02 00 00   Move                 r2, r0        r2 = arg_0
    0003   0x09A940   43 31 02 00   Move                 r49, r2       r49 = arg_0
    0004   0x09A948   1B 01 01 01   Call                 r1, r1, 1     r1 = absf(arg_0)
    0005   0x09A950   43 02 00 00   Move                 r2, r0        r2 = arg_0
    0006   0x09A958   40 03 01 00   LoadStaticFloatImm   r3, 1         r3 = ST[1] -> <0.000000>
    0007   0x09A960   24 02 02 03   FGreaterThanEqual    r2, r2, r3    r2 = r2 >= r3
    0008   0x09A968   2F 0B 02 00   BranchIfNot          r2, 0xB       IF NOT r2 => L_0
    0009   0x09A970   40 02 02 00   LoadStaticFloatImm   r2, 2         r2 = ST[2] -> <1.000000>
    000A   0x09A978   2D 0C 00 00   Branch               0xC           GOTO => L_1
  L_0:
    000B   0x09A980   40 02 03 00   LoadStaticFloatImm   r2, 3         r2 = ST[3] -> <-1.000000>
  L_1:
    000C   0x09A988   43 03 02 00   Move                 r3, r2        r3 = -1.000000
    000D   0x09A990   15 04 04 00   LookupPointer        r4, 4         r4 = ST[4] -> <sqrt>
    000E   0x09A998   43 05 01 00   Move                 r5, r1        r5 = RET_absf
    000F   0x09A9A0   43 31 05 00   Move                 r49, r5       r49 = RET_absf
    0010   0x09A9A8   1C 04 04 01   CallFf               r4, r4, 1     r4 = sqrt(RET_absf)
    0011   0x09A9B0   07 03 03 04   FMul                 r3, r3, r4    -1.000000 = -1.000000 * RET_sqrt
    0012   0x09A9B8   43 01 03 00   Move                 r1, r3        r1 = -1.000000
    0013   0x09A9C0   00 01 01 00   Return               r1            Return

    SYMBOL TABLE:
    0000   0x09A9C8    function: absf
    0001   0x09A9D0    float: 0.000000
    0002   0x09A9D8    float: 1.000000
    0003   0x09A9E0    float: -1.000000
    0004   0x09A9E8    function: sqrt
}

The code is now a lot more readable, but even the single branch is annoying to read if you're not used to reading assembly.

제어 흐름 그래프

여기서 너무 자세히 설명하지는 않겠지만, 제어 흐름 그래프 (CFG)는 다양한 분기 명령어를 따라 어셈블리 코드를 "노드"로 분할합니다. 이는 프로그램의 "흐름"이 다른 경로로 분기될 수 있는 위치를 파악하기 위해 코드를 분석할 때 중요합니다. 이러한 분기는 변수, if 문, for 루프 등을 생성해야 할 수도 있습니다. 이러한 그래프는 백그라운드에서 생성되어야 하지만, --graphs 프로그램 플래그를 사용하여 이미지로 출력할 수 있습니다.

최종 의사 코드```rust

u64? sqrt-sign(f32 arg_0) { f32 var_1; if (arg_0 >= 0.00) { var_1 = 1.00; } else { var_1 = -1.00; } return var_1 * sqrt(absf(arg_0)); }

root@kitploit:~
함수의 목적은 이제 매우 명확합니다. 인수의 절댓값을 취하고, 그 값의 제곱근을 구한 다음, 원래 인수의 부호를 곱합니다. 예를 들어, `sqrt-sign(-9) = -3`입니다.

## 최적화 패스

dconstruct는 의사 코드에 자동으로 최적화 패스를 적용합니다. 다음은 몇 가지 예시입니다:

### 함수 호출 인라이닝

#### 이전```c
u64? set-arrow-explosive-handle-rootvars() {
    u64? var_0 = get-uint64(fx-handle, self);
    u64? var_1 = get-float(kill, self);
    set-effect-float(var_0, killradius, var_1);
    u64? var_2 = get-uint64(fx-handle, self);
    u64? var_3 = get-float(strong, self);
    set-effect-float(var_2, strongradius, var_3);
    u64? var_4 = get-uint64(fx-handle, self);
    u64? var_5 = get-float(weak, self);
    u64? var_6 = set-effect-float(var_4, weakradius, var_5);
    return var_6;
}

이후```c

u64? set-arrow-explosive-handle-rootvars() { set-effect-float(get-uint64(fx-handle, self), killradius, get-float(kill, self)); set-effect-float(get-uint64(fx-handle, self), strongradius, get-float(strong, self)); return set-effect-float(get-uint64(fx-handle, self), weakradius, get-float(weak, self)); }

root@kitploit:~
### Foreach loops

### 이전```c#
u64? bmm-deactivate-all(u64? arg_0) {
    u64? var_0 = darray-count(arg_0);
    begin-foreach();
    for (u64 i = 0; i < var_0; i++) {
        u64? var_1 = darray-at(arg_0, i);
        u16 var_2;
        if (var_1 && *(u16*)(var_1 + 12) == 7) {
            var_2 = *(u64*)var_1;
        } else if (var_1 && *(u16*)(var_1 + 12) == 5) {
            var_2 = *(u64*)var_1;
        } else if (var_1 && *(u16*)(var_1 + 12) == 4) {
            var_2 = *(u64*)var_1;
        } else {
            var_2 = 0;
        }
        net-send-event-all(deactivate, var_2);
    }
    u64? var_3 = end-foreach();
    return var_3;
}

이후```c#

u64? bmm-deactivate-all(u64? arg_0) { foreach (u64? var_1 : arg_0) { u16 var_2; if (var_1 && (u16)(var_1 + 12) == 7) { var_2 = (u64)var_1; } else if (var_1 && (u16)(var_1 + 12) == 5) { var_2 = (u64)var_1; } else if (var_1 && (u16)(var_1 + 12) == 4) { var_2 = (u64)var_1; } else { var_2 = 0; } net-send-event-all(deactivate, var_2); } }

root@kitploit:~
### 매치 표현식

### 이전```scala
string #C57EE0A64537AE8F(u16 arg_0) {
    string var_0;
    if (arg_0 == 0) {
        var_0 = "Militia";
    } else if (arg_0 == 1) {
        var_0 = "Scars";
    } else if (arg_0 == 2) {
        var_0 = "Rattlers";
    } else if (arg_0 == 3) {
        var_0 = "Infected";
    } else if (arg_0 == 4) {
        var_0 = "Max Num Factions";
    } else {
        var_0 = "Invalid";
    }
    return var_0;
}

이후```scala

string #C57EE0A64537AE8F(u16 arg_0) { return match (arg_0) { 0 -> "Militia" 1 -> "Scars" 2 -> "Rattlers" 3 -> "Infected" 4 -> "Max Num Factions" else -> "Invalid" }; }

root@kitploit:~
## 분해된 구조의 예```c
*ellie-weapons* = symbol-array [0x00190] {
  [0] int: 6
  [1] int: 0
  [2] array [0x198] {size: 6} {
    [0] anonymous struct [0x780] {
      [0] sid: pistol-beretta
    }
    [1] anonymous struct [0x788] {
      [0] sid: pistol-revolver-taurus
    }
    [2] anonymous struct [0x790] {
      [0] sid: rifle-remington-bolt
    }
    [3] anonymous struct [0x798] {
      [0] sid: bow-ellie
    }
    [4] anonymous struct [0x7a0] {
      [0] sid: shotgun-remington-pump
    }
    [5] anonymous struct [0x7a8] {
      [0] sid: rifle-mpx5
    }
  }
}

편집

-e 플래그를 사용하여 DC 파일 편집

-e 플래그를 사용하여 DC 파일에 편집을 적용할 수 있습니다. 이 편집 내용은 원본 파일의 새 복사본에 저장되며, 원본은 그대로 유지됩니다. 한 번에 여러 편집을 수행하기 위해 여러 -e 플래그를 동시에 지정할 수 있습니다.

또는 프로그램에 편집 파일 경로를 제공할 수 있습니다. 편집 파일에는 한 줄에 하나의 편집이 포함됩니다. -e 플래그와 동일한 구문을 사용하지만, 여러 편집을 한 번에 적용하려는 경우 조금 더 사용하기 쉬울 수 있습니다.

편집은 디스어셈블리 및 디컴파일 전에 수행되므로, 편집 내용이 생성된 파일에 표시됩니다.

편집 구문

각 편집은 다음 구문을 따릅니다:```xml

[]= ``` - ``: 편집하려는 구조체의 메모리 주소 (16진수, `0x`로 시작함. 편집하려는 파일의 디스어셈블된 버전에서 복사하여 붙여넣는 것이 가장 쉽습니다). - ``: 구조체 내 멤버 변수의 인덱스입니다. 멤버 왼쪽에 표시된 숫자와 동일합니다. - ``: 해당 멤버에 할당할 새 값입니다. 동일한 크기여야 합니다. (ints와 floats는 크기가 4, sids/structs는 크기가 8입니다). 프로그램은 구조체가 동일한 타입인지 확인하지 않습니다.

예시

다음과 같은 구조체가 있다고 가정해 보겠습니다:```c++ [4] firearm-gameplay-def [0x11C28] { [0] float 0.7 // might represent the rate of fire, so i want to lower it for my mod ... }

root@kitploit:~
첫 번째 멤버 변수(인덱스 0)를 float 값 0.5로 바꾸려면 편집 명령은 다음과 같습니다:

`-e 0x11C28[0]=0.5`

편집하려는 구조체는 `0x11C28`에 있으며, 첫 번째 멤버 변수(float 왼쪽의 0)를 대상으로 합니다. 그런 다음 `=` 뒤에 새 값(이 경우 0.5)을 넣습니다. 편집이 성공하면 프로그램은 값이 `0.7->0.5`로 변경되었음을 나타내는 메시지를 표시합니다.

편집 파일의 경우, `-e`를 생략하고 각 편집을 한 줄에 하나씩 입력하면 됩니다:

### edit_file.txt

0x11C28[0]=0.5

0x11C28[1]=0.2

...

## 멤버 변수의 유형

구조체는 다양한 유형의 멤버 변수를 가질 수 있습니다:

- `float` - 마침표를 사용하여 소수 값을 지정합니다 (예: 0.5).

- `int` - 마침표 없이 정수 값을 지정합니다 (예: 42).

- `sid` (문자열 식별자) - (아래 추가 정보)

- `string` - 현재 교체를 지원하지 않음

- `structure` - 포인터 교체를 통해 (아래 추가 정보)

### 이름 조회를 통한 sid 교체:

`-e 0xABC[5]=ellie`

현재 sidbase에서 "ellie" 값을 찾습니다. 존재하지 않으면 경고가 발생하고 편집이 적용되지 않습니다. 값을 찾으면 실제 해시 값(큰 숫자)이 멤버 변수의 현재 값을 대체합니다.

### 직접 수동 해시 재정의를 통한 sid 교체:

`-e 0xABC[5]=#XXXXXXXXXXXXXXXX`

#은 원시 해시 값을 나타내며, 조회 없이 직접 적용됩니다.

### 멤버 구조체 교체

구조체가 다른 구조체를 멤버로 포함하는 경우, 전체 멤버 구조체를 다른 구조체의 주소를 할당하여 교체할 수 있습니다.

예를 들어, 다음과 같은 경우를 가정해 보겠습니다:```c++
[4] weapon-gameplay-def [0x0C523] {
    ...
    [7] firearm-gameplay-def [0x11C28] {
        ...
    }
}

따라서 weapon-gameplay-def는 firearm-gameplay-def를 포함합니다. weapon-gameplay-def 내부의 firearm-gameplay-def를 주소 0x0ABC에 위치한 다른 firearm-gameplay-def로 교체하려면 편집 명령은 다음과 같습니다:

-e 0x11C28[7]=0x0ABC

DCPL 언어 VS Code 확장

VS Code는 사용자 정의 언어에 구문 강조를 추가하기 위한 사용자 정의 확장을 생성하는 것을 지원합니다. dconstruct는 .dcpl 파일 확장자에 대한 이 지원을 추가하는 .vsix 파일을 함께 제공합니다. 이는 일상적인 프로그래밍을 위한 것이 아닌 단일 용도 언어이기 때문에, 확장을 마켓플레이스에 업로드하지 않고 대신 원시 .vsix 파일로 제공합니다. VS Code에 이 확장을 설치하려면 다음 명령을 실행하십시오:```shell code --install-extension <path/to/extension/dcpl-lint-0.0.1.vsix>

root@kitploit:~
또는 CTRL+SHIFT+P를 눌러 명령 팔레트를 열고 'Install extension via VSIX'를 입력한 후 .vsix 파일을 선택하세요.

그러면 .dcpl 코드가 다음과 같이 표시됩니다:

![dcpl_code](https://assets.kitploit.com/production/public/readmes/13048/8b4ab26ab7952a91a015d1376d3101bcad17c65602ed9c2b5c1587cb1d1a9f3c.png)

# 알려진 문제

디컴파일러는 현재 100% 완성되지 않았으므로 '실험적' 상태입니다. 디컴파일 중 경고가 발생해도 걱정하지 마세요. 해당 기능들은 현재 지원되지 않지만, 향후 지원될 예정입니다. 이 외에도 현재 다음과 같은 알려진 문제가 있습니다:

- 단일 표현식 함수 중 단락 평가(short-circuiting)가 많이 사용된 함수(특히 구조체 내 함수)는 아직 구현되지 않았습니다. 이에 대한 알고리즘 작업을 시작했지만 완료까지 얼마나 걸릴지 모르겠습니다. 하지만 이는 우선순위가 높은 작업입니다.
- 일부 타입(특히 인수 타입)이 올바르지 않습니다.
- if/else 문에서 빈 if 블록이 이상한 들여쓰기를 유발할 수 있습니다. 이는 항상 제 잘못은 아닙니다. 실제로 아무 작업도 하지 않는 분기가 존재하는데 이를 감지하기 어렵기 때문입니다.

이와 함께, 아마도 수정되지 않을 문제들도 있습니다:

- 함수가 void인지 아닌지 알 수 없을 때 쓰레기 값을 반환하는 문제
- 수많은 중복 코드

# 계획된 기능

- 완전한 Racket 및 Python 출력 형식

# 특별 감사

- **icemesh** – DC 파일의 기본 [구조](https://github.com/icemesh/dc/tree/main/t2)와 [디스어셈블러](https://github.com/icemesh/t2-dc-disasm)를 제공해 주셨습니다. 이는 크게 영감을 주었습니다.

- **Specilizer** – DC-Tool을 제공해 주셨으며, 이 프로그램에도 영감을 주었습니다.

- **uxh** – 스크립팅 지식을 제공해 주셨습니다.

- **bigdragon** 및 **Wedge** – 베타 테스트를 해 주셨습니다.

- 전체 모딩 Discord 커뮤니티 – 친절하고 도움을 주셨습니다.

## 지원

제 모든 도구와 모드는 항상 100% 무료입니다. 하지만 이런 프로그램에는 많은 노력이 필요합니다.

저를 지원하고 싶다면 제 Ko-fi를 방문해 주세요:

[![Ko-fi](https://img.shields.io/badge/Donate-Ko--fi-ff5f5f.svg)](https://ko-fi.com/deepquantum)

## 라이선스

이 모드를 사용하여 생성한 파일은 전적으로 귀하의 소유이며, 원하는 대로 자유롭게 사용할 수 있습니다. 출처 표시는 감사하지만 필수는 아닙니다.

프로그램 자체는 [크리에이티브 커먼즈 저작자표시-비영리-변경금지 4.0 국제 라이선스](https://creativecommons.org/licenses/by-nc-nd/4.0/)에 따라 라이선스가 부여됩니다.

이는 출처를 표시하면 다른 사람과 프로그램을 공유할 수 있지만, 현재 수정하거나 상업적으로 이용할 수 없음을 의미합니다.
도구 다운로드