본문 바로가기

리버싱!

CCE 준비

Intels_Dream

이젠 대부분 지원하지 않는 AVX512 어셈블리를 이용해 만든 문제

겉보기엔 별거없다.(저함수를 보기전까진)

userinput_range = [
    (' ', 32, 0x4040000000000000),
    ('!', 33, 0x4040800000000000),
    ('"', 34, 0x4041000000000000),
    ('#', 35, 0x4041800000000000),
    ('$', 36, 0x4042000000000000),
    ('%', 37, 0x4042400000000000),
    ('&', 38, 0x4043000000000000),
    ("'", 39, 0x4043800000000000),
    ('(', 40, 0x4044000000000000),
    (')', 41, 0x4044800000000000),
    ('*', 42, 0x4045000000000000),
    ('+', 43, 0x4045800000000000),
    (',', 44, 0x4046000000000000),
    ('-', 45, 0x4046800000000000),
    ('.', 46, 0x4047000000000000),
    ('/', 47, 0x4047800000000000),
    ('0', 48, 0x4048000000000000),
    ('1', 49, 0x4048800000000000),
    ('2', 50, 0x4049000000000000),
    ('3', 51, 0x4049800000000000),
    ('4', 52, 0x404a000000000000),
    ('5', 53, 0x404a400000000000),
    ('6', 54, 0x404b000000000000),
    ('7', 55, 0x404b800000000000),
    ('8', 56, 0x404c000000000000),
    ('9', 57, 0x404c800000000000),
    (':', 58, 0x404d000000000000),
    (';', 59, 0x404d800000000000),
    ('<', 60, 0x404e000000000000),
    ('=', 61, 0x404e800000000000),
    ('>', 62, 0x404f000000000000),
    ('?', 63, 0x404f800000000000),
    ('@', 64, 0x4050000000000000),
    ('A', 65, 0x4050400000000000),
    ('B', 66, 0x4050800000000000),
    ('C', 67, 0x4050c00000000000),
    ('D', 68, 0x4051000000000000),
    ('E', 69, 0x4051400000000000),
    ('F', 70, 0x4051800000000000),
    ('G', 71, 0x4051c00000000000),
    ('H', 72, 0x4052000000000000),
    ('I', 73, 0x4052200000000000),
    ('J', 74, 0x4052600000000000),
    ('K', 75, 0x4052800000000000),
    ('L', 76, 0x4052c00000000000),
    ('M', 77, 0x4053000000000000),
    ('N', 78, 0x4053400000000000),
    ('O', 79, 0x4053800000000000),
    ('P', 80, 0x4054000000000000),
    ('Q', 81, 0x4054200000000000),
    ('R', 82, 0x4054400000000000),
    ('S', 83, 0x4054600000000000),
    ('T', 84, 0x4054800000000000),
    ('U', 85, 0x4054a00000000000),
    ('V', 86, 0x4054c00000000000),
    ('W', 87, 0x4054e00000000000),
    ('X', 88, 0x4055000000000000),
    ('Y', 89, 0x4055200000000000),
    ('Z', 90, 0x4055400000000000),
    ('[', 91, 0x4056c00000000000),
    ('\\', 92, 0x4057000000000000),
    (']', 93, 0x4057400000000000),
    ('^', 94, 0x4057800000000000),
    ('_', 95, 0x4057c00000000000),
    ('`', 96, 0x4058000000000000),
    ('a', 97, 0x4058200000000000),
    ('b', 98, 0x4058400000000000),
    ('c', 99, 0x4058600000000000),
    ('d', 100, 0x4058800000000000),
    ('e', 101, 0x4058a00000000000),
    ('f', 102, 0x4058c00000000000),
    ('g', 103, 0x4058e00000000000),
    ('h', 104, 0x4059000000000000),
    ('i', 105, 0x4059200000000000),
    ('j', 106, 0x4059400000000000),
    ('k', 107, 0x4059600000000000),
    ('l', 108, 0x4059800000000000),
    ('m', 109, 0x4059a00000000000),
    ('n', 110, 0x4059c00000000000),
    ('o', 111, 0x4059e00000000000),
    ('p', 112, 0x405a000000000000),
    ('q', 113, 0x405a200000000000),
    ('r', 114, 0x405a400000000000),
    ('s', 115, 0x405a600000000000),
    ('t', 116, 0x405a800000000000),
    ('u', 117, 0x405aa00000000000),
    ('v', 118, 0x405ac00000000000),
    ('w', 119, 0x405ae00000000000),
    ('x', 120, 0x405b000000000000),
    ('y', 121, 0x405b200000000000),
    ('z', 122, 0x405b400000000000),
    ('{', 123, 0x405b600000000000),
    ('|', 124, 0x405b800000000000),
    ('}', 125, 0x405ba00000000000),
    ('~', 126, 0x405f800000000000),
]

각 아스키값을 부동소수점으로 변환시킨뒤 연산을 한다.

_BOOL8 __fastcall sub_11C9(__int64 a1, __int64 a2)
{
  _QWORD v53[3]; // [rsp+28h] [rbp-388h] BYREF

  v53[2] = a1;
  _RAX = a1;
  __asm
  {
    vmovupd zmm0, zmmword ptr [rax]
    vmovapd zmmword ptr [rsp+348h+var_140], zmm0
  }
  v53[1] = a2;
  _RAX = a2;
  __asm
  {
    vmovupd zmm0, zmmword ptr [rax]
    vmovapd zmmword ptr [rsp+348h+var_100], zmm0
    vmovapd zmm0, zmmword ptr [rsp+348h+var_140]
    vmovapd zmmword ptr [rsp+348h+var_80], zmm0
    vmovapd zmm0, zmmword ptr [rsp+348h+var_100]
    vmovapd zmmword ptr [rsp+348h+var_40], zmm0
    vmovapd zmm0, zmmword ptr [rsp+348h+var_80]
    vmulpd  zmm0, zmm0, zmmword ptr [rsp+348h+var_40]
    vmovapd zmmword ptr [rsp+348h+var_C0], zmm0
    vmovapd ymm1, [rsp+348h+var_160]
    vmovapd zmm0, zmmword ptr [rsp+348h+var_C0]
  }
  LODWORD(_RAX) = -1;
  __asm
  {
    kmovb   k1, eax
    vextractf64x4 ymm1{k1}, zmm0, 0
    vmovapd [rsp+348h+var_2A0], ymm1
    vmovapd ymm1, [rsp+348h+var_180]
    vmovapd zmm0, zmmword ptr [rsp+348h+var_C0]
  }
  LODWORD(_RAX) = -1;
  __asm
  {
    kmovb   k2, eax
    vextractf64x4 ymm1{k2}, zmm0, 1
    vmovapd [rsp+348h+var_280], ymm1
    vmovapd ymm0, [rsp+348h+var_2A0]
    vmovapd [rsp+348h+var_1C0], ymm0
    vmovapd ymm0, [rsp+348h+var_2A0]
    vmovapd [rsp+348h+var_1A0], ymm0
    vmovapd ymm0, [rsp+348h+var_1C0]
    vhaddpd ymm0, ymm0, [rsp+348h+var_1A0]
    vmovapd [rsp+348h+var_260], ymm0
    vmovapd ymm0, [rsp+348h+var_260]
    vextractf64x2 [rsp+348h+var_370], ymm0, 1
    vmovapd ymm0, [rsp+348h+var_260]
    vmovapd [rsp+348h+var_1E0], ymm0
    vmovapd xmm0, xmmword ptr [rsp+348h+var_1E0]
    vmovapd [rsp+348h+var_2C0], xmm0
    vmovapd xmm0, [rsp+348h+var_370]
    vmovapd [rsp+348h+var_2B0], xmm0
    vmovapd xmm0, [rsp+348h+var_2C0]
    vaddpd  xmm0, xmm0, [rsp+348h+var_2B0]
    vmovapd [rsp+348h+var_360], xmm0
    vmovapd ymm0, [rsp+348h+var_280]
    vmovapd [rsp+348h+var_220], ymm0
    vmovapd ymm0, [rsp+348h+var_280]
    vmovapd [rsp+348h+var_200], ymm0
    vmovapd ymm0, [rsp+348h+var_220]
    vhaddpd ymm0, ymm0, [rsp+348h+var_200]
    vmovapd [rsp+348h+var_260], ymm0
    vmovapd ymm0, [rsp+348h+var_260]
    vextractf64x2 [rsp+348h+var_370], ymm0, 1
    vmovapd ymm0, [rsp+348h+var_260]
    vmovapd [rsp+348h+var_240], ymm0
    vmovapd xmm0, xmmword ptr [rsp+348h+var_240]
    vmovapd [rsp+348h+var_2E0], xmm0
    vmovapd xmm0, [rsp+348h+var_370]
    vmovapd [rsp+348h+var_2D0], xmm0
    vmovapd xmm0, [rsp+348h+var_2E0]
    vaddpd  xmm0, xmm0, [rsp+348h+var_2D0]
    vmovapd xmm1, [rsp+348h+var_360]
    vmovapd [rsp+348h+var_300], xmm1
    vmovapd [rsp+348h+var_2F0], xmm0
    vmovapd xmm0, [rsp+348h+var_300]
    vaddpd  xmm0, xmm0, [rsp+348h+var_2F0]
    vmovapd [rsp+348h+var_360], xmm0
    vmovsd  xmm0, cs:qword_2030
    vmovsd  [rsp+348h+var_388], xmm0
    vmovddup xmm0, [rsp+348h+var_388]
    vmovapd [rsp+348h+var_320], xmm0
    vmovapd xmm0, [rsp+348h+var_360]
    vmovapd [rsp+348h+var_310], xmm0
    vmovapd xmm0, [rsp+348h+var_320]
    vandnpd xmm0, xmm0, [rsp+348h+var_310]
    vmovapd [rsp+348h+var_360], xmm0
    vmovsd  xmm0, cs:qword_2038
    vmovsd  [rsp+348h+var_390], xmm0
    vmovddup xmm0, [rsp+348h+var_390]
    vmovapd [rsp+348h+var_350], xmm0
    vmovapd xmm0, [rsp+348h+var_360]
    vmovapd xmm1, [rsp+348h+var_350]
    vcmple_oqpd xmm0, xmm0, xmm1
    vmovapd [rsp+348h+var_340], xmm0
    vmovapd xmm0, [rsp+348h+var_340]
    vmovapd [rsp+348h+var_330], xmm0
    vmovapd xmm0, [rsp+348h+var_330]
    vmovmskpd eax, xmm0
  }
  return (_DWORD)_RAX != 3;
}

SUB11C9함수->내적계산->즉 유저의입력 32바이트중 8바이트단위로 나눈후 유저의 입력 8바이트와 

unk_4020 = [
    [3.387045066050125e+01, -1.324185041221260e+01, -9.317799606909844e+00, 3.071594516945687e+00, -2.806142504512223e+00, -6.339762631327346e+00, -1.139401607224445e+01, 2.935152834317645e+01],
    [-1.344973543616474e+01, -4.867517706614414e+00, 5.015123316054783e+01, -2.781688692079760e+01, -2.429678642992163e+01, 1.324636218789480e+01, -3.513004761686637e+01, 5.725593922781699e+01],
    [-7.817584021800304e+00, -3.688712167973065e+00, 1.376273811332777e+01, -1.131584668758947e-01, 2.264399900900457e+01, -2.269356338446157e+01, -6.363727302253503e+00, 8.219262090587993e+00],
    [-2.791648987201455e+00, -1.608155233849494e+00, 6.360341939439855e+01, -2.814901066476282e+01, 3.585088225073992e+01, -2.074663986297853e+01, -2.025267405001097e+01, 3.325241869083762e+00],
    [-3.421801311475132e+01, 4.201183815559237e+01, 4.603396669885246e+01, -9.106562514210857e+00, 2.536290996037208e+01, 7.819627916685675e+00, -1.956476937819338e+01, -1.639218016215027e+01],
    [-5.315931622696866e-01, -8.552687437228784e+00, 2.439518328363432e+01, -7.378805920886762e+00, 1.885970414078048e+01, -1.502635525333599e+01, 2.629827488534610e+01, -2.623815768726158e+01],
    [6.931061439431262e+01, -1.070779519063509e+01, -1.950178031718001e+01, -1.870605142221053e+01, -3.575098041354232e+01, 3.057781400337144e+01, -2.361443261657830e+01, 4.336145008708302e+01],
    [-4.097359526746330e+01, 4.275248971397427e+01, 3.749954878095529e+01, -2.434054280816612e+01, 3.467401670368094e+01, -1.401049616981334e+01, -1.986979616185187e+01, 2.013601488437402e+01],
    [1.438789187045981e+01, -6.884943956978312e+00, 3.565244160708674e+01, -2.325479765894399e+01, -5.669356989886404e+00, 2.189577222770489e+01, -1.442246554205215e+01, 8.773888507893268e+00],
    [-3.103594974493705e+01, 7.826764505667597e+00, -2.697008990140635e+00, 5.170156599298723e+01, -1.772925144809175e+01, 4.373240358635057e+01, -1.694083550897041e-01, -5.651364774864270e+00],
    [-3.659641961749908e+01, 2.372199805222245e+01, -3.802362559288635e+00, 3.112993892951376e+01, 3.085680921955330e+00, -3.554931530156654e+00, 2.274339174890782e+01, -2.540409098796385e+01],
    [2.569097033019904e+01, -4.808542095460718e+01, 2.281320358668125e+01, 2.288262771134330e+01, -4.520372569157735e+01, 4.890829781062493e+01, 3.813334168389372e+01, 3.715299824395295e+00]
]

unk_4020의 8차원벡터 3개와 비교해서 모두 직교성이 있어야한다. -> 3개의 벡터에서 모두 직교함으로->NULL Space이용->5차원으로 줄어들고 선형방정식으로 풀기가능해짐

_BOOL8 __fastcall sub_14B2(__int64 a1, __int64 a2)
{
  _QWORD v58[4]; // [rsp+20h] [rbp-3E0h] BYREF

  v58[3] = a1;
  _RAX = a1;
  __asm
  {
    vmovupd zmm0, zmmword ptr [rax]
    vmovapd zmmword ptr [rsp+388h+var_140], zmm0
  }
  v58[2] = a1;
  _RAX = a1;
  __asm
  {
    vmovupd zmm0, zmmword ptr [rax]
    vmovapd zmmword ptr [rsp+388h+var_100], zmm0
    vmovapd zmm0, zmmword ptr [rsp+388h+var_140]
    vmovapd zmmword ptr [rsp+388h+var_80], zmm0
    vmovapd zmm0, zmmword ptr [rsp+388h+var_100]
    vmovapd zmmword ptr [rsp+388h+var_40], zmm0
    vmovapd zmm0, zmmword ptr [rsp+388h+var_80]
    vmulpd  zmm0, zmm0, zmmword ptr [rsp+388h+var_40]
    vmovapd zmmword ptr [rsp+388h+var_C0], zmm0
    vmovapd ymm1, [rsp+388h+var_160]
    vmovapd zmm0, zmmword ptr [rsp+388h+var_C0]
  }
  LODWORD(_RAX) = -1;
  __asm
  {
    kmovb   k1, eax
    vextractf64x4 ymm1{k1}, zmm0, 0
    vmovapd [rsp+388h+var_2A0], ymm1
    vmovapd ymm1, [rsp+388h+var_180]
    vmovapd zmm0, zmmword ptr [rsp+388h+var_C0]
  }
  LODWORD(_RAX) = -1;
  __asm
  {
    kmovb   k2, eax
    vextractf64x4 ymm1{k2}, zmm0, 1
    vmovapd [rsp+388h+var_280], ymm1
    vmovapd ymm0, [rsp+388h+var_2A0]
    vmovapd [rsp+388h+var_1C0], ymm0
    vmovapd ymm0, [rsp+388h+var_2A0]
    vmovapd [rsp+388h+var_1A0], ymm0
    vmovapd ymm0, [rsp+388h+var_1C0]
    vhaddpd ymm0, ymm0, [rsp+388h+var_1A0]
    vmovapd [rsp+388h+var_260], ymm0
    vmovapd ymm0, [rsp+388h+var_260]
    vextractf64x2 [rsp+388h+var_3C0], ymm0, 1
    vmovapd ymm0, [rsp+388h+var_260]
    vmovapd [rsp+388h+var_1E0], ymm0
    vmovapd xmm0, xmmword ptr [rsp+388h+var_1E0]
    vmovapd [rsp+388h+var_2C0], xmm0
    vmovapd xmm0, [rsp+388h+var_3C0]
    vmovapd [rsp+388h+var_2B0], xmm0
    vmovapd xmm0, [rsp+388h+var_2C0]
    vaddpd  xmm0, xmm0, [rsp+388h+var_2B0]
    vmovapd [rsp+388h+var_3B0], xmm0
    vmovapd ymm0, [rsp+388h+var_280]
    vmovapd [rsp+388h+var_220], ymm0
    vmovapd ymm0, [rsp+388h+var_280]
    vmovapd [rsp+388h+var_200], ymm0
    vmovapd ymm0, [rsp+388h+var_220]
    vhaddpd ymm0, ymm0, [rsp+388h+var_200]
    vmovapd [rsp+388h+var_260], ymm0
    vmovapd ymm0, [rsp+388h+var_260]
    vextractf64x2 [rsp+388h+var_3C0], ymm0, 1
    vmovapd ymm0, [rsp+388h+var_260]
    vmovapd [rsp+388h+var_240], ymm0
    vmovapd xmm0, xmmword ptr [rsp+388h+var_240]
    vmovapd [rsp+388h+var_2E0], xmm0
    vmovapd xmm0, [rsp+388h+var_3C0]
    vmovapd [rsp+388h+var_2D0], xmm0
    vmovapd xmm0, [rsp+388h+var_2E0]
    vaddpd  xmm0, xmm0, [rsp+388h+var_2D0]
    vmovapd [rsp+388h+var_3A0], xmm0
    vmovapd xmm0, [rsp+388h+var_3B0]
    vmovapd [rsp+388h+var_2F0], xmm0
    vsqrtpd xmm0, [rsp+388h+var_2F0]
    vmovapd [rsp+388h+var_3B0], xmm0
    vmovapd xmm0, [rsp+388h+var_3A0]
    vmovapd [rsp+388h+var_300], xmm0
    vsqrtpd xmm0, [rsp+388h+var_300]
    vmovapd [rsp+388h+var_3A0], xmm0
    vmovapd xmm0, [rsp+388h+var_3B0]
    vmovapd [rsp+388h+var_320], xmm0
    vmovapd xmm0, [rsp+388h+var_3A0]
    vmovapd [rsp+388h+var_310], xmm0
    vmovapd xmm0, [rsp+388h+var_310]
    vmovlpd xmm0, xmm0, qword ptr [rsp+388h+var_320+8]
    vmovapd [rsp+388h+var_390], xmm0
  }
  v58[1] = a2;
  _RAX = a2;
  __asm
  {
    vmovupd xmm0, xmmword ptr [rax]
    vmovapd [rsp+388h+var_380], xmm0
    vmovapd xmm0, [rsp+388h+var_390]
    vmovapd [rsp+388h+var_340], xmm0
    vmovapd xmm0, [rsp+388h+var_380]
    vmovapd [rsp+388h+var_330], xmm0
    vmovapd xmm0, [rsp+388h+var_340]
    vsubpd  xmm0, xmm0, [rsp+388h+var_330]
    vmovapd [rsp+388h+var_390], xmm0
    vmovsd  xmm0, cs:qword_2038
    vmovsd  [rsp+388h+var_3E0], xmm0
    vmovddup xmm0, [rsp+388h+var_3E0]
    vmovapd [rsp+388h+var_370], xmm0
    vmovapd xmm0, [rsp+388h+var_390]
    vmovapd xmm1, [rsp+388h+var_370]
    vcmple_oqpd xmm0, xmm0, xmm1
    vmovapd [rsp+388h+var_360], xmm0
    vmovapd xmm0, [rsp+388h+var_360]
    vmovapd [rsp+388h+var_350], xmm0
    vmovapd xmm0, [rsp+388h+var_350]
    vmovmskpd eax, xmm0
  }
  return (_DWORD)_RAX != 3;
}

SUB11C9함수->노름구하기->유저의 8바이트를 4바이트/ 4바이트를 나누고 각바이트의 제곱을 더한뒤 제곱근과

unk_4320 = [
    [1.344358583116871e+02, 1.595838337677097e+02],
    [1.562241978696002e+02, 1.077172223927075e+02],
    [1.366601624468521e+02, 1.347479127853192e+02],
    [1.590817399955130e+02, 1.346216921599190e+02]
]

 unk_4320와 비교 비선형적인 구조

qword_2038 3E45798EE2308C3Ah

부동소수점으로 인한 허용 오차범위는 다음과 같으며 보기좋게 바꾸면 1e-5정도

 

즉 이걸 역산을하여 구해야하는데

막막했다.

비선형적인 데이터부터 처리하는 방식이 효과적이였고

4바이트 4바이트 각각 부르트포싱(플래그형식이 영어소문자와 숫자로만 이루어져있고)을 해서 노름값이 오차범위 내일때 선형 방정식에 대입해서 구하는것으로 부르트포싱을 진행하니 값을 구할수있었다.

import numpy as np
import scipy.linalg
import itertools

unk_4020 = np.array([
    [3.387045066050125e+01, -1.324185041221260e+01, -9.317799606909844e+00, 3.071594516945687e+00, -2.806142504512223e+00, -6.339762631327346e+00, -1.139401607224445e+01, 2.935152834317645e+01],
    [-1.344973543616474e+01, -4.867517706614414e+00, 5.015123316054783e+01, -2.781688692079760e+01, -2.429678642992163e+01, 1.324636218789480e+01, -3.513004761686637e+01, 5.725593922781699e+01],
    [-7.817584021800304e+00, -3.688712167973065e+00, 1.376273811332777e+01, -1.131584668758947e-01, 2.264399900900457e+01, -2.269356338446157e+01, -6.363727302253503e+00, 8.219262090587993e+00],
    [-2.791648987201455e+00, -1.608155233849494e+00, 6.360341939439855e+01, -2.814901066476282e+01, 3.585088225073992e+01, -2.074663986297853e+01, -2.025267405001097e+01, 3.325241869083762e+00],
    [-3.421801311475132e+01, 4.201183815559237e+01, 4.603396669885246e+01, -9.106562514210857e+00, 2.536290996037208e+01, 7.819627916685675e+00, -1.956476937819338e+01, -1.639218016215027e+01],
    [-5.315931622696866e-01, -8.552687437228784e+00, 2.439518328363432e+01, -7.378805920886762e+00, 1.885970414078048e+01, -1.502635525333599e+01, 2.629827488534610e+01, -2.623815768726158e+01],
    [6.931061439431262e+01, -1.070779519063509e+01, -1.950178031718001e+01, -1.870605142221053e+01, -3.575098041354232e+01, 3.057781400337144e+01, -2.361443261657830e+01, 4.336145008708302e+01],
    [-4.097359526746330e+01, 4.275248971397427e+01, 3.749954878095529e+01, -2.434054280816612e+01, 3.467401670368094e+01, -1.401049616981334e+01, -1.986979616185187e+01, 2.013601488437402e+01],
    [1.438789187045981e+01, -6.884943956978312e+00, 3.565244160708674e+01, -2.325479765894399e+01, -5.66935698986404e+00, 2.189577222770489e+01, -1.442246554205215e+01, 8.773888507893268e+00],
    [-3.103594974493705e+01, 7.826764505667597e+00, -2.697008990140635e+00, 5.170156599298723e+01, -1.772925144809175e+01, 4.373240358635057e+01, -1.694083550897041e-01, -5.651364774864270e+00],
    [-3.659641961749908e+01, 2.372199805222245e+01, -3.802362559288635e+00, 3.112993892951376e+01, 3.085680921955330e+00, -3.554931530156654e+00, 2.274339174890782e+01, -2.540409098796385e+01],
    [2.569097033019904e+01, -4.808542095460718e+01, 2.281320358668125e+01, 2.288262771134330e+01, -4.520372569157735e+01, 4.890829781062493e+01, 3.813334168389372e+01, 3.715299824395295e+00]
])

unk_4320 = np.array([
    [1.344358583116871e+02, 1.595838337677097e+02],
    [1.562241978696002e+02, 1.077172223927075e+02],
    [1.366601624468521e+02, 1.347479127853192e+02],
    [1.590817399955130e+02, 1.346216921599190e+02]
])


valid_ascii = list(range(48, 58)) + list(range(97, 123))
solution_bytes = np.zeros(32, dtype=np.int32)
all_blocks_found = True

print("--- 노름과 널 공간을 이용한 탐색 시작 ---")

for k in range(4): 
    block_A = unk_4020[k*3 : k*3+3]
    block_B = unk_4320[k]
    
    found_block_solution = False
    
    
    for combo1 in itertools.product(valid_ascii, repeat=4):
        vec1 = np.array(combo1, dtype=np.float64)
        if not np.isclose(np.linalg.norm(vec1), block_B[0], atol=1e-5):
            continue
            
        for combo2 in itertools.product(valid_ascii, repeat=4):
            vec2 = np.array(combo2, dtype=np.float64)
            if not np.isclose(np.linalg.norm(vec2), block_B[1], atol=1e-5):
                continue
            
            a1 = np.concatenate([vec1, vec2])
            
            if np.allclose(block_A @ a1, 0, atol=1e-5):
                
                print(f"✅ 블록 {k}의 해를 찾았습니다!")
                solution_bytes[k*8 : k*8+8] = a1.astype(np.int32)
                found_block_solution = True
                break
        
        if found_block_solution:
            break
            
    if not found_block_solution:
        print(f"❌ 블록 {k}의 해를 찾지 못했습니다.")
        all_blocks_found = False
        break

if all_blocks_found:
    solution_string = "".join([chr(b) for b in solution_bytes])
    print("\n--- 최종 결과 ---")
    print("🎉 모든 블록에 대한 해를 찾았습니다!")
    print(f"최종 s 문자열: {solution_string}")
    print("ASCII 값 (바이트):", solution_bytes)
else:
    print("\n--- 최종 결과 ---")
    print("❌ 모든 블록에 대한 해를 찾지 못했습니다.")

GPT에게 아이디어를 줬으나 한번에 완벽하게 짜주진않았다. 여러 코드 교정을 통해 구할수있었고 사용자의 역량이 중요함을 느꼈습니다.

 

 

CPU에서 지원하지않아 SDE라는 인텔 시뮬레이터를 통해 실행시켜야한다.

이후는 삽질내역

ef vector_magnitude_diff_check(a1, a2, threshold):
    norm1 = np.linalg.norm(a1)
    norm2 = np.linalg.norm(a2) 
    diff = norm1 - norm2
    return abs(diff) <= threshold
def simple_check(a1, a2, threshold):
    dot_product = np.dot(a1, a2)
    return dot_product <= threshold
--- 1번째 8바이트 블록 (unk_4020[0:3]) ---
널 공간의 차원: 5
널 공간의 첫 번째 기저 벡터: [-0.26484824 -0.30488498  0.11833734  0.87828732 -0.13767245  0.12868897
 -0.08144505  0.09674903]

직교성 확인:
a2_1와의 내적: 1.776356839400250e-15. 임계값 내? True
a2_2와의 내적: 1.776356839400250e-15. 임계값 내? True
a2_3와의 내적: 1.110223024625157e-15. 임계값 내? True

✅ 1번째 블록의 널 공간 기저 벡터는 모두 직교합니다.

--- 2번째 8바이트 블록 (unk_4020[3:6]) ---
널 공간의 차원: 5
널 공간의 첫 번째 기저 벡터: [-0.28197421 -0.3181236   0.1882102   0.84779463  0.137231   -0.14354821
 -0.11482088  0.11174446]

직교성 확인:
a2_1와의 내적: 1.776356839400250e-14. 임계값 내? True
a2_2와의 내적: 3.552713678800501e-15. 임계값 내? True
a2_3와의 내적: 0.000000000000000e+00. 임계값 내? True

✅ 2번째 블록의 널 공간 기저 벡터는 모두 직교합니다.

--- 3번째 8바이트 블록 (unk_4020[6:9]) ---
널 공간의 차원: 5
널 공간의 첫 번째 기저 벡터: [ 0.21018609  0.27393102  0.37260294  0.83796613 -0.00258023  0.10208624
 -0.12204211  0.12017019]

직교성 확인:
a2_1와의 내적: -5.329070518200751e-15. 임계값 내? True
a2_2와의 내적: 5.329070518200751e-15. 임계값 내? True
a2_3와의 내적: -3.552713678800501e-15. 임계값 내? True

✅ 3번째 블록의 널 공간 기저 벡터는 모두 직교합니다.

--- 4번째 8바이트 블록 (unk_4020[9:12]) ---
널 공간의 차원: 5
널 공간의 첫 번째 기저 벡터: [ 0.62457199  0.0776084  -0.13643957  0.67696575  0.16255312 -0.3096619
 -0.06072902  0.03140648]

직교성 확인:
a2_1와의 내적: -7.105427357601002e-15. 임계값 내? True
a2_2와의 내적: 3.552713678800501e-15. 임계값 내? True
a2_3와의 내적: -5.329070518200751e-15. 임계값 내? True

✅ 4번째 블록의 널 공간 기저 벡터는 모두 직교합니다

'리버싱!' 카테고리의 다른 글

ransomeware_cce2025 정리  (0) 2025.10.16
cce2025  (4) 2025.08.19
justCTF2025  (0) 2025.08.03
UIUCTF 2025-풀이  (3) 2025.07.26
DownUnderCTF2025-풀이  (3) 2025.07.21