__int16 __cdecl ExploitPoint(wchar_t *Source, CHAR *lpString, char *String, _DWORD *a4, int *a5) { __int16 v5; // di wchar_t *concatURL_addr; // ebx CHAR *lpString_copy; // eax CHAR v8; // dl __int64 len_lpString; // rax wchar_t *Source_copy; // ecx __int64 len_Source; // rax int v12; // eax int totallen_Source; // eax int len_Source_notUTF; // eax CHAR *allocadr_Source; // eax wchar_t *v16; // ecx int totallen_lpString; // eax int len_lpString_notUTF; // eax CHAR *allocadr_lpString; // eax int v20; // eax int v21; // edx int v22; // edx _DWORD *v23; // eax int v24; // ecx int *v25; // eax int v26; // ecx int v27; // eax int v28; // ecx int v29; // eax wchar_t *v30; // ecx int v31; // eax int len_allocaddr; // eax int v33; // eax int v34; // ecx int v35; // edx wchar_t *v37; // [esp-4h] [ebp-F4h] unsigned int v38; // [esp-4h] [ebp-F4h] wchar_t *v39; // [esp-4h] [ebp-F4h] unsigned int v40; // [esp-4h] [ebp-F4h] unsigned int v41; // [esp-4h] [ebp-F4h] int v42[7]; // [esp+Ch] [ebp-E4h] BYREF int v43; // [esp+28h] [ebp-C8h] int v44; // [esp+2Ch] [ebp-C4h] int v45; // [esp+30h] [ebp-C0h] int v46; // [esp+34h] [ebp-BCh] wchar_t *v47; // [esp+38h] [ebp-B8h] __int64 v48; // [esp+3Ch] [ebp-B4h] int v49; // [esp+4Ch] [ebp-A4h] int v50[3]; // [esp+50h] [ebp-A0h] BYREF int v51; // [esp+5Ch] [ebp-94h] int v52; // [esp+60h] [ebp-90h] int v53; // [esp+64h] [ebp-8Ch] int v54; // [esp+68h] [ebp-88h] int v55; // [esp+6Ch] [ebp-84h] int v56; // [esp+70h] [ebp-80h] int v57; // [esp+74h] [ebp-7Ch] int v58; // [esp+78h] [ebp-78h] char *v59; // [esp+7Ch] [ebp-74h] __int64 v60; // [esp+80h] [ebp-70h] __int64 v61; // [esp+88h] [ebp-68h] int v62; // [esp+90h] [ebp-60h] int v63[3]; // [esp+94h] [ebp-5Ch] BYREF int v64; // [esp+A0h] [ebp-50h] int v65; // [esp+A4h] [ebp-4Ch] int v66; // [esp+A8h] [ebp-48h] int v67; // [esp+ACh] [ebp-44h] int v68; // [esp+B0h] [ebp-40h] int v69; // [esp+B4h] [ebp-3Ch] int v70; // [esp+B8h] [ebp-38h] int v71; // [esp+BCh] [ebp-34h] void *v72; // [esp+C0h] [ebp-30h] __int128 v73; // [esp+C4h] [ebp-2Ch] int v74; // [esp+D4h] [ebp-1Ch] int iMaxLength[2]; // [esp+D8h] [ebp-18h] LPCSTR allocadr_lpString_copy; // [esp+E0h] [ebp-10h] LPCSTR allocadr_Source_copy; // [esp+E4h] [ebp-Ch] int v78[2]; // [esp+E8h] [ebp-8h] BYREF allocadr_Source_copy = 0; allocadr_lpString_copy = 0; v5 = 1; *(_QWORD *)v78 = 0i64; *(_QWORD *)iMaxLength = 0i64; concatURL_addr = 0; v49 = 0; v62 = 0; v74 = 0; if(!a5) return 0; *a5 = 0; // [1-1] relative URL 길이 측정 lpString_copy = lpString; if(lpString && *lpString && (v8 = lpString[1]) != 0 && *lpString == (CHAR)0xFE && v8 == (CHAR)0xFF) { len_lpString = ((__int64 (__cdecl *)(CHAR *))strlen_UTF16BE)(lpString); v78[1] = len_lpString; if ((HIDWORD(len_lpString)&(unsigned int)len_lpString) == -1) { LABEL_9: *a5 = -2; return 0; } lpString_copy = lpString; } else { v78[1] = v78[0]; } // [1-2] base URL 길이 측정 Source_copy = Source; if(!Source || !lpString_copy || !String || !a4) { *a5 = -2; goto LABEL_86; } if(*(_BYTE *)Source != 0xFE) goto LABEL_25; if(*((_BYTE *)Source+1) == 0xFF) { len_Source = ((__int64 (__cdecl *)(wchar_t *))strlen_UTF16BE)(Source); iMaxLength[1] = len_Source; if((HIDWORD(len_Source)&(unsigned int)len_Source) == -1) goto LABEL_9; Source_copy = Source; v12 = iMaxLength[1]; } else { v12 = iMaxLength[0]; } if(*(_BYTE *)Source_copy == 0xFE && *((_BYTE *)Source_copy+1) == 0xFF) { totallen_Source = v12 + 2; } else { LABEL_25: len_Source_notUTF = (int)custom_strlen((LPCSTR)Source_copy); Source_copy = v37; totallen_Source = len_Source_notUTF + 1; } iMaxLength[1] = totallen_Source; // [2-1] base URL을 새로운 heap에 저장 allocadr_Source = (CHAR *)((int (__usercall *)@(wchar_t *@, int, int))calloc_guess)(Source_copy, 1, totallen_Source); allocadr_Source_copy = allocadr_Source; if(!allocadr_Source) { *a5 = -7; return 0; } ((void (__usercall *)(unsigned int@, wchar_t *, wchar_t *, int))custom_strncpy)(v38, (wchar_t *)allocadr_Source, Source, iMaxLength[1]); if(*lpString==(CHAR)0xFE && lpString[1]==(CHAR)0xFF) { totallen_lpString = v78[1] + 2; } else { len_lpString_notUTF = (int)custom_strlen(lpString); v16 = v39; totallen_lpString = len_lpString_notUTF + 1; } v78[1] = totallen_lpString; // [2-2] relative URL을 새로운 heap에 저장 allocadr_lpString = (CHAR *)((int (__usercall *)@(wchar_t *@, int, int))calloc_guess)(v16, 1, totallen_lpString); allocadr_lpString_copy = allocadr_lpString; if(!allocadr_lpString) { *a5 = -7; LABEL_86: v5 = 0; goto LABEL_87; } ((void (__usercall *)(unsigned int@, wchar_t *, wchar_t *, int))custom_strncpy)(v40, (wchar_t *)allocadr_lpString, (wchar_t *)lpString, v78[1]); if(!(unsigned __int16)check_modify_URL((int)allocadr_Source_copy, iMaxLength[1], a5) || !(unsigned __int16)check_modify_URL((int)allocadr_lpString_copy, v78[1], a5)) { goto LABEL_86; } // [3] URL 관련 연산 수행 v20 = URLparse_process((CHAR *)allocadr_Source_copy, v42); if(v20 || (v20 = URLparse_process((CHAR *)allocadr_lpString_copy, v50)) != 0) { *a5 = v20; goto LABEL_86; } if(!*(_BYTE *)Source || (v21 = v42[0], v50[0] != 5) && v50[0] != v42[0]) { v35 = sub_25802FAC((int)v50); v23 = a4; v24 = v35 + 1; if(v35 + 1 > *a4) goto LABEL_44; *a4 = v35; v25 = v50; goto LABEL_82; } if(*lpString) { v26 = v55; v63[1] = v42[1]; v63[2] = v42[2]; v27 = v51; v63[0] = v42[0]; v73 = 0i64; if(!v51 && !v53 && !v55) { if(sub_25803155(v50)) { v28 = v44; v64 = v42[3]; v65 = v42[4]; v66 = v42[5]; v67 = v42[6]; v29 = v43; if(v49 == 1) { v29 = v43 + 2; v28 = v44 - 1; v43 += 2; --v44; } v69 = v28; v68 = v29; v70 = v45; if(v58) { if (*v59 != '/') { // [4] 연결된 URL을 저장하기 위한 새로운 heap 할당 concatURL_addr = (wchar_t *)((int (__usercall *)@(wchar_t *@, int, int))calloc_guess)((wchar_t *)(v58 + 1), 1, v58 + 1 + v46); if(!concatURL_addr) { v23 = a4; v24 = v58 + v46 + 1; goto LABEL_44; } if(v46) { // [5] base URL을 [4]에서 할당한 heap memory에 저장 ((void (__usercall *)(unsigned int@, wchar_t *, wchar_t *, int))custom_strncpy)(v41, concatURL_addr, v47, v46 + 1); if (*((_BYTE *)concatURL_addr + v46 - 1) != '/') { v31 = ((int (__usercall *)@(wchar_t *@, char *, int))sub_25818D6E)(v30, (char *)concatURL_addr, '/'); if(v31) *(_BYTE *)(v31 + 1) = 0; else *(_BYTE *)concatURL_addr = 0; } } // [6] relative URL을 [5]에서 저장한 base URL 뒤에 이어 붙임 : 취약점 발생 if(v58) { len_allocaddr = (int)custom_strlen((LPCSTR)concatURL_addr); ((void (__usercall *)(uintptr_t@, char *, char *, int))custom_strncat)(v58 + 1, (char *)concatURL_addr, v59, v58 + 1 + len_allocaddr); } sub_25802E0C((int)concatURL_addr, 0); v71 = (int)custom_strlen((LPCSTR)concatURL_addr); v72 = concatURL_addr; goto LABEL_75; } v71 = v58; v72 = v59; } else { v71 = v46; v72 = v47; if((_DWORD)v60) goto LABEL_75; *(_QWORD *)&v73 = v48; } LABEL_74: if((_DWORD)v73) { LABEL_77: if ( (int)v61 > 0 ) *((_QWORD *)&v73 + 1) = v61; v34 = sub_25802FAC((int)v63); if(v34+1 > *a4) { *a4 = v34 + 1; goto LABEL_45; } *a4 = v34; v25 = v63; goto LABEL_82; } LABEL_75: if((int)v60 > 0) *(_QWORD *)&v73 = v60; goto LABEL_77; } v26 = v55; v21 = v42[0]; v27 = v51; } v64 = v27; v65 = v52; v66 = v53; v67 = v54; v33 = v56; if(v62 == 1) { v26 += 2; v33 = v56 - 1; v55 = v26; --v56; } v69 = v33; v68 = v26; v71 = v58; v70 = v57; v72 = v59; if(v57) goto LABEL_75; v78[1] = 0; if(!sub_25802C93(v21, &v78[1])) goto LABEL_75; v70 = v78[1]; goto LABEL_74; } v22 = sub_25802FAC((int)v42); v23 = a4; v24 = v22 + 1; if(v22+1 > *a4) { LABEL_44: *v23 = v24; LABEL_45: *a5 = -3; goto LABEL_86; } *a4 = v22; v25 = v42; LABEL_82: sub_25803194((int)v25, String); LABEL_87: if(allocadr_Source_copy) (*(void (__cdecl **)(LPCSTR))(dword_25824098 + 12))(allocadr_Source_copy); if(allocadr_lpString_copy) (*(void (__cdecl **)(LPCSTR))(dword_25824098 + 12))(allocadr_lpString_copy); if(concatURL_addr) (*(void (__cdecl **)(wchar_t *))(dword_25824098 + 12))(concatURL_addr); return v5; }