[CrackMyApp] do-you-even-keygen? - Unlike any crackme before! 풀이

_2·2025년 1월 7일

Crackme

목록 보기
2/12

크랙미: do-you-even-keygen?

rust + tauri로 웹뷰를 띄워 실행된다.
tauri sig를 만들어서 할 생각까진 없어서 그냥 assets 덤프했다.

key는 js의 h 함수 내부에서 체크한다.
함수 안에서 key는 r 변수에 저장된다.

if (console.log("Frontend: Starting key verification for:", r), r.trim().length === 0) {
        await On.error("Please enter a key");
        return
    }

if (r.length < 32 || r.length > 128) {
        console.log("Frontend: Invalid key length:", r.length), await On.error("Invalid key length");
        return
    }

try {
        const m = await G("verify_key", {
            key: r
        });
        switch (console.log("Frontend: Received validation result:", m), m.debug_info && console.log("Backend debug info:", m.debug_info), m.status) {
            case "Valid":
                f(!0), await On.success("Impressive! You've generated a valid key.", {
                    duration: 5e3
                });
                break;
            case "Expired":
                f(!1), await On.error("This key has expired");
                break;
            case "InvalidHardware":
                f(!1), await On.error("This key is not valid!");
                break;
            case "InvalidSignature":
                f(!1), await On.error("Invalid key - Keep trying!");
                break;
            case "InvalidFormat":
            case "InvalidChars":
                f(!1), await On.error(m.message || "Invalid key format");
                break
        }

여기서 G는

function G(r, n = {}, o) {
    return window.__TAURI_INTERNALS__.invoke(r, n, o)
}

인데
https://v1.tauri.app/v1/guides/features/command/
를 보면 js 내에서 러스트 함수를 호출하는 걸로 보인다.

러스트 내에선
sub_14011D951 함수에서 이를 받아 처리한다.

mov rdi,[rdx+000001B8] // name
mov r14,[rdx+000001C0] // size

이 함수 내부에서 처리하는name의 목록이다.

show_main_window
debug_generate_key
verify_key

.

js 코드에 안보이는 실패 message가 있는데 (Invalid Key)
이건 m.message 에 있다. (rust function에서 넣어줌.)

첫번째 조건은 "-" 를 기준으로 나눠진 데이터 길이가 4인지를 비교한다.

 {
      v23 = *(sub_140122F04(*(&v63 + 1), 4ui64, 0i64, &off_140229D08) + 8);// src\verifier.rs
                                                // its data[0]
      v21 = *(sub_140122F04(*(&v63 + 1), v64, 1ui64, &off_140229D20) + 8);// aSrcVerifierRs
                                                // data[1]
      v24 = *(sub_140122F04(*(&v63 + 1), v64, 2ui64, &off_140229D38) + 8);// aSrcVerifierRs
                                                // data[2]
      v25 = sub_140122F04(*(&v63 + 1), v64, 3ui64, &off_140229D50);// aSrcVerifierRs
                                                // data[3]
      if ( v23 == 16 )                          // data[0].size == 16

두번째 조건은 data[0].size가 16, 나머지는 8이여야 한다.

   v27 = *(v25 + 8);
        if ( v21 == 8 && v24 == 8 && v27 == 8 )

그 후 시간을 구하고

*&v95[0] = get_time(0x1Eui64);

시간 값과 문자열로 변환된 데이터를 가지고 어떤 연산을 한다.
이 과정에 HWID를 구해 데이터를 만드는 과정도 포함된다.
(함수 내부 확인 X)

<[u8]_as_core::cmp::PartialEq>::eq(data[1], data[1].size, 최종연산결과, 길이)

그리고 data[1]과 비교 (첫번째 입력 데이터 비교)

<[u8]_as_core::cmp::PartialEq>::eq(data[3], data[3].size, HWID, 길이)

data[3]은 HWID로 만든 값과 비교한다. (두번째 입력 데이터 비교)

그 다음 또 뭔가를 해서 또 다른 데이터를 만드는데 ( 내부 확인 X )
이 값의 앞 일부분을 data[0]과 비교한다. (세번째 입력 데이터 비교)

<[u8]_as_core::cmp::PartialEq>::eq(data[0], data[0].size, 최종연산결과, 길이)

마지막으로 비교 결과를 검사한다.

v20 = &v67.m256i_i8[1];
            if ( v67.m256i_i8[0] ) // 1
            {
              if ( v67.m256i_i8[1] ) // 2
              {
                v21 = v67.m256i_i64 + 2;
                if ( v67.m256i_i8[2] ) // 3
                {

입력을 정리하면
data[0]은 time 관련 값으로 만들어진 데이터
data[1]은 time, hwid로 만들어진 데이터 (Signature)
data[2]는 아무 입력이나 상관 없고
data[3]은 hwid 관련 값으로 고정적이다.

  • 수정: 글을 쓰며 처음부터 하나씩 다시 대충 확인하며 쓰다 보니 data[0]과 data[1]의 설명이 반대로 된 거 같음. 풀이엔 문제 X

data[0]과 data[1]을 만드는 방법을 알려면 로직을 모두 분석해야 하겠지만 크기가 상당하고 어려움 보단 시간이 많이 드는 과정이라 그렇게까지 하고 싶지 않아 리턴되는 데이터를 받아서 입력값을 만들어 출력하는 식으로 풀었다.

이 CrackMe는 Patch가 금지되어 있는데 푼 방법이 Patch와 비슷하다면
연산 함수 내부 루틴 까진 아니더라도 함수만 복사해서 데이터 생성 로직을 따라 하면 Keygen을 만들 수 있다.

연산 = sha256
data[1] = sha256 결과

참고
https://github.com/tauri-apps/tauri

https://infosecwriteups.com/reverse-engineering-a-native-desktop-application-tauri-app-5a2d92772da5

0개의 댓글