수호의 메모장
Let's break 010Editor's License Authentication! 본문
Security/Reverse Engineering
Let's break 010Editor's License Authentication!
수호-_- 2023. 9. 20. 15:31
헥스에디터로 뭐 하나 분석하려고 했건만 30일 체험판이 끝나버렸대요 ಢ‸ಢ
010 Editor의 편리함을 아는 나는 차마 HxD로 돌아가기 싫어하는데..

제겐 든든한 아이다씨가 있죠!
먼저 만료된 010 Editor을 실행시키면 아래와 같은 String을 포착할 수 있어요:

IDA로 String을 추출시키고 xref를 따라가 봅시다



위의 함수로 이동 되는데, 이것을 hexray로 디컴파일 하면 아래와 같은 의사코드가 나와요


딱봐도 라이센싱과 관련된 함수로 보이죠? 전체 의사코드는 아래와 같아요:
void __fastcall j_nullsub_54_0(__int64 a1)
{
int v2; // r15d
__int64 v3; // rax
const struct QString *v4; // rbx
const struct QString *v5; // rbx
const struct QString *v6; // rax
const struct QString *v7; // rbx
const struct QString *v8; // rax
QString *v9; // rbx
const struct QString *v10; // rax
unsigned int v11; // esi
int v12; // eax
__int64 *v13; // rcx
const struct QString *v14; // rdi
const struct QString *v15; // rbx
const struct QString *v16; // rbx
const struct QString *v17; // rax
const struct QString *v18; // rbx
const struct QString *v19; // rbx
const struct QString *v20; // rax
const struct QString *v21; // rbx
const struct QString *v22; // rax
QString *v23; // rbx
const struct QString *v24; // rax
__int64 *v25; // rcx
const struct QString *v26; // rbx
const struct QString *v27; // rbx
const struct QString *v28; // rax
const struct QString *v29; // rbx
const struct QString *v30; // rax
QString *v31; // rbx
const struct QString *v32; // rax
const struct QString *v33; // rbx
const struct QString *v34; // rbx
const struct QString *v35; // rax
const struct QString *v36; // rbx
const struct QString *v37; // rax
QString *v38; // rbx
const struct QString *v39; // rax
__int64 v40; // rdx
const struct QString *v41; // rbx
const struct QString *v42; // rax
const struct QString *v43; // rdi
const struct QString *v44; // rbx
const struct QString *v45; // rbx
const struct QString *v46; // rax
__int64 *v47; // rdi
int v48; // esi
const struct QString *v49; // rbx
int v50; // esi
const struct QString *v51; // rbx
const struct QString *v52; // rax
unsigned int v53; // esi
const struct QString *v54; // rbx
int v55; // esi
const struct QString *v56; // rbx
const struct QString *v57; // rax
__int64 v58; // rdx
const struct QString *v59; // rbx
int v60; // esi
const struct QString *v61; // rax
const struct QString *v62; // rdi
const struct QString *v63; // rbx
int v64; // esi
const struct QString *v65; // rbx
const struct QString *v66; // rax
const struct QString *v67; // rdi
__int64 v68; // rbx
int v69; // esi
unsigned int v70; // esi
int v71; // eax
const struct QString *v72; // rdi
const struct QString *v73; // rbx
const struct QString *v74; // rbx
const struct QString *v75; // rax
int v76; // eax
int v77; // ebx
unsigned __int8 v78; // di
__int64 v79; // rdx
__int64 v80; // rdx
__int64 v81; // rdx
__int64 v82; // rdx
__int64 v83; // rdx
__int64 v84; // rdx
char v85[8]; // [rsp+20h] [rbp-48h] BYREF
char v86[8]; // [rsp+28h] [rbp-40h] BYREF
__int64 v87; // [rsp+30h] [rbp-38h] BYREF
__int64 v88; // [rsp+38h] [rbp-30h] BYREF
__int64 v89; // [rsp+40h] [rbp-28h] BYREF
__int64 v90; // [rsp+48h] [rbp-20h] BYREF
__int64 v91; // [rsp+50h] [rbp-18h] BYREF
char v92[16]; // [rsp+58h] [rbp-10h] BYREF
__int64 v93; // [rsp+A0h] [rbp+38h] BYREF
__int64 v94; // [rsp+A8h] [rbp+40h] BYREF
char v95; // [rsp+B0h] [rbp+48h] BYREF
char v96; // [rsp+B8h] [rbp+50h] BYREF
v2 = 0;
LODWORD(v93) = 0;
LODWORD(v94) = 0;
QString::QString(&v95);
QString::QString(&v96);
QString::QString(v86);
QString::QString(v85);
v3 = qword_140D64950;
if ( !qword_140D64950 )
{
v93 = operator new((unsigned int)(qword_140D64950 + 80));
v3 = sub_140009520(v93);
qword_140D64950 = v3;
}
sub_140001569(v3);
*(_DWORD *)(a1 + 412) = sub_140008693(qword_140D64950, 14i64, 19242i64);
QString::operator=(
v86,
"Thank you for using 010 Editor, the only text/hex editor with powerful Binary Templates technology. ");
v90 = QString::fromAscii_helper(
"You may use this software free for 30 days. After that time, you will need to purchase a license to continue u"
"sing the software. For more information, please click on \"Purchase a license\" below ",
194i64);
v4 = QString::QString((QString *)&v89, (const struct QString *)v86);
LODWORD(v93) = 4;
QString::append((QString *)&v89, (const struct QString *)&v90);
v5 = QString::QString((QString *)&v88, v4);
LODWORD(v93) = 12;
v6 = (const struct QString *)QString::fromUtf8(&v91, "or visit \"", 0xFFFFFFFFi64);
QString::append((QString *)&v88, v6);
QString::~QString(&v91);
v7 = QString::QString((QString *)&v87, v5);
LODWORD(v93) = 28;
v8 = (const struct QString *)QString::fromUtf8(&v91, "https://www.sweetscape.com/store/", 0xFFFFFFFFi64);
QString::append((QString *)&v87, v8);
QString::~QString(&v91);
v9 = QString::QString((QString *)&v94, v7);
LODWORD(v93) = 60;
v10 = (const struct QString *)QString::fromUtf8(&v91, "\".", 0xFFFFFFFFi64);
QString::append((QString *)&v94, v10);
QString::~QString(&v91);
QString::operator=(&v95, v9);
QString::~QString(&v94);
QString::~QString(&v87);
QString::~QString(&v88);
v11 = 0;
LODWORD(v93) = 0;
QString::~QString(&v89);
QString::~QString(&v90);
v12 = *(_DWORD *)(a1 + 412);
if ( v12 != 219 )
{
if ( v12 == 375 )
{
v93 = QString::fromAscii_helper("Evaluation Period Expired", 25i64);
QLabel::setText(*(QLabel **)(a1 + 200), (const struct QString *)&v93);
QString::~QString(&v93);
v87 = QString::fromAscii_helper(
"Your free 30-day trial period has now ended. To continue using this program you will need to purchase a li"
"cense. For more information please click on \"Purchase a license\" below ",
177i64);
v18 = QString::QString((QString *)&v88, (const struct QString *)v86);
LODWORD(v93) = 256;
QString::append((QString *)&v88, (const struct QString *)&v87);
v19 = QString::QString((QString *)&v89, v18);
LODWORD(v93) = 768;
v20 = (const struct QString *)QString::fromUtf8(&v91, "or visit \"", 0xFFFFFFFFi64);
QString::append((QString *)&v89, v20);
QString::~QString(&v91);
v21 = QString::QString((QString *)&v90, v19);
LODWORD(v93) = 1792;
v22 = (const struct QString *)QString::fromUtf8(&v91, "https://www.sweetscape.com/store/", 0xFFFFFFFFi64);
QString::append((QString *)&v90, v22);
QString::~QString(&v91);
v23 = QString::QString((QString *)&v94, v21);
LODWORD(v93) = 3840;
v24 = (const struct QString *)QString::fromUtf8(&v91, "\".", 0xFFFFFFFFi64);
QString::append((QString *)&v94, v24);
QString::~QString(&v91);
QString::operator=(&v95, v23);
QString::~QString(&v94);
QString::~QString(&v90);
QString::~QString(&v89);
v11 = 0;
LODWORD(v93) = 0;
QString::~QString(&v88);
v25 = &v87;
}
else if ( v12 == 275 )
{
v93 = QString::fromAscii_helper("Invalid License", 15i64);
QLabel::setText(*(QLabel **)(a1 + 200), (const struct QString *)&v93);
QString::~QString(&v93);
v91 = QString::fromAscii_helper(
"Your free 30-day trial period has now ended. To continue using this program, you will need to purchase a l"
"icense. For more information, please click on \"Purchase a license\" below ",
179i64);
v87 = QString::fromAscii_helper("010 Editor has detected that you are using an invalid license. ", 63i64);
v26 = QString::QString((QString *)&v88, (const struct QString *)&v87);
LODWORD(v93) = 4096;
QString::append((QString *)&v88, (const struct QString *)&v91);
v27 = QString::QString((QString *)&v89, v26);
LODWORD(v93) = 12288;
v28 = (const struct QString *)QString::fromUtf8(v92, "or visit \"", 0xFFFFFFFFi64);
QString::append((QString *)&v89, v28);
QString::~QString(v92);
v29 = QString::QString((QString *)&v90, v27);
LODWORD(v93) = 28672;
v30 = (const struct QString *)QString::fromUtf8(v92, "https://www.sweetscape.com/store/", 0xFFFFFFFFi64);
QString::append((QString *)&v90, v30);
QString::~QString(v92);
v31 = QString::QString((QString *)&v94, v29);
LODWORD(v93) = 61440;
v32 = (const struct QString *)QString::fromUtf8(v92, "\".", 0xFFFFFFFFi64);
QString::append((QString *)&v94, v32);
QString::~QString(v92);
QString::operator=(&v95, v31);
QString::~QString(&v94);
QString::~QString(&v90);
QString::~QString(&v89);
v11 = 0;
LODWORD(v93) = 0;
QString::~QString(&v88);
QString::~QString(&v87);
v25 = &v91;
}
else if ( v12 == 237 )
{
v93 = QString::fromAscii_helper("Upgrade Required - Evaluation Expired", 37i64);
QLabel::setText(*(QLabel **)(a1 + 200), (const struct QString *)&v93);
QString::~QString(&v93);
v88 = QString::fromAscii_helper(
"Your free 30-day trial period has now ended. To continue using this program you will need to purchase an u"
"pgrade. For more information please click on \"Purchase an upgrade\" below ",
179i64);
v33 = QString::QString((QString *)&v89, (const struct QString *)v86);
LODWORD(v93) = 0x10000;
QString::append((QString *)&v89, (const struct QString *)&v88);
v34 = QString::QString((QString *)&v90, v33);
LODWORD(v93) = 196608;
v35 = (const struct QString *)QString::fromUtf8(v92, "or visit \"", 0xFFFFFFFFi64);
QString::append((QString *)&v90, v35);
QString::~QString(v92);
v36 = QString::QString((QString *)&v91, v34);
LODWORD(v93) = 458752;
v37 = (const struct QString *)QString::fromUtf8(v92, "https://www.sweetscape.com/store/", 0xFFFFFFFFi64);
QString::append((QString *)&v91, v37);
QString::~QString(v92);
v38 = QString::QString((QString *)&v94, v36);
LODWORD(v93) = 983040;
v39 = (const struct QString *)QString::fromUtf8(v92, "\".", 0xFFFFFFFFi64);
QString::append((QString *)&v94, v39);
QString::~QString(v92);
QString::operator=(&v95, v38);
QString::~QString(&v94);
QString::~QString(&v91);
QString::~QString(&v90);
v11 = 0;
LODWORD(v93) = 0;
QString::~QString(&v89);
v25 = &v88;
}
else
{
if ( v12 != 47 )
{
if ( v12 == 249 )
{
v93 = QString::fromAscii_helper("Evaluation Version", 18i64);
QLabel::setText(*(QLabel **)(a1 + 200), (const struct QString *)&v93);
QString::~QString(&v93);
QString::operator=(&v96, "Evaluation Version - ");
v40 = *(unsigned int *)(qword_140D64950 + 52);
if ( (_DWORD)v40 == 1 )
{
v41 = QString::QString((QString *)&v94, (const struct QString *)&v96);
LODWORD(v93) = 0x100000;
v42 = (const struct QString *)QString::fromUtf8(v92, "1 Use Left", 0xFFFFFFFFi64);
QString::append((QString *)&v94, v42);
QString::~QString(v92);
QLabel::setText(*(QLabel **)(a1 + 200), v41);
v11 = 0;
LODWORD(v93) = 0;
v25 = &v94;
goto LABEL_36;
}
v43 = (const struct QString *)QString::number(&v90, v40, 10i64);
v44 = QString::QString((QString *)&v91, (const struct QString *)&v96);
LODWORD(v93) = 0x200000;
QString::append((QString *)&v91, v43);
v45 = QString::QString((QString *)&v94, v44);
LODWORD(v93) = 6291456;
v46 = (const struct QString *)QString::fromUtf8(v92, " Uses Left", 0xFFFFFFFFi64);
QString::append((QString *)&v94, v46);
QString::~QString(v92);
QLabel::setText(*(QLabel **)(a1 + 200), v45);
QString::~QString(&v94);
v11 = 0;
LODWORD(v93) = 0;
QString::~QString(&v91);
}
else
{
if ( v12 == 524 )
{
QString::operator=(&v96, "Upgrade Required - ");
QString::operator=(&v95, &Str1);
QString::operator+=(
&v95,
"Your license is for an earlier version of this program and you will have to purchase an upgrade to continu"
"e using this software. ");
if ( *(_DWORD *)(a1 + 416) )
{
v89 = QString::fromAscii_helper("Continue", 8i64);
v47 = &v89;
v48 = 1;
}
else
{
v90 = QString::fromAscii_helper("Cancel", 6i64);
v47 = &v90;
v48 = 2;
}
LODWORD(v93) = v48;
v49 = (const struct QString *)QString::fromUtf8(
&v91,
"To use this program as a 30-day trial version click the \"",
0xFFFFFFFFi64);
v50 = v48 | 0x800000;
LODWORD(v93) = v50;
QString::append((QString *)&v91, (const struct QString *)v47);
v51 = QString::QString((QString *)&v94, v49);
v50 |= 0x1000000u;
LODWORD(v93) = v50;
v52 = (const struct QString *)QString::fromUtf8(v92, "\" button ", 0xFFFFFFFFi64);
QString::append((QString *)&v94, v52);
QString::~QString(v92);
QString::append((QString *)&v95, v51);
QString::~QString(&v94);
v53 = v50 & 0xFE7FFFFF;
LODWORD(v93) = v53;
QString::~QString(&v91);
if ( (v53 & 2) != 0 )
{
v53 &= ~2u;
LODWORD(v93) = v53;
QString::~QString(&v90);
}
if ( (v53 & 1) != 0 )
{
v53 &= ~1u;
LODWORD(v93) = v53;
QString::~QString(&v89);
}
QString::operator+=(&v95, "or to purchase an upgrade click the first link below. ");
v90 = QString::fromAscii_helper("https://www.sweetscape.com/download/previous/", 45i64);
v54 = (const struct QString *)QString::fromUtf8(
&v91,
"You may download previous versions of 010 Editor from \"",
0xFFFFFFFFi64);
v55 = v53 | 0x2000000;
LODWORD(v93) = v55;
QString::append((QString *)&v91, (const struct QString *)&v90);
v56 = QString::QString((QString *)&v94, v54);
v55 |= 0x4000000u;
LODWORD(v93) = v55;
v57 = (const struct QString *)QString::fromUtf8(v92, "\". Thank you!", 0xFFFFFFFFi64);
QString::append((QString *)&v94, v57);
QString::~QString(v92);
QString::append((QString *)&v95, v56);
QString::~QString(&v94);
v11 = v55 & 0xF9FFFFFF;
QString::~QString(&v91);
QString::~QString(&v90);
}
else
{
QString::operator=(&v96, "Evaluation Version - ");
}
v58 = (unsigned int)(*(_DWORD *)(qword_140D64950 + 40) - *(_DWORD *)(qword_140D64950 + 36));
if ( (_DWORD)v58 == 1 )
{
v59 = QString::QString((QString *)&v94, (const struct QString *)&v96);
v60 = v11 | 0x8000000;
LODWORD(v93) = v60;
v61 = (const struct QString *)QString::fromUtf8(v92, "1 Day Left", 0xFFFFFFFFi64);
QString::append((QString *)&v94, v61);
QString::~QString(v92);
QLabel::setText(*(QLabel **)(a1 + 200), v59);
v11 = v60 & 0xF7FFFFFF;
LODWORD(v93) = v11;
v25 = &v94;
goto LABEL_36;
}
v62 = (const struct QString *)QString::number(&v90, v58, 10i64);
v63 = QString::QString((QString *)&v91, (const struct QString *)&v96);
v64 = v11 | 0x10000000;
LODWORD(v93) = v64;
QString::append((QString *)&v91, v62);
v65 = QString::QString((QString *)&v94, v63);
v64 |= 0x20000000u;
LODWORD(v93) = v64;
v66 = (const struct QString *)QString::fromUtf8(v92, " Days Left", 0xFFFFFFFFi64);
QString::append((QString *)&v94, v66);
QString::~QString(v92);
QLabel::setText(*(QLabel **)(a1 + 200), v65);
QString::~QString(&v94);
v11 = v64 & 0xCFFFFFFF;
LODWORD(v93) = v11;
QString::~QString(&v91);
}
v25 = &v90;
goto LABEL_36;
}
v94 = QString::fromAscii_helper("Bad Clock Date", 14i64);
QLabel::setText(*(QLabel **)(a1 + 200), (const struct QString *)&v94);
v25 = &v94;
}
LABEL_36:
QString::~QString(v25);
goto LABEL_37;
}
if ( *(_DWORD *)(qword_140D64950 + 48) == 1 )
{
v94 = QString::fromAscii_helper("Registered - Single User License", 32i64);
QLabel::setText(*(QLabel **)(a1 + 200), (const struct QString *)&v94);
v13 = &v94;
}
else if ( (unsigned int)sub_14000B406() )
{
v94 = QString::fromAscii_helper("Registered - Site License", 25i64);
QLabel::setText(*(QLabel **)(a1 + 200), (const struct QString *)&v94);
v13 = &v94;
}
else
{
v14 = (const struct QString *)QString::number(&v89, *(unsigned int *)(qword_140D64950 + 48), 10i64);
v15 = (const struct QString *)QString::fromUtf8(&v90, "Registered - ", 0xFFFFFFFFi64);
LODWORD(v93) = 64;
QString::append((QString *)&v90, v14);
v16 = QString::QString((QString *)&v94, v15);
LODWORD(v93) = 192;
v17 = (const struct QString *)QString::fromUtf8(&v91, " User License", 0xFFFFFFFFi64);
QString::append((QString *)&v94, v17);
QString::~QString(&v91);
QLabel::setText(*(QLabel **)(a1 + 200), v16);
QString::~QString(&v94);
v11 = 0;
LODWORD(v93) = 0;
QString::~QString(&v90);
v13 = &v89;
}
QString::~QString(v13);
QString::operator=(&v95, "Your registration has been accepted. Thank you for purchasing 010 Editor.");
LABEL_37:
QLabel::setText(*(QLabel **)(a1 + 256), (const struct QString *)&v95);
if ( *(_DWORD *)(qword_140D64950 + 68) )
{
sub_14000376F(qword_140D64950, v92);
v91 = QString::fromAscii_helper("MMMM d, yyyy", 12i64);
v67 = (const struct QString *)QDate::toString(v92, &v90, &v91);
v68 = QString::fromUtf8(&v94, "Free Upgrades, Support, and Repository Updates Expire:\n ", 0xFFFFFFFFi64);
v69 = v11 | 0x40000000;
LODWORD(v93) = v69;
QString::append((QString *)&v94, v67);
QString::operator=(v85, v68);
v70 = v69 & 0xBFFFFFFF;
LODWORD(v93) = v70;
QString::~QString(&v94);
QString::~QString(&v90);
QString::~QString(&v91);
v71 = sub_14000AE25(qword_140D64950);
if ( v71 >= 0 )
{
v72 = (const struct QString *)QString::number(&v88, (unsigned int)v71, 10i64);
v73 = (const struct QString *)QString::fromUtf8(&v90, " (", 0xFFFFFFFFi64);
LODWORD(v93) = v70 | 0x80000000;
QString::append((QString *)&v90, v72);
v74 = QString::QString((QString *)&v91, v73);
LODWORD(v94) = 1;
v75 = (const struct QString *)QString::fromUtf8(&v89, " days left)", 0xFFFFFFFFi64);
QString::append((QString *)&v91, v75);
QString::~QString(&v89);
QString::append((QString *)v85, v74);
QString::~QString(&v91);
QString::~QString(&v90);
QString::~QString(&v88);
}
else
{
QString::operator+=(v85, " (EXPIRED)");
}
}
QLabel::setText(*(QLabel **)(a1 + 384), (const struct QString *)v85);
v76 = *(_DWORD *)(a1 + 412);
if ( v76 == 524 || (v77 = 0, v76 == 237) )
v77 = 1;
if ( v76 == 219 || v76 == 524 || v76 == 237 )
{
v2 = 1;
v78 = 1;
}
else
{
v78 = 0;
}
(*(void (__fastcall **)(_QWORD, _QWORD))(**(_QWORD **)(a1 + 272) + 88i64))(*(_QWORD *)(a1 + 272), 0i64);
(*(void (__fastcall **)(_QWORD, _QWORD))(**(_QWORD **)(a1 + 280) + 88i64))(*(_QWORD *)(a1 + 280), 0i64);
(*(void (__fastcall **)(_QWORD, _QWORD))(**(_QWORD **)(a1 + 288) + 88i64))(
*(_QWORD *)(a1 + 288),
(unsigned __int8)v77);
(*(void (__fastcall **)(_QWORD, _QWORD))(**(_QWORD **)(a1 + 296) + 88i64))(
*(_QWORD *)(a1 + 296),
(unsigned __int8)v77);
LOBYTE(v79) = 1;
(*(void (__fastcall **)(_QWORD, __int64))(**(_QWORD **)(a1 + 304) + 88i64))(*(_QWORD *)(a1 + 304), v79);
LOBYTE(v80) = 1;
(*(void (__fastcall **)(_QWORD, __int64))(**(_QWORD **)(a1 + 312) + 88i64))(*(_QWORD *)(a1 + 312), v80);
if ( !v2 || v77 )
v81 = 0i64;
else
LOBYTE(v81) = 1;
(*(void (__fastcall **)(_QWORD, __int64))(**(_QWORD **)(a1 + 320) + 88i64))(*(_QWORD *)(a1 + 320), v81);
if ( !v2 || v77 )
v82 = 0i64;
else
LOBYTE(v82) = 1;
(*(void (__fastcall **)(_QWORD, __int64))(**(_QWORD **)(a1 + 328) + 88i64))(*(_QWORD *)(a1 + 328), v82);
LOBYTE(v83) = 1;
(*(void (__fastcall **)(_QWORD, __int64))(**(_QWORD **)(a1 + 336) + 88i64))(*(_QWORD *)(a1 + 336), v83);
LOBYTE(v84) = 1;
(*(void (__fastcall **)(_QWORD, __int64))(**(_QWORD **)(a1 + 344) + 88i64))(*(_QWORD *)(a1 + 344), v84);
(*(void (__fastcall **)(_QWORD, _QWORD))(**(_QWORD **)(a1 + 352) + 88i64))(*(_QWORD *)(a1 + 352), v78);
(*(void (__fastcall **)(_QWORD, _QWORD))(**(_QWORD **)(a1 + 360) + 88i64))(*(_QWORD *)(a1 + 360), v78);
(*(void (__fastcall **)(_QWORD, _QWORD))(**(_QWORD **)(a1 + 368) + 88i64))(*(_QWORD *)(a1 + 368), v78);
(*(void (__fastcall **)(_QWORD, _QWORD))(**(_QWORD **)(a1 + 376) + 88i64))(*(_QWORD *)(a1 + 376), v78);
QBasicTimer::start((QBasicTimer *)(a1 + 420), 10, (struct QObject *)a1);
QString::~QString(v85);
QString::~QString(v86);
QString::~QString(&v96);
QString::~QString(&v95);
}
이 함수를 0xC3(==ret)로 패치하여 호출되자마자 리턴되게 패치를 해 보아요!

결과:

만료되었다는 창이 뜨지만 x를 눌러 창을 닫아버리면?

프로그램이 정상적으로 실행되게 된다!
2ez
'Security > Reverse Engineering' 카테고리의 다른 글
[dreamhack, rev] Permpkin writeup (2) | 2023.11.20 |
---|---|
Easy_ELF [KUCC 정뾰 과제] (0) | 2023.10.10 |
code2 [KUCC 정뾰 세션 과제] (0) | 2023.10.10 |
NtQuerySystemInformation API Hooking을 통한 Usermode Process Hiding (0) | 2022.10.11 |