์๊ฐ
XNUMX์ ๋ง์ ์ฐ๋ฆฌ๋
์ผ๋ง ์ UC Browser๋ ๋งค์ฐ ๊ณต๊ฒฉ์ ์ผ๋ก ๊ด๊ณ ๋ฐ ๋ฐฐํฌ๋์์ต๋๋ค. ์
์ฑ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ฅ์น์ ์ค์น๋์์ผ๋ฉฐ, ๋น๋์ค ํ์ผ๋ก ์์ฅํ์ฌ ๋ค์ํ ์ฌ์ดํธ์์ ๋ฐฐํฌ๋์์ต๋๋ค(์: ์ฌ์ฉ์๋ ํฌ๋ฅด๋
ธ ๋น๋์ค ๋ฑ์ ๋ค์ด๋ก๋ํ๋ค๊ณ ์๊ฐํ์ง๋ง, ๋์ ์ด ๋ธ๋ผ์ฐ์ ๋ก APK๋ฅผ ๋ฐ์์ต๋๋ค), ๋ธ๋ผ์ฐ์ ๊ฐ ์ค๋๋๊ณ ์ทจ์ฝํ๋ค๋ ๋ฉ์์ง๊ฐ ํฌํจ๋ ๋ฌด์์ด ๋ฐฐ๋๋ฅผ ์ฌ์ฉํ์ต๋๋ค. VK์ ๊ณต์ UC ๋ธ๋ผ์ฐ์ ๊ทธ๋ฃน์๋ ๋ค์์ด ์์ต๋๋ค.
์ด ๊ธ์ ์ฐ๋ ์์ ์ UC Browser๋ Google Play์์ 500์ต ๊ฑด ์ด์ ์ค์น๋์์ต๋๋ค. ์ด๋ ์ธ์์ ์
๋๋ค. Google Chrome์๋ง ๋ ๋ง์ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. ๋ฆฌ๋ทฐ ์ค์๋ ๊ด๊ณ ์ ๋ํ ๋ถ๋ง ์ฌํญ๊ณผ Google Play์ ์ผ๋ถ ์ ํ๋ฆฌ์ผ์ด์
์ผ๋ก์ ๋ฆฌ๋๋ ์
์ ๋ณผ ์ ์์ต๋๋ค. ์ด๊ฒ์ด ์ฐ๋ฆฌ ์ฐ๊ตฌ์ ์ด์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ UC ๋ธ๋ผ์ฐ์ ๊ฐ ๋ญ๊ฐ ๋์ ์ผ์ ํ๊ณ ์๋์ง ์์๋ณด๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฐ ๊ทธ๋ฌ๋ค๋ ๊ฒ์ด ๋ฐํ์ก์ต๋๋ค!
์ ํ๋ฆฌ์ผ์ด์
์ฝ๋์์๋ ์คํ ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ๋ค์ด๋ก๋ํ๊ณ ์คํํ๋ ๊ธฐ๋ฅ์ด ๋ฐ๊ฒฌ๋๊ณ ,
์๋์ ๊ธฐ๋ก๋ ๋ชจ๋ ๋ด์ฉ์ ์ฐ๊ตฌ ๋น์ Google Play์์ ์ฌ์ฉํ ์ ์์๋ UC ๋ธ๋ผ์ฐ์ ๋ฒ์ ๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค.
package: com.UCMobile.intl
versionName: 12.10.8.1172
versionCode: 10598
sha1 APK-ัะฐะนะปะฐ: f5edb2243413c777172f6362876041eb0c3a928c
๊ณต๊ฒฉ ๋ฒกํฐ
UC ๋ธ๋ผ์ฐ์ ๋งค๋ํ์คํธ์์ ์ค๋ช ์ด ํ์ํ ์ด๋ฆ์ ๊ฐ์ง ์๋น์ค๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. com.uc.deployment.UpgradeDeployService.
<service android_exported="false" android_name="com.uc.deployment.UpgradeDeployService" android_process=":deploy" />
์ด ์๋น์ค๊ฐ ์์๋๋ฉด ๋ธ๋ผ์ฐ์ ๋ POST ์์ฒญ์ ์ํํฉ๋๋ค.
๋ฐ๋ผ์ ์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ์์ ์ง์ PDF๋ฅผ ์ด๋ ค๊ณ ํ๋ฉด ํธ๋ํฝ์์ ๋ค์ ์์ฒญ์ด ํ์๋ ์ ์์ต๋๋ค.
๋จผ์ POST ์์ฒญ์ด ์์ต๋๋ค.
PDF ๋ฐ Office ํ์์ ๋ณผ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํฌํจ๋ ์์นด์ด๋ธ๊ฐ ๋ค์ด๋ก๋๋ฉ๋๋ค. ์ฒซ ๋ฒ์งธ ์์ฒญ์ด ์์คํ
์ ๋ํ ์ ๋ณด(์ ์ด๋ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ ๊ณตํ๊ธฐ ์ํ ์ํคํ
์ฒ)๋ฅผ ์ ์กํ๊ณ ์ด์ ๋ํ ์๋ต์ผ๋ก ๋ธ๋ผ์ฐ์ ๊ฐ ๋ค์ด๋ก๋ํด์ผ ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ์ผ๋ถ ์ ๋ณด(์ฃผ์ ๋ฐ ๊ฐ๋ฅํ ๊ฒฝ์ฐ)๋ฅผ ์์ ํ๋ค๊ณ ๊ฐ์ ํ๋ ๊ฒ์ด ๋
ผ๋ฆฌ์ ์
๋๋ค. , ๋ค๋ฅธ ๊ฒ. ๋ฌธ์ ๋ ์ด ์์ฒญ์ด ์ํธํ๋์ด ์๋ค๋ ๊ฒ์
๋๋ค.
์กฐ๊ฐ ์์ฒญ
๋ต๋ณ ์กฐ๊ฐ
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ฒด๋ ZIP์ผ๋ก ํจํค์ง๋์ด ์์ผ๋ฉฐ ์ํธํ๋์ง ์์ต๋๋ค.
ํธ๋ํฝ ๋ณตํธํ ์ฝ๋ ๊ฒ์
์๋ฒ ์๋ต์ ํด๋ ํด ๋ณด๊ฒ ์ต๋๋ค. ํด๋์ค ์ฝ๋๋ฅผ ์ดํด๋ณด์ com.uc.deployment.UpgradeDeployService: ๋ฉ์๋์์ ์์ ๋ช ๋ น ์ด๋ com.uc.deployment.bx, ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ๋ถํฐ com.uc.browser.core.dcfe:
public final void e(l arg9) {
int v4_5;
String v3_1;
byte[] v3;
byte[] v1 = null;
if(arg9 == null) {
v3 = v1;
}
else {
v3_1 = arg9.iGX.ipR;
StringBuilder v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]product:");
v4.append(arg9.iGX.ipR);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]version:");
v4.append(arg9.iGX.iEn);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]upgrade_type:");
v4.append(arg9.iGX.mMode);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]force_flag:");
v4.append(arg9.iGX.iEo);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]silent_mode:");
v4.append(arg9.iGX.iDQ);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]silent_type:");
v4.append(arg9.iGX.iEr);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]silent_state:");
v4.append(arg9.iGX.iEp);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]silent_file:");
v4.append(arg9.iGX.iEq);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apk_md5:");
v4.append(arg9.iGX.iEl);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]download_type:");
v4.append(arg9.mDownloadType);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]download_group:");
v4.append(arg9.mDownloadGroup);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]download_path:");
v4.append(arg9.iGH);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apollo_child_version:");
v4.append(arg9.iGX.iEx);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apollo_series:");
v4.append(arg9.iGX.iEw);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apollo_cpu_arch:");
v4.append(arg9.iGX.iEt);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apollo_cpu_vfp3:");
v4.append(arg9.iGX.iEv);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apollo_cpu_vfp:");
v4.append(arg9.iGX.iEu);
ArrayList v3_2 = arg9.iGX.iEz;
if(v3_2 != null && v3_2.size() != 0) {
Iterator v3_3 = v3_2.iterator();
while(v3_3.hasNext()) {
Object v4_1 = v3_3.next();
StringBuilder v5 = new StringBuilder("[");
v5.append(((au)v4_1).getName());
v5.append("]component_name:");
v5.append(((au)v4_1).getName());
v5 = new StringBuilder("[");
v5.append(((au)v4_1).getName());
v5.append("]component_ver_name:");
v5.append(((au)v4_1).aDA());
v5 = new StringBuilder("[");
v5.append(((au)v4_1).getName());
v5.append("]component_ver_code:");
v5.append(((au)v4_1).gBl);
v5 = new StringBuilder("[");
v5.append(((au)v4_1).getName());
v5.append("]component_req_type:");
v5.append(((au)v4_1).gBq);
}
}
j v3_4 = new j();
m.b(v3_4);
h v4_2 = new h();
m.b(v4_2);
ay v5_1 = new ay();
v3_4.hS("");
v3_4.setImsi("");
v3_4.hV("");
v5_1.bPQ = v3_4;
v5_1.bPP = v4_2;
v5_1.yr(arg9.iGX.ipR);
v5_1.gBF = arg9.iGX.mMode;
v5_1.gBI = arg9.iGX.iEz;
v3_2 = v5_1.gAr;
c.aBh();
v3_2.add(g.fs("os_ver", c.getRomInfo()));
v3_2.add(g.fs("processor_arch", com.uc.b.a.a.c.getCpuArch()));
v3_2.add(g.fs("cpu_arch", com.uc.b.a.a.c.Pb()));
String v4_3 = com.uc.b.a.a.c.Pd();
v3_2.add(g.fs("cpu_vfp", v4_3));
v3_2.add(g.fs("net_type", String.valueOf(com.uc.base.system.a.Jo())));
v3_2.add(g.fs("fromhost", arg9.iGX.iEm));
v3_2.add(g.fs("plugin_ver", arg9.iGX.iEn));
v3_2.add(g.fs("target_lang", arg9.iGX.iEs));
v3_2.add(g.fs("vitamio_cpu_arch", arg9.iGX.iEt));
v3_2.add(g.fs("vitamio_vfp", arg9.iGX.iEu));
v3_2.add(g.fs("vitamio_vfp3", arg9.iGX.iEv));
v3_2.add(g.fs("plugin_child_ver", arg9.iGX.iEx));
v3_2.add(g.fs("ver_series", arg9.iGX.iEw));
v3_2.add(g.fs("child_ver", r.aVw()));
v3_2.add(g.fs("cur_ver_md5", arg9.iGX.iEl));
v3_2.add(g.fs("cur_ver_signature", SystemHelper.getUCMSignature()));
v3_2.add(g.fs("upgrade_log", i.bjt()));
v3_2.add(g.fs("silent_install", String.valueOf(arg9.iGX.iDQ)));
v3_2.add(g.fs("silent_state", String.valueOf(arg9.iGX.iEp)));
v3_2.add(g.fs("silent_file", arg9.iGX.iEq));
v3_2.add(g.fs("silent_type", String.valueOf(arg9.iGX.iEr)));
v3_2.add(g.fs("cpu_archit", com.uc.b.a.a.c.Pc()));
v3_2.add(g.fs("cpu_set", SystemHelper.getCpuInstruction()));
boolean v4_4 = v4_3 == null || !v4_3.contains("neon") ? false : true;
v3_2.add(g.fs("neon", String.valueOf(v4_4)));
v3_2.add(g.fs("cpu_cores", String.valueOf(com.uc.b.a.a.c.Jl())));
v3_2.add(g.fs("ram_1", String.valueOf(com.uc.b.a.a.h.Po())));
v3_2.add(g.fs("totalram", String.valueOf(com.uc.b.a.a.h.OL())));
c.aBh();
v3_2.add(g.fs("rom_1", c.getRomInfo()));
v4_5 = e.getScreenWidth();
int v6 = e.getScreenHeight();
StringBuilder v7 = new StringBuilder();
v7.append(v4_5);
v7.append("*");
v7.append(v6);
v3_2.add(g.fs("ss", v7.toString()));
v3_2.add(g.fs("api_level", String.valueOf(Build$VERSION.SDK_INT)));
v3_2.add(g.fs("uc_apk_list", SystemHelper.getUCMobileApks()));
Iterator v4_6 = arg9.iGX.iEA.entrySet().iterator();
while(v4_6.hasNext()) {
Object v6_1 = v4_6.next();
v3_2.add(g.fs(((Map$Entry)v6_1).getKey(), ((Map$Entry)v6_1).getValue()));
}
v3 = v5_1.toByteArray();
}
if(v3 == null) {
this.iGY.iGI.a(arg9, "up_encode", "yes", "fail");
return;
}
v4_5 = this.iGY.iGw ? 0x1F : 0;
if(v3 == null) {
}
else {
v3 = g.i(v4_5, v3);
if(v3 == null) {
}
else {
v1 = new byte[v3.length + 16];
byte[] v6_2 = new byte[16];
Arrays.fill(v6_2, 0);
v6_2[0] = 0x5F;
v6_2[1] = 0;
v6_2[2] = ((byte)v4_5);
v6_2[3] = -50;
System.arraycopy(v6_2, 0, v1, 0, 16);
System.arraycopy(v3, 0, v1, 16, v3.length);
}
}
if(v1 == null) {
this.iGY.iGI.a(arg9, "up_encrypt", "yes", "fail");
return;
}
if(TextUtils.isEmpty(this.iGY.mUpgradeUrl)) {
this.iGY.iGI.a(arg9, "up_url", "yes", "fail");
return;
}
StringBuilder v0 = new StringBuilder("[");
v0.append(arg9.iGX.ipR);
v0.append("]url:");
v0.append(this.iGY.mUpgradeUrl);
com.uc.browser.core.d.c.i v0_1 = this.iGY.iGI;
v3_1 = this.iGY.mUpgradeUrl;
com.uc.base.net.e v0_2 = new com.uc.base.net.e(new com.uc.browser.core.d.c.i$a(v0_1, arg9));
v3_1 = v3_1.contains("?") ? v3_1 + "&dataver=pb" : v3_1 + "?dataver=pb";
n v3_5 = v0_2.uc(v3_1);
m.b(v3_5, false);
v3_5.setMethod("POST");
v3_5.setBodyProvider(v1);
v0_2.b(v3_5);
this.iGY.iGI.a(arg9, "up_null", "yes", "success");
this.iGY.iGI.b(arg9);
}
์ฌ๊ธฐ์๋ POST ์์ฒญ์ด ํ์ฑ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ 16๋ฐ์ดํธ ๋ฐฐ์ด ์์ฑ๊ณผ ๊ทธ ์ฑ์ฐ๊ธฐ(0x5F, 0, 0x1F, -50 (=0xCE))์ ์ฃผ์๋ฅผ ๊ธฐ์ธ์์ต๋๋ค. ์ ์์ฒญ์์ ๋ณธ ๋ด์ฉ๊ณผ ์ผ์นํฉ๋๋ค.
๊ฐ์ ํด๋์ค์์ ๋ ๋ค๋ฅธ ํฅ๋ฏธ๋ก์ด ๋ฉ์๋๊ฐ ์๋ ์ค์ฒฉ ํด๋์ค๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
public final void a(l arg10, byte[] arg11) {
f v0 = this.iGQ;
StringBuilder v1 = new StringBuilder("[");
v1.append(arg10.iGX.ipR);
v1.append("]:UpgradeSuccess");
byte[] v1_1 = null;
if(arg11 == null) {
}
else if(arg11.length < 16) {
}
else {
if(arg11[0] != 0x60 && arg11[3] != 0xFFFFFFD0) {
goto label_57;
}
int v3 = 1;
int v5 = arg11[1] == 1 ? 1 : 0;
if(arg11[2] != 1 && arg11[2] != 11) {
if(arg11[2] == 0x1F) {
}
else {
v3 = 0;
}
}
byte[] v7 = new byte[arg11.length - 16];
System.arraycopy(arg11, 16, v7, 0, v7.length);
if(v3 != 0) {
v7 = g.j(arg11[2], v7);
}
if(v7 == null) {
goto label_57;
}
if(v5 != 0) {
v1_1 = g.P(v7);
goto label_57;
}
v1_1 = v7;
}
label_57:
if(v1_1 == null) {
v0.iGY.iGI.a(arg10, "up_decrypt", "yes", "fail");
return;
}
q v11 = g.b(arg10, v1_1);
if(v11 == null) {
v0.iGY.iGI.a(arg10, "up_decode", "yes", "fail");
return;
}
if(v0.iGY.iGt) {
v0.d(arg10);
}
if(v0.iGY.iGo != null) {
v0.iGY.iGo.a(0, ((o)v11));
}
if(v0.iGY.iGs) {
v0.iGY.a(((o)v11));
v0.iGY.iGI.a(v11, "up_silent", "yes", "success");
v0.iGY.iGI.a(v11);
return;
}
v0.iGY.iGI.a(v11, "up_silent", "no", "success");
}
}
์ด ๋ฉ์๋๋ ๋ฐ์ดํธ ๋ฐฐ์ด์ ์
๋ ฅ์ผ๋ก ์ฌ์ฉํ๊ณ 0๋ฐ์ดํธ๊ฐ 60x0์ธ์ง, ์ธ ๋ฒ์งธ ๋ฐ์ดํธ๊ฐ 0xD1์ธ์ง, ๋ ๋ฒ์งธ ๋ฐ์ดํธ๊ฐ 11, 0 ๋๋ 1x0F์ธ์ง ํ์ธํฉ๋๋ค. ์๋ฒ์ ์๋ต์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. 60๋ฐ์ดํธ๋ 0x1, ๋ ๋ฒ์งธ ๋ฐ์ดํธ๋ 0x60F, ์ธ ๋ฒ์งธ ๋ฐ์ดํธ๋ XNUMXxXNUMX์
๋๋ค. ์ฐ๋ฆฌ์๊ฒ ๊ผญ ํ์ํ ๊ฒ ๊ฐ๊ตฐ์. ํ(์: "up_decrypt")์ผ๋ก ํ๋จํ๋ฉด ์๋ฒ์ ์๋ต์ ํด๋
ํ๋ ๋ฉ์๋๊ฐ ์ฌ๊ธฐ์์ ํธ์ถ๋์ด์ผ ํฉ๋๋ค.
๋ฐฉ๋ฒ์ผ๋ก ๋์ด ๊ฐ์๋ค gj. ์ฒซ ๋ฒ์งธ ์ธ์๋ ์คํ์
2(์: ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ 0x1F)์ ์๋ ๋ฐ์ดํธ์ด๊ณ ๋ ๋ฒ์งธ ์ธ์๋ ์คํ์
์ด ์๋ ์๋ฒ ์๋ต์
๋๋ค.
์ฒ์ 16๋ฐ์ดํธ.
public static byte[] j(int arg1, byte[] arg2) {
if(arg1 == 1) {
arg2 = c.c(arg2, c.adu);
}
else if(arg1 == 11) {
arg2 = m.aF(arg2);
}
else if(arg1 != 0x1F) {
}
else {
arg2 = EncryptHelper.decrypt(arg2);
}
return arg2;
}
๋ถ๋ช
ํ ์ฌ๊ธฐ์๋ ์ํธ ํด๋
์๊ณ ๋ฆฌ์ฆ์ ์ ํํ๊ณ
0x1F์ ๋์ผํ ๊ฒฝ์ฐ๋ ์ธ ๊ฐ์ง ๊ฐ๋ฅํ ์ต์
์ค ํ๋๋ฅผ ๋ํ๋
๋๋ค.
์ฐ๋ฆฌ๋ ๊ณ์ํด์ ์ฝ๋๋ฅผ ๋ถ์ํฉ๋๋ค. ๋ช ๋ฒ์ ์ ํ ํ์ ์ฐ๋ฆฌ๋ ์ค๋ช ์ด ํ์ ์๋ ์ด๋ฆ์ ๊ฐ์ง ๋ฉ์๋์ ๋๋ฌํ๊ฒ ๋์์ต๋๋ค. decryptBytesByKey.
์ฌ๊ธฐ์์๋ ์๋ต์์ ๋ ๋ฐ์ดํธ๊ฐ ๋ ๋ถ๋ฆฌ๋๊ณ ๊ทธ๋ก๋ถํฐ ๋ฌธ์์ด์ด ์ป์ด์ง๋๋ค. ์ด๋ฐ ๋ฐฉ์์ผ๋ก ๋ฉ์์ง๋ฅผ ํด๋ ํ๊ธฐ ์ํ ํค๊ฐ ์ ํ๋๋ค๋ ๊ฒ์ ๋ถ๋ช ํฉ๋๋ค.
private static byte[] decryptBytesByKey(byte[] bytes) {
byte[] v0 = null;
if(bytes != null) {
try {
if(bytes.length < EncryptHelper.PREFIX_BYTES_SIZE) {
}
else if(bytes.length == EncryptHelper.PREFIX_BYTES_SIZE) {
return v0;
}
else {
byte[] prefix = new byte[EncryptHelper.PREFIX_BYTES_SIZE]; // 2 ะฑะฐะนัะฐ
System.arraycopy(bytes, 0, prefix, 0, prefix.length);
String keyId = c.ayR().d(ByteBuffer.wrap(prefix).getShort()); // ะัะฑะพั ะบะปััะฐ
if(keyId == null) {
return v0;
}
else {
a v2 = EncryptHelper.ayL();
if(v2 == null) {
return v0;
}
else {
byte[] enrypted = new byte[bytes.length - EncryptHelper.PREFIX_BYTES_SIZE];
System.arraycopy(bytes, EncryptHelper.PREFIX_BYTES_SIZE, enrypted, 0, enrypted.length);
return v2.l(keyId, enrypted);
}
}
}
}
catch(SecException v7_1) {
EncryptHelper.handleDecryptException(((Throwable)v7_1), v7_1.getErrorCode());
return v0;
}
catch(Throwable v7) {
EncryptHelper.handleDecryptException(v7, 2);
return v0;
}
}
return v0;
}
์์ ๋ด๋ค๋ณด๋ฉด ์ด ๋จ๊ณ์์๋ ์์ง ํค๋ฅผ ์ป์ง ๋ชปํ๊ณ ํค์ "์๋ณ์"๋ง ์ป์ ์ ์์ต๋๋ค. ์ด์ ๋ฅผ ์ป๋ ๋ฐฉ๋ฒ์ ์กฐ๊ธ ๋ ๋ณต์กํฉ๋๋ค.
๋ค์ ๋ฐฉ๋ฒ์์๋ ๊ธฐ์กด ๋งค๊ฐ๋ณ์์ 16๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๋ ์ถ๊ฐํ์ฌ ๊ทธ ์ค XNUMX๊ฐ(๋งค์ง ๋๋ฒ XNUMX, ํค ์๋ณ์, ์ํธํ๋ ๋ฐ์ดํฐ, ์ดํดํ ์ ์๋ ๋ฌธ์์ด(์ฌ๊ธฐ์๋ ๋น์ด ์์))๋ฅผ ๋ง๋ญ๋๋ค.
public final byte[] l(String keyId, byte[] encrypted) throws SecException {
return this.ayJ().staticBinarySafeDecryptNoB64(16, keyId, encrypted, "");
}
์ผ๋ จ์ ์ ํ ํ์ ์ฐ๋ฆฌ๋ ๋ฐฉ๋ฒ์ ๋๋ฌํฉ๋๋ค. staticBinarySafeDecryptNoB64 ์ธํฐํ์ด์ค com.alibaba.wireless.security.open.staticdataencrypt.IStaticDataEncryptComponent. ์ด ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๊ธฐ๋ณธ ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋์๋ ํด๋์ค๊ฐ ์์ต๋๋ค. ํ์ผ์ ๊ทธ๋ฌํ ํด๋์ค๊ฐ ์์ต๋๋ค lib/armeabi-v7a/libsgmain.so, ์ค์ ๋ก๋ .so๊ฐ ์๋๋ผ .jar์ ๋๋ค. ์ฐ๋ฆฌ๊ฐ ๊ด์ฌ ์๋ ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํ๋ฉ๋๋ค.
package com.alibaba.wireless.security.a.i;
// ...
public class a implements IStaticDataEncryptComponent {
private ISecurityGuardPlugin a;
// ...
private byte[] a(int mode, int magicInt, int xzInt, String keyId, byte[] encrypted, String magicString) {
return this.a.getRouter().doCommand(10601, new Object[]{Integer.valueOf(mode), Integer.valueOf(magicInt), Integer.valueOf(xzInt), keyId, encrypted, magicString});
}
// ...
private byte[] b(int magicInt, String keyId, byte[] encrypted, String magicString) {
return this.a(2, magicInt, 0, keyId, encrypted, magicString);
}
// ...
public byte[] staticBinarySafeDecryptNoB64(int magicInt, String keyId, byte[] encrypted, String magicString) throws SecException {
if(keyId != null && keyId.length() > 0 && magicInt >= 0 && magicInt < 19 && encrypted != null && encrypted.length > 0) {
return this.b(magicInt, keyId, encrypted, magicString);
}
throw new SecException("", 301);
}
//...
}
์ฌ๊ธฐ์ ๋งค๊ฐ๋ณ์ ๋ชฉ๋ก์ ๋ ๊ฐ์ ์ ์(2์ 0)๋ก ๋ณด์๋ฉ๋๋ค.
๋ชจ๋ ๊ฒ, 2๋ ๋ฉ์๋์์์ ๊ฐ์ด ์ํธ ํด๋
์ ์๋ฏธํฉ๋๋ค. doFinal ์์คํ
ํด๋์ค javax.crypto.Cipher. ๊ทธ๋ฆฌ๊ณ ์ด ๋ชจ๋ ๊ฒ์ ๋ฒํธ 10601์ ๊ฐ์ง ํน์ ๋ผ์ฐํฐ๋ก ์ ์ก๋ฉ๋๋ค. ์ด๊ฒ์ ๋ถ๋ช
ํ ๋ช
๋ น ๋ฒํธ์
๋๋ค.
๋ค์ ์ ํ ์ฒด์ธ ํ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ํด๋์ค๋ฅผ ์ฐพ์ต๋๋ค. IRouterComponent ๋ฐ ๋ฐฉ๋ฒ do๋ช ๋ น:
package com.alibaba.wireless.security.mainplugin;
import com.alibaba.wireless.security.framework.IRouterComponent;
import com.taobao.wireless.security.adapter.JNICLibrary;
public class a implements IRouterComponent {
public a() {
super();
}
public Object doCommand(int arg2, Object[] arg3) {
return JNICLibrary.doCommandNative(arg2, arg3);
}
}
๊ทธ๋ฆฌ๊ณ ์์ ๋ ํ๊ณ JNIC๋์๊ด, ๋ค์ดํฐ๋ธ ๋ฉ์๋๊ฐ ์ ์ธ๋จ doCommandNative:
package com.taobao.wireless.security.adapter;
public class JNICLibrary {
public static native Object doCommandNative(int arg0, Object[] arg1);
}
์ด๋ ๋ค์ดํฐ๋ธ ์ฝ๋์์ ๋ฉ์๋๋ฅผ ์ฐพ์์ผ ํจ์ ์๋ฏธํฉ๋๋ค. doCommandNative. ๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ด ์ฌ๋ฏธ๊ฐ ์์๋๋ ๊ณณ์ ๋๋ค.
๊ธฐ๊ณ์ด ์ฝ๋ ๋๋ ํ
ํ์ผ์์ libsgmain.so (์ค์ ๋ก๋ .jar์ด๊ณ ๋ฐ๋ก ์์์ ์ผ๋ถ ์ํธํ ๊ด๋ จ ์ธํฐํ์ด์ค์ ๊ตฌํ์ ์ฐพ์์ต๋๋ค.) ํ๋์ ๊ธฐ๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ต๋๋ค. libsgmainso-6.4.36.so. IDA์์ ์ด๋ฉด ์ค๋ฅ๊ฐ ์๋ ๋ํ ์์๊ฐ ๋ง์ด ๋ํ๋ฉ๋๋ค. ๋ฌธ์ ๋ ์น์ ํค๋ ํ ์ด๋ธ์ด ์ ํจํ์ง ์๋ค๋ ๊ฒ์ ๋๋ค. ์ด๋ ๋ถ์์ ๋ณต์กํ๊ฒ ๋ง๋ค๊ธฐ ์ํด ์๋์ ์ผ๋ก ์ํ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ ์ด๋ ํ์ํ์ง ์์ต๋๋ค. ELF ํ์ผ์ ์ฌ๋ฐ๋ฅด๊ฒ ๋ก๋ํ๊ณ ๋ถ์ํ๋ ค๋ฉด ํ๋ก๊ทธ๋จ ํค๋ ํ
์ด๋ธ์ด๋ฉด ์ถฉ๋ถํฉ๋๋ค. ๋ฐ๋ผ์ ์น์
ํ
์ด๋ธ์ ์ญ์ ํ๊ณ ํค๋์ ํด๋น ํ๋๋ฅผ XNUMX์ผ๋ก ๋ง๋ญ๋๋ค.
IDA์์ ํ์ผ์ ๋ค์ ์ฝ๋๋ค.
Java ์ฝ๋์์ ๋ค์ดํฐ๋ธ๋ก ์ ์ธ๋ ๋ฉ์๋์ ๊ตฌํ์ด ๋ค์ดํฐ๋ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ํํ ์ด๋์ ์๋์ง Java ๊ฐ์ ๋จธ์ ์ ์๋ ค์ฃผ๋ ๋ฐฉ๋ฒ์๋ ๋ ๊ฐ์ง๊ฐ ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ๋ ์ข ์ด๋ฆ์ ์ง์ ํ๋ ๊ฒ์ ๋๋ค. Java_package_name_ClassName_MethodName.
๋ ๋ฒ์งธ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ ๋ ๋ฑ๋กํ๋ ๊ฒ์
๋๋ค(ํจ์์์ JNI_OnLoad)
ํจ์ ํธ์ถ์ ์ฌ์ฉํ์ฌ ๋ฑ๋ก์์ฃผ๋ฏผ.
์ฐ๋ฆฌ์ ๊ฒฝ์ฐ ์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ฉด ์ด๋ฆ์ ๋ค์๊ณผ ๊ฐ์์ผ ํฉ๋๋ค. Java_com_taobao_wireless_security_adapter_JNICLibrary_doCommandNative.
๋ด๋ณด๋ธ ํจ์ ์ค์๋ ํด๋น ํจ์๊ฐ ์์ผ๋ฏ๋ก ํธ์ถ์ ์ฐพ์์ผ ํจ์ ์๋ฏธํฉ๋๋ค. ๋ฑ๋ก์์ฃผ๋ฏผ.
ํจ์๋ก ๊ฐ๋ณด์ JNI_OnLoad ๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๋ ์ด ์ฌ์ง์ ๋ด
๋๋ค:
์ฌ๊ธฐ์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋ ๊ฑธ๊น์? ์ธ๋ป ๋ณด๊ธฐ์ ํจ์์ ์์๊ณผ ๋์ ARM ์ํคํ
์ฒ์์ ์ผ๋ฐ์ ์
๋๋ค. ์คํ์ ์ฒซ ๋ฒ์งธ ๋ช
๋ น์ด๋ ํจ์๊ฐ ์์
์ ์ฌ์ฉํ ๋ ์ง์คํฐ(์ด ๊ฒฝ์ฐ R0, R1 ๋ฐ R2)์ ๋ด์ฉ๊ณผ ํจ์์ ๋ฐํ ์ฃผ์๊ฐ ํฌํจ๋ LR ๋ ์ง์คํฐ์ ๋ด์ฉ์ ์ ์ฅํฉ๋๋ค. . ๋ง์ง๋ง ๋ช
๋ น์ด๋ ์ ์ฅ๋ ๋ ์ง์คํฐ๋ฅผ ๋ณต์ํ๊ณ ๋ฐํ ์ฃผ์๋ ์ฆ์ PC ๋ ์ง์คํฐ์ ๋ฐฐ์น๋๋ฏ๋ก ํจ์์์ ๋ฐํ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ์์ธํ ์ดํด๋ณด๋ฉด ๋์์ ๋ ๋ฒ์งธ ๋ช
๋ น์ด๊ฐ ์คํ์ ์ ์ฅ๋ ๋ฐํ ์ฃผ์๋ฅผ ๋ณ๊ฒฝํ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ๋์ค์ ์ด๋ป๊ฒ ๋ ์ง ๊ณ์ฐํด ๋ด
์๋ค
์ฝ๋ ์คํ. ํน์ ์ฃผ์ 1xB0์ด R130์ ๋ก๋๋๊ณ ๊ฑฐ๊ธฐ์์ 5๋ฅผ ๋บ ๋ค์ R0์ผ๋ก ์ ์ก๋๊ณ 0x10์ด ์ถ๊ฐ๋ฉ๋๋ค. 0xB13B๋ก ๋ํ๋ฉ๋๋ค. ๋ฐ๋ผ์ IDA๋ ๋ง์ง๋ง ๋ช
๋ น์ด๊ฐ ์ ์์ ์ธ ํจ์ ๋ฆฌํด์ด๋ผ๊ณ ์๊ฐํ์ง๋ง ์ค์ ๋ก๋ ๊ณ์ฐ๋ ์ฃผ์ 0xB13B๋ก ๊ฐ๋ ๊ฒ์
๋๋ค.
์ฌ๊ธฐ์ ARM ํ๋ก์ธ์์๋ ARM๊ณผ Thumb์ด๋ผ๋ ๋ ๊ฐ์ง ๋ชจ๋์ ๋ ๊ฐ์ง ๋ช ๋ น์ด ์ธํธ๊ฐ ์๋ค๋ ์ ์ ๊ธฐ์ตํ ๊ฐ์น๊ฐ ์์ต๋๋ค. ์ฃผ์์ ์ตํ์ ๋นํธ๋ ์ด๋ค ๋ช ๋ น์ด ์ธํธ๊ฐ ์ฌ์ฉ๋๊ณ ์๋์ง ํ๋ก์ธ์์ ์๋ ค์ค๋๋ค. ์ฆ, ์ค์ ์ฃผ์๋ 0xB13A์ด๊ณ ์ตํ์ ๋นํธ ์ค ํ๋๋ Thumb ๋ชจ๋๋ฅผ ๋ํ๋ ๋๋ค.
์ ์ฌํ "์ด๋ํฐ"๊ฐ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฐ ๊ธฐ๋ฅ ์์ ๋ถ๋ถ์ ์ถ๊ฐ๋์์ผ๋ฉฐ
์ฐ๋ ๊ธฐ ์ฝ๋. ์ฐ๋ฆฌ๋ ๋ ์ด์ ์์ธํ ์ค๋ช
ํ์ง ์์ ๊ฒ์
๋๋ค. ์ฐ๋ฆฌ๋ ๋จ์ง ๊ธฐ์ตํฉ๋๋ค
๊ฑฐ์ ๋ชจ๋ ๊ธฐ๋ฅ์ ์ค์ ์์์ ์กฐ๊ธ ๋ ๋ฉ๋ฆฌ ๋จ์ด์ ธ ์๋ค๋ ๊ฒ์
๋๋ค.
์ฝ๋๊ฐ ๋ช ์์ ์ผ๋ก 0xB13A๋ก ์ ํํ์ง ์๊ธฐ ๋๋ฌธ์ IDA ์์ฒด์์๋ ํด๋น ์ฝ๋๊ฐ ์ด ์์น์ ์๋ค๋ ๊ฒ์ ์ธ์ํ์ง ๋ชปํ์ต๋๋ค. ๊ฐ์ ์ด์ ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ ๋๋ถ๋ถ์ ์ฝ๋๋ฅผ ์ฝ๋๋ก ์ธ์ํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ๋ถ์์ด ๋ค์ ์ด๋ ต๋ค. ์ฐ๋ฆฌ๋ ์ด๊ฒ์ด ์ฝ๋๋ผ๊ณ IDA์ ์๋ฆฝ๋๋ค. ๊ทธ๋ฌ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ผ์ด ์ผ์ด๋ฉ๋๋ค.
ํ
์ด๋ธ์ ๋ถ๋ช
ํ 0xB144์์ ์์๋ฉ๋๋ค. sub_494C์๋ ๋ฌด์์ด ์๋์?
LR ๋ ์ง์คํฐ์์ ์ด ํจ์๋ฅผ ํธ์ถํ๋ฉด ์์ ์ธ๊ธํ ํ
์ด๋ธ(0xB144)์ ์ฃผ์๋ฅผ ์ป์ต๋๋ค. R0 - ์ด ํ
์ด๋ธ์ ์ธ๋ฑ์ค์
๋๋ค. ์ฆ, ํ
์ด๋ธ์์ ๊ฐ์ ๊ฐ์ ธ์ LR์ ์ถ๊ฐํ๋ฉด ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๊ฐ ์ฃผ์. ๊ณ์ฐํด ๋ด
์๋ค: 0xB144 + [0xB144 + 8* 4] = 0xB144 + 0x120 = 0xB264. ์์ ๋ ์ฃผ์๋ก ์ด๋ํ์ฌ ๋ฌธ์ ๊ทธ๋๋ก ๋ช ๊ฐ์ง ์ ์ฉํ ์ง์นจ์ ํ์ธํ ๋ค์ ๋ค์ 0xB140์ผ๋ก ์ด๋ํฉ๋๋ค.
์ด์ ํ
์ด๋ธ์ ์ธ๋ฑ์ค 0x20์ ์ฌ์ฉํ์ฌ ์คํ์
์์ ์ ํ์ด ๋ฐ์ํฉ๋๋ค.
ํ ์ด๋ธ์ ํฌ๊ธฐ๋ก ํ๋จํ๋ฉด ์ฝ๋์ ์ด๋ฌํ ์ ํ์ด ๋ง์ด ์์ ๊ฒ์ ๋๋ค. ์๋์ผ๋ก ์ฃผ์๋ฅผ ๊ณ์ฐํ์ง ์๊ณ ๋ ์ด ๋ฌธ์ ๋ฅผ ๋ณด๋ค ์๋์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋์ง ์ฌ๋ถ์ ๋ํ ์๋ฌธ์ด ์ ๊ธฐ๋ฉ๋๋ค. IDA์ ์คํฌ๋ฆฝํธ์ ์ฝ๋ ํจ์น ๊ธฐ๋ฅ์ด ๋์์ด ๋ฉ๋๋ค.
def put_unconditional_branch(source, destination):
offset = (destination - source - 4) >> 1
if offset > 2097151 or offset < -2097152:
raise RuntimeError("Invalid offset")
if offset > 1023 or offset < -1024:
instruction1 = 0xf000 | ((offset >> 11) & 0x7ff)
instruction2 = 0xb800 | (offset & 0x7ff)
patch_word(source, instruction1)
patch_word(source + 2, instruction2)
else:
instruction = 0xe000 | (offset & 0x7ff)
patch_word(source, instruction)
ea = here()
if get_wide_word(ea) == 0xb503: #PUSH {R0,R1,LR}
ea1 = ea + 2
if get_wide_word(ea1) == 0xbf00: #NOP
ea1 += 2
if get_operand_type(ea1, 0) == 1 and get_operand_value(ea1, 0) == 0 and get_operand_type(ea1, 1) == 2:
index = get_wide_dword(get_operand_value(ea1, 1))
print "index =", hex(index)
ea1 += 2
if get_operand_type(ea1, 0) == 7:
table = get_operand_value(ea1, 0) + 4
elif get_operand_type(ea1, 1) == 2:
table = get_operand_value(ea1, 1) + 4
else:
print "Wrong operand type on", hex(ea1), "-", get_operand_type(ea1, 0), get_operand_type(ea1, 1)
table = None
if table is None:
print "Unable to find table"
else:
print "table =", hex(table)
offset = get_wide_dword(table + (index << 2))
put_unconditional_branch(ea, table + offset)
else:
print "Unknown code", get_operand_type(ea1, 0), get_operand_value(ea1, 0), get_operand_type(ea1, 1) == 2
else:
print "Unable to detect first instruction"
0xB26A ๋ผ์ธ์ ์ปค์๋ฅผ ๋๊ณ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ์ฌ 0xB4B0์ผ๋ก์ ์ ํ์ ํ์ธํฉ๋๋ค.
IDA๋ ์ด๋ฒ์๋ ์ด ์์ญ์ ์ฝ๋๋ก ์ธ์ํ์ง ๋ชปํ์ต๋๋ค. ์ฐ๋ฆฌ๋ ๊ทธ๋
๋ฅผ ๋๊ณ ๊ทธ๊ณณ์์ ๋ ๋ค๋ฅธ ๋์์ธ์ ๋ด
๋๋ค.
BLX ์ดํ์ ์ง์นจ์ ๊ทธ๋ค์ง ์๋ฏธ๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ผ์ข
์ ์นํ๊ณผ ๋น์ทํฉ๋๋ค. sub_4964๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ค์ ๋ก ์ฌ๊ธฐ์๋ LR์ ์๋ ์ฃผ์์์ dword๋ฅผ ๊ฐ์ ธ์ ์ด ์ฃผ์์ ์ถ๊ฐํ ๋ค์ ๊ฒฐ๊ณผ ์ฃผ์์ ๊ฐ์ ๊ฐ์ ธ์ ์คํ์ ๋ฃ์ต๋๋ค. ๋ํ ํจ์์์ ๋ฐํ๋ ํ ๋์ผํ ์คํ์
์ ๊ฑด๋๋ฐ๋๋ก LR์ 4๊ฐ ์ถ๊ฐ๋ฉ๋๋ค. ๊ทธ ํ POP {R1} ๋ช
๋ น์ ์คํ์์ ๊ฒฐ๊ณผ ๊ฐ์ ๊ฐ์ ธ์ต๋๋ค. ์ฃผ์ 0xB4BA + 0xEA = 0xB5A4์ ์์นํ ๊ฒ์ ๋ณด๋ฉด ์ฃผ์ ํ
์ด๋ธ๊ณผ ๋น์ทํ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค:
์ด ๋์์ธ์ ํจ์นํ๋ ค๋ฉด ์ฝ๋์์ ๋ ๊ฐ์ ๋งค๊ฐ๋ณ์, ์ฆ ์คํ์
๊ณผ ๊ฒฐ๊ณผ๋ฅผ ๋ฃ์ ๋ ์ง์คํฐ ๋ฒํธ๋ฅผ ๊ฐ์ ธ์์ผ ํฉ๋๋ค. ๊ฐ๋ฅํ ๊ฐ ๋ฑ๋ก์ ๋ํด ๋ฏธ๋ฆฌ ์ฝ๋๋ฅผ ์ค๋นํด์ผ ํฉ๋๋ค.
patches = {}
patches[0] = (0x00, 0xbf, 0x01, 0x48, 0x00, 0x68, 0x02, 0xe0)
patches[1] = (0x00, 0xbf, 0x01, 0x49, 0x09, 0x68, 0x02, 0xe0)
patches[2] = (0x00, 0xbf, 0x01, 0x4a, 0x12, 0x68, 0x02, 0xe0)
patches[3] = (0x00, 0xbf, 0x01, 0x4b, 0x1b, 0x68, 0x02, 0xe0)
patches[4] = (0x00, 0xbf, 0x01, 0x4c, 0x24, 0x68, 0x02, 0xe0)
patches[5] = (0x00, 0xbf, 0x01, 0x4d, 0x2d, 0x68, 0x02, 0xe0)
patches[8] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0x80, 0xd8, 0xf8, 0x00, 0x80, 0x01, 0xe0)
patches[9] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0x90, 0xd9, 0xf8, 0x00, 0x90, 0x01, 0xe0)
patches[10] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0xa0, 0xda, 0xf8, 0x00, 0xa0, 0x01, 0xe0)
patches[11] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0xb0, 0xdb, 0xf8, 0x00, 0xb0, 0x01, 0xe0)
ea = here()
if (get_wide_word(ea) == 0xb082 #SUB SP, SP, #8
and get_wide_word(ea + 2) == 0xb503): #PUSH {R0,R1,LR}
if get_operand_type(ea + 4, 0) == 7:
pop = get_bytes(ea + 12, 4, 0)
if pop[1] == 'xbc':
register = -1
r = get_wide_byte(ea + 12)
for i in range(8):
if r == (1 << i):
register = i
break
if register == -1:
print "Unable to detect register"
else:
address = get_wide_dword(ea + 8) + ea + 8
for b in patches[register]:
patch_byte(ea, b)
ea += 1
if ea % 4 != 0:
ea += 2
patch_dword(ea, address)
elif pop[:3] == 'x5dxf8x04':
register = ord(pop[3]) >> 4
if register in patches:
address = get_wide_dword(ea + 8) + ea + 8
for b in patches[register]:
patch_byte(ea, b)
ea += 1
patch_dword(ea, address)
else:
print "POP instruction not found"
else:
print "Wrong operand type on +4:", get_operand_type(ea + 4, 0)
else:
print "Unable to detect first instructions"
๊ต์ฒดํ๋ ค๋ ๊ตฌ์กฐ(0xB4B2)์ ์์ ๋ถ๋ถ์ ์ปค์๋ฅผ ๋๊ณ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํฉ๋๋ค.
์ด๋ฏธ ์ธ๊ธ๋ ๊ตฌ์กฐ ์ธ์๋ ์ฝ๋์๋ ๋ค์์ด ํฌํจ๋์ด ์์ต๋๋ค.
์ด์ ์ฌ๋ก์ ๋ง์ฐฌ๊ฐ์ง๋ก BLX ๋ช
๋ น์ด ๋ค์ ์คํ์
์ด ์์ต๋๋ค.
LR์ ์ฃผ์์ ๋ํ ์คํ์
์ ๊ฐ์ ธ์ LR์ ์ถ๊ฐํ๊ณ ๊ฑฐ๊ธฐ๋ก ์ด๋ํฉ๋๋ค. 0x72044 + 0xC = 0x72050. ์ด ๋์์ธ์ ์คํฌ๋ฆฝํธ๋ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค.
def put_unconditional_branch(source, destination):
offset = (destination - source - 4) >> 1
if offset > 2097151 or offset < -2097152:
raise RuntimeError("Invalid offset")
if offset > 1023 or offset < -1024:
instruction1 = 0xf000 | ((offset >> 11) & 0x7ff)
instruction2 = 0xb800 | (offset & 0x7ff)
patch_word(source, instruction1)
patch_word(source + 2, instruction2)
else:
instruction = 0xe000 | (offset & 0x7ff)
patch_word(source, instruction)
ea = here()
if get_wide_word(ea) == 0xb503: #PUSH {R0,R1,LR}
ea1 = ea + 6
if get_wide_word(ea + 2) == 0xbf00: #NOP
ea1 += 2
offset = get_wide_dword(ea1)
put_unconditional_branch(ea, (ea1 + offset) & 0xffffffff)
else:
print "Unable to detect first instruction"
์คํฌ๋ฆฝํธ ์คํ ๊ฒฐ๊ณผ:
ํจ์์ ๋ชจ๋ ๊ฒ์ด ํจ์น๋๋ฉด IDA๊ฐ ์ค์ ์์์ ๊ฐ๋ฆฌํฌ ์ ์์ต๋๋ค. ๋ชจ๋ ํจ์ ์ฝ๋๋ฅผ ํ๋๋ก ๋ฌถ๊ณ HexRays๋ฅผ ์ฌ์ฉํ์ฌ ๋์ปดํ์ผํ ์ ์์ต๋๋ค.
๋ฌธ์์ด ๋์ฝ๋ฉ
์ฐ๋ฆฌ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๊ธฐ๊ณ์ด ์ฝ๋์ ๋๋ ํ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ต๋๋ค. libsgmainso-6.4.36.so UC Browser์์ ํจ์ ์ฝ๋๋ฅผ ๋ฐ์์ต๋๋ค. JNI_OnLoad.
int __fastcall real_JNI_OnLoad(JavaVM *vm)
{
int result; // r0
jclass clazz; // r0 MAPDST
int v4; // r0
JNIEnv *env; // r4
int v6; // [sp-40h] [bp-5Ch]
int v7; // [sp+Ch] [bp-10h]
v7 = *(_DWORD *)off_8AC00;
if ( !vm )
goto LABEL_39;
sub_7C4F4();
env = (JNIEnv *)sub_7C5B0(0);
if ( !env )
goto LABEL_39;
v4 = sub_72CCC();
sub_73634(v4);
sub_73E24(&unk_83EA6, &v6, 49);
clazz = (jclass)((int (__fastcall *)(JNIEnv *, int *))(*env)->FindClass)(env, &v6);
if ( clazz
&& (sub_9EE4(),
sub_71D68(env),
sub_E7DC(env) >= 0
&& sub_69D68(env) >= 0
&& sub_197B4(env, clazz) >= 0
&& sub_E240(env, clazz) >= 0
&& sub_B8B0(env, clazz) >= 0
&& sub_5F0F4(env, clazz) >= 0
&& sub_70640(env, clazz) >= 0
&& sub_11F3C(env) >= 0
&& sub_21C3C(env, clazz) >= 0
&& sub_2148C(env, clazz) >= 0
&& sub_210E0(env, clazz) >= 0
&& sub_41B58(env, clazz) >= 0
&& sub_27920(env, clazz) >= 0
&& sub_293E8(env, clazz) >= 0
&& sub_208F4(env, clazz) >= 0) )
{
result = (sub_B7B0(env, clazz) >> 31) | 0x10004;
}
else
{
LABEL_39:
result = -1;
}
return result;
}
๋ค์ ์ค์ ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
sub_73E24(&unk_83EA6, &v6, 49);
clazz = (jclass)((int (__fastcall *)(JNIEnv *, int *))(*env)->FindClass)(env, &v6);
๊ธฐ๋ฅ ์ค sub_73E24 ํด๋์ค ์ด๋ฆ์ด ๋ถ๋ช ํ ํด๋ ๋๊ณ ์์ต๋๋ค. ์ด ํจ์์ ๋งค๊ฐ๋ณ์๋ก๋ ์ํธํ๋ ๋ฐ์ดํฐ์ ์ ์ฌํ ๋ฐ์ดํฐ์ ๋ํ ํฌ์ธํฐ, ํน์ ๋ฒํผ ๋ฐ ์ซ์๊ฐ ์ ๋ฌ๋ฉ๋๋ค. ๋ถ๋ช ํ ํจ์๋ฅผ ํธ์ถํ ํ์๋ ํจ์์ ์ ๋ฌ๋๊ธฐ ๋๋ฌธ์ ๋ฒํผ์ ํด๋ ๋ ๋ผ์ธ์ด ์์ ๊ฒ์ ๋๋ค. ํด๋์ค ์ฐพ๊ธฐ, ํด๋์ค ์ด๋ฆ์ ๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก ์ฌ์ฉํฉ๋๋ค. ๋ฐ๋ผ์ ์ซ์๋ ๋ฒํผ์ ํฌ๊ธฐ ๋๋ ์ค์ ๊ธธ์ด์ ๋๋ค. ํด๋์ค ์ด๋ฆ์ ํด๋ ํด ๋ด ์๋ค. ํด๋์ค ์ด๋ฆ์ ์ฐ๋ฆฌ๊ฐ ์ฌ๋ฐ๋ฅธ ๋ฐฉํฅ์ผ๋ก ๊ฐ๊ณ ์๋์ง ์๋ ค์ค ๊ฒ์ ๋๋ค. ์์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๋์ง ์์ธํ ์ดํด ๋ณด๊ฒ ์ต๋๋ค. sub_73E24.
int __fastcall sub_73E56(unsigned __int8 *in, unsigned __int8 *out, size_t size)
{
int v4; // r6
int v7; // r11
int v8; // r9
int v9; // r4
size_t v10; // r5
int v11; // r0
struc_1 v13; // [sp+0h] [bp-30h]
int v14; // [sp+1Ch] [bp-14h]
int v15; // [sp+20h] [bp-10h]
v4 = 0;
v15 = *(_DWORD *)off_8AC00;
v14 = 0;
v7 = sub_7AF78(17);
v8 = sub_7AF78(size);
if ( !v7 )
{
v9 = 0;
goto LABEL_12;
}
(*(void (__fastcall **)(int, const char *, int))(v7 + 12))(v7, "DcO/lcK+h?m3c*q@", 16);
if ( !v8 )
{
LABEL_9:
v4 = 0;
goto LABEL_10;
}
v4 = 0;
if ( !in )
{
LABEL_10:
v9 = 0;
goto LABEL_11;
}
v9 = 0;
if ( out )
{
memset(out, 0, size);
v10 = size - 1;
(*(void (__fastcall **)(int, unsigned __int8 *, size_t))(v8 + 12))(v8, in, v10);
memset(&v13, 0, 0x14u);
v13.field_4 = 3;
v13.field_10 = v7;
v13.field_14 = v8;
v11 = sub_6115C(&v13, &v14);
v9 = v11;
if ( v11 )
{
if ( *(_DWORD *)(v11 + 4) == v10 )
{
qmemcpy(out, *(const void **)v11, v10);
v4 = *(_DWORD *)(v9 + 4);
}
else
{
v4 = 0;
}
goto LABEL_11;
}
goto LABEL_9;
}
LABEL_11:
sub_7B148(v7);
LABEL_12:
if ( v8 )
sub_7B148(v8);
if ( v9 )
sub_7B148(v9);
return v4;
}
๊ธฐ๋ฅ sub_7AF78 ์ง์ ๋ ํฌ๊ธฐ์ ๋ฐ์ดํธ ๋ฐฐ์ด์ ๋ํ ์ปจํ ์ด๋ ์ธ์คํด์ค๋ฅผ ์์ฑํฉ๋๋ค(์ด๋ฌํ ์ปจํ ์ด๋์ ๋ํด์๋ ์์ธํ ์ค๋ช ํ์ง ์์ต๋๋ค). ์ฌ๊ธฐ์ ๋ ๊ฐ์ ์ปจํ ์ด๋๊ฐ ์์ฑ๋ฉ๋๋ค. ํ๋๋ ๋ค์ ์ค์ ํฌํจํฉ๋๋ค. "DcO/lcK+h?m3c*q@" (์ด๊ฒ์ ํค๋ผ๊ณ ์ถ์ธกํ๊ธฐ ์ฝ์ต๋๋ค), ๋ค๋ฅธ ํ๋๋ ์ํธํ๋ ๋ฐ์ดํฐ๋ฅผ ํฌํจํฉ๋๋ค. ๋ค์์ผ๋ก, ๋ ๊ฐ์ฒด ๋ชจ๋ ํน์ ๊ตฌ์กฐ์ ๋ฐฐ์น๋๊ณ , ์ด๋ ํจ์์ ์ ๋ฌ๋ฉ๋๋ค. sub_6115C. ๋ํ ์ด ๊ตฌ์กฐ์์ ํ๋์ ๊ฐ 3์ ํ์ํ๊ณ ๋ค์์๋ ์ด ๊ตฌ์กฐ์ ์ด๋ค ์ผ์ด ๋ฐ์ํ๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
int __fastcall sub_611B4(struc_1 *a1, _DWORD *a2)
{
int v3; // lr
unsigned int v4; // r1
int v5; // r0
int v6; // r1
int result; // r0
int v8; // r0
*a2 = 820000;
if ( a1 )
{
v3 = a1->field_14;
if ( v3 )
{
v4 = a1->field_4;
if ( v4 < 0x19 )
{
switch ( v4 )
{
case 0u:
v8 = sub_6419C(a1->field_0, a1->field_10, v3);
goto LABEL_17;
case 3u:
v8 = sub_6364C(a1->field_0, a1->field_10, v3);
goto LABEL_17;
case 0x10u:
case 0x11u:
case 0x12u:
v8 = sub_612F4(
a1->field_0,
v4,
*(_QWORD *)&a1->field_8,
*(_QWORD *)&a1->field_8 >> 32,
a1->field_10,
v3,
a2);
goto LABEL_17;
case 0x14u:
v8 = sub_63A28(a1->field_0, v3);
goto LABEL_17;
case 0x15u:
sub_61A60(a1->field_0, v3, a2);
return result;
case 0x16u:
v8 = sub_62440(a1->field_14);
goto LABEL_17;
case 0x17u:
v8 = sub_6226C(a1->field_10, v3);
goto LABEL_17;
case 0x18u:
v8 = sub_63530(a1->field_14);
LABEL_17:
v6 = 0;
if ( v8 )
{
*a2 = 0;
v6 = v8;
}
return v6;
default:
LOWORD(v5) = 28032;
goto LABEL_5;
}
}
}
}
LOWORD(v5) = -27504;
LABEL_5:
HIWORD(v5) = 13;
v6 = 0;
*a2 = v5;
return v6;
}
์ค์์น ๋งค๊ฐ๋ณ์๋ ์ด์ ์ ๊ฐ 3์ด ํ ๋น๋ ๊ตฌ์กฐ ํ๋์ ๋๋ค. ์ฌ๋ก 3์ ์ดํด๋ณด์ธ์. sub_6364C ๋งค๊ฐ๋ณ์๋ ์ด์ ํจ์์ ์ถ๊ฐ๋ ๊ตฌ์กฐ(์: ํค ๋ฐ ์ํธํ๋ ๋ฐ์ดํฐ)์์ ์ ๋ฌ๋ฉ๋๋ค. ์์ธํ ์ดํด๋ณด๋ฉด sub_6364C, RC4 ์๊ณ ๋ฆฌ์ฆ์ ์ธ์ํ ์ ์์ต๋๋ค.
์ฐ๋ฆฌ์๊ฒ๋ ์๊ณ ๋ฆฌ์ฆ๊ณผ ํค๊ฐ ์์ต๋๋ค. ํด๋์ค ์ด๋ฆ์ ํด๋ ํด ๋ด ์๋ค. ์ผ์ด๋ ์ผ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. com/taobao/wireless/security/adapter/JNICLibrary. ์์ฒญ๋! ์ฐ๋ฆฌ๋ ์ฌ๋ฐ๋ฅธ ๊ธธ์ ๊ฐ๊ณ ์์ต๋๋ค.
๋ช ๋ น ํธ๋ฆฌ
์ด์ ์ฐ๋ฆฌ๋ ๋์ ์ ์ฐพ์์ผ ํฉ๋๋ค ๋ฑ๋ก์์ฃผ๋ฏผ, ์ด๋ ์ฐ๋ฆฌ์๊ฒ ํจ์๋ฅผ ์๋ ค์ค ๊ฒ์ ๋๋ค doCommandNative. ํธ์ถ๋๋ ํจ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. JNI_OnLoad, ๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ฐ๊ฒฌํฉ๋๋ค sub_B7B0:
int __fastcall sub_B7F6(JNIEnv *env, jclass clazz)
{
char signature[41]; // [sp+7h] [bp-55h]
char name[16]; // [sp+30h] [bp-2Ch]
JNINativeMethod method; // [sp+40h] [bp-1Ch]
int v8; // [sp+4Ch] [bp-10h]
v8 = *(_DWORD *)off_8AC00;
decryptString((unsigned __int8 *)&unk_83ED9, (unsigned __int8 *)name, 0x10u);// doCommandNative
decryptString((unsigned __int8 *)&unk_83EEA, (unsigned __int8 *)signature, 0x29u);// (I[Ljava/lang/Object;)Ljava/lang/Object;
method.name = name;
method.signature = signature;
method.fnPtr = sub_B69C;
return ((int (__fastcall *)(JNIEnv *, jclass, JNINativeMethod *, int))(*env)->RegisterNatives)(env, clazz, &method, 1) >> 31;
}
๊ทธ๋ฆฌ๊ณ ์ค์ ๋ก ์ฌ๊ธฐ์ ์ด๋ฆ์ด ๋ถ์ ๋ค์ดํฐ๋ธ ๋ฉ์๋๊ฐ ๋ฑ๋ก๋์ด ์์ต๋๋ค. doCommandNative. ์ด์ ์ฐ๋ฆฌ๋ ๊ทธ์ ์ฃผ์๋ฅผ ์๊ณ ์์ต๋๋ค. ๊ทธ๊ฐ ๋ฌด์์ ํ๋์ง ๋ด ์๋ค.
int __fastcall doCommandNative(JNIEnv *env, jobject obj, int command, jarray args)
{
int v5; // r5
struc_2 *a5; // r6
int v9; // r1
int v11; // [sp+Ch] [bp-14h]
int v12; // [sp+10h] [bp-10h]
v5 = 0;
v12 = *(_DWORD *)off_8AC00;
v11 = 0;
a5 = (struc_2 *)malloc(0x14u);
if ( a5 )
{
a5->field_0 = 0;
a5->field_4 = 0;
a5->field_8 = 0;
a5->field_C = 0;
v9 = command % 10000 / 100;
a5->field_0 = command / 10000;
a5->field_4 = v9;
a5->field_8 = command % 100;
a5->field_C = env;
a5->field_10 = args;
v5 = sub_9D60(command / 10000, v9, command % 100, 1, (int)a5, &v11);
}
free(a5);
if ( !v5 && v11 )
sub_7CF34(env, v11, &byte_83ED7);
return v5;
}
์ด๋ฆ์ ๋ณด๋ฉด ๊ฐ๋ฐ์๊ฐ ๋ค์ดํฐ๋ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์ ์กํ๊ธฐ๋ก ๊ฒฐ์ ํ ๋ชจ๋ ๊ธฐ๋ฅ์ ์ง์ ์ ์ด ์ฌ๊ธฐ์ ์์์ ์ง์ํ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ํจ์ ๋ฒํธ 10601์ ๊ด์ฌ์ด ์์ต๋๋ค.
์ฝ๋์์ ๋ช ๋ น ๋ฒํธ๊ฐ ์ธ ๊ฐ์ ์ซ์๋ฅผ ์์ฑํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ๋ช ๋ น/10000, ๋ช ๋ น % 10000 / 100 ะธ ๋ช ๋ น % 10, ์ฆ, ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ์๋ 1, 6, 1์ ๋๋ค. ์ด ์ธ ์ซ์์ ํฌ์ธํฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. JNIEnv ํจ์์ ์ ๋ฌ๋ ์ธ์๋ ๊ตฌ์กฐ์ ์ถ๊ฐ๋์ด ์ ๋ฌ๋ฉ๋๋ค. ์ป์ ์ธ ๊ฐ์ ์ซ์(N1, N2 ๋ฐ N3๋ก ํ์)๋ฅผ ์ฌ์ฉํ์ฌ ๋ช ๋ น ํธ๋ฆฌ๊ฐ ๊ตฌ์ถ๋ฉ๋๋ค.
์ด ๊ฐ์:
ํธ๋ฆฌ๋ ๋์ ์ผ๋ก ์ฑ์์ง๋๋ค. JNI_OnLoad.
์ธ ๊ฐ์ ์ซ์๊ฐ ํธ๋ฆฌ์ ๊ฒฝ๋ก๋ฅผ ์ธ์ฝ๋ฉํฉ๋๋ค. ํธ๋ฆฌ์ ๊ฐ ์์๋ ํด๋น ํจ์์ ํฌ์ผ ์ฃผ์๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ํค๋ ์์ ๋
ธ๋์ ์์ต๋๋ค. ์ฌ์ฉ๋ ๋ชจ๋ ๊ตฌ์กฐ๋ฅผ ์ดํดํ๋ค๋ฉด ์ฝ๋์์ ํ์ํ ํจ์๊ฐ ํธ๋ฆฌ์ ์ถ๊ฐ๋๋ ์์น๋ฅผ ์ฐพ๋ ๊ฒ์ด ์ด๋ ต์ง ์์ต๋๋ค(์ด๋ฏธ ํฐ ๋ฌธ์๋ฅผ ๋ถํ๋ฆฌ์ง ์๊ธฐ ์ํด ์ค๋ช
ํ์ง ์์ต๋๋ค).
๋ ๋๋ ํ
ํธ๋ํฝ์ ํด๋ ํด์ผ ํ๋ ํจ์์ ์ฃผ์: 0x5F1AC๋ฅผ ๋ฐ์์ต๋๋ค. ํ์ง๋ง ๊ธฐ๋ปํ๊ธฐ์๋ ์์ง ์ด๋ฅด์ต๋๋ค. UC ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์๊ฐ ์ฐ๋ฆฌ๋ฅผ ์ํด ๋ ๋ค๋ฅธ ๋๋ผ์์ ์ค๋นํ์ต๋๋ค.
Java ์ฝ๋๋ก ๊ตฌ์ฑ๋ ๋ฐฐ์ด์์ ๋งค๊ฐ๋ณ์๋ฅผ ์์ ํ ํ ๋ค์์ ์ป์ต๋๋ค.
์ฃผ์ 0x4D070์ ํจ์์. ๊ทธ๋ฆฌ๊ณ ๋ ๋ค๋ฅธ ์ ํ์ ์ฝ๋ ๋๋
ํ๊ฐ ์ฐ๋ฆฌ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๋ค.
R7๊ณผ R4์ ๋ ๊ฐ์ ์ธ๋ฑ์ค๋ฅผ ๋ฃ์ต๋๋ค.
์ฒซ ๋ฒ์งธ ์ธ๋ฑ์ค๋ฅผ R11๋ก ์ด๋ํฉ๋๋ค.
ํ
์ด๋ธ์์ ์ฃผ์๋ฅผ ์ป์ผ๋ ค๋ฉด ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ญ์์ค.
์ฒซ ๋ฒ์งธ ์ฃผ์๋ก ์ด๋ํ ํ R4์ ์๋ ๋ ๋ฒ์งธ ์ธ๋ฑ์ค๊ฐ ์ฌ์ฉ๋ฉ๋๋ค. ํ
์ด๋ธ์๋ 230๊ฐ์ ์์๊ฐ ์์ต๋๋ค.
์ด๋ป๊ฒ ํด์ผ ํ ๊น์? ํธ์ง -> ๊ธฐํ -> ์ค์์น ๊ด์ฉ์ด ์ง์ ์ ํตํด IDA์ ์ด๊ฒ์ด ์ค์์น์์ ์๋ฆด ์ ์์ต๋๋ค.
๊ฒฐ๊ณผ ์ฝ๋๋ ๋ฌด์ญ์ต๋๋ค. ํ์ง๋ง ์ ๊ธ์ ํค์ณ๋๊ฐ๋ค ๋ณด๋ฉด ์ด๋ฏธ ์ฐ๋ฆฌ์๊ฒ ์น์ํ ํจ์๊ฐ ํธ์ถ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. sub_6115C:
์ฌ๋ก 3์ ๊ฒฝ์ฐ RC4 ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ์ํธ๋ฅผ ํด๋
ํ๋ ์ค์์น๊ฐ ์์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ๊ฒฝ์ฐ ํจ์์ ์ ๋ฌ๋ ๊ตฌ์กฐ๋ ์ ๋ฌ๋ ๋งค๊ฐ๋ณ์๋ก ์ฑ์์ง๋๋ค. doCommandNative. ์ฐ๋ฆฌ๊ฐ ๊ฑฐ๊ธฐ์์ ๋ฌด์์ ๊ฐ์ก๋์ง ๊ธฐ์ตํ์ ๋งค์ง์ธํธ ๊ฐ์ 16์
๋๋ค. ํด๋น ์ฌ๋ก๋ฅผ ์ดํด๋ณด๊ณ ์ฌ๋ฌ ๋ฒ์ ์ ํ ํ์ ์๊ณ ๋ฆฌ์ฆ์ ์๋ณํ ์ ์๋ ์ฝ๋๋ฅผ ์ฐพ์ต๋๋ค.
AES ์
๋๋ค!
์๊ณ ๋ฆฌ์ฆ์ ์กด์ฌํ๋ฉฐ, ๋จ์ ๊ฒ์ ํด๋น ๋งค๊ฐ๋ณ์(๋ชจ๋, ํค ๋ฐ ์ด๊ธฐํ ๋ฒกํฐ)๋ฅผ ์ป๋ ๊ฒ๋ฟ์ ๋๋ค(ํด๋น ์กด์ฌ ์ฌ๋ถ๋ AES ์๊ณ ๋ฆฌ์ฆ์ ์๋ ๋ชจ๋์ ๋ฐ๋ผ ๋ค๋ฆ). ์ด๋ฅผ ํฌํจํ๋ ๊ตฌ์กฐ๋ ํจ์ ํธ์ถ ์ด์ ์ด๋๊ฐ์ ํ์ฑ๋์ด์ผ ํฉ๋๋ค. sub_6115C, ๊ทธ๋ฌ๋ ์ฝ๋์ ์ด ๋ถ๋ถ์ ํนํ ๋๋ ํ๋์ด ์์ผ๋ฏ๋ก ํด๋ ๊ธฐ๋ฅ์ ๋ชจ๋ ๋งค๊ฐ๋ณ์๊ฐ ํ์ผ์ ๋คํ๋๋๋ก ์ฝ๋๋ฅผ ํจ์นํ๋ ์์ด๋์ด๊ฐ ๋ ์ค๋ฆ ๋๋ค.
ํจ์น
๋ชจ๋ ํจ์น ์ฝ๋๋ฅผ ์ด์ ๋ธ๋ฆฌ ์ธ์ด๋ก ์๋์ผ๋ก ์์ฑํ์ง ์์ผ๋ ค๋ฉด Android Studio๋ฅผ ์คํํ๊ณ ๋ณตํธํ ํจ์์ ๋์ผํ ์ ๋ ฅ ๋งค๊ฐ๋ณ์๋ฅผ ์์ ํ์ฌ ํ์ผ์ ์ฐ๋ ํจ์๋ฅผ ์์ฑํ ๋ค์ ์ปดํ์ผ๋ฌ๊ฐ ์ํํ ์ฝ๋๋ฅผ ๋ณต์ฌํ์ฌ ๋ถ์ฌ๋ฃ์ ์ ์์ต๋๋ค. ์์ฑํ๋ค.
UC ๋ธ๋ผ์ฐ์ ํ์ ์น๊ตฌ๋ค๋ ์ฝ๋ ์ถ๊ฐ์ ํธ์์ฑ์ ๊ณ ๋ คํ์ต๋๋ค. ๊ฐ ํจ์์ ์์ ๋ถ๋ถ์๋ ๋ค๋ฅธ ํจ์๋ก ์ฝ๊ฒ ๋์ฒด๋ ์ ์๋ ๊ฐ๋น์ง ์ฝ๋๊ฐ ์๋ค๋ ๊ฒ์ ๊ธฐ์ตํ์ธ์. ๋งค์ฐ ํธ๋ฆฌํฉ๋๋ค ๐ ํ์ง๋ง ๋์ ํจ์ ์์ ๋ถ๋ถ์ ๋ชจ๋ ๋งค๊ฐ๋ณ์๋ฅผ ํ์ผ์ ์ ์ฅํ๋ ์ฝ๋๋ฅผ ์ํ ๊ณต๊ฐ์ด ๋ถ์กฑํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ์ ์ฌ๋ฌ ๋ถ๋ถ์ผ๋ก ๋๋๊ณ ์ธ์ ํ ๊ธฐ๋ฅ์ ๊ฐ๋น์ง ๋ธ๋ก์ ์ฌ์ฉํด์ผ ํ์ต๋๋ค. ์ด XNUMX๊ฐ์ ๋ถ๋ถ์ด ์์์ต๋๋ค.
ะะตัะฒะฐั์ ัะฐััั :
ARM ์ํคํ
์ฒ์์ ์ฒ์ 0๊ฐ์ ํจ์ ๋งค๊ฐ๋ณ์๋ ๋ ์ง์คํฐ R3-R0์ ํตํด ์ ๋ฌ๋๊ณ , ๋๋จธ์ง๋ ์คํ์ ํตํด ์ ๋ฌ๋ฉ๋๋ค. LR ๋ ์ง์คํฐ๋ ๋ณต๊ท ์ฃผ์๋ฅผ ์ ๋ฌํฉ๋๋ค. ๋งค๊ฐ๋ณ์๋ฅผ ๋คํํ ํ ํจ์๊ฐ ์๋ํ ์ ์๋๋ก ์ด ๋ชจ๋ ๊ฒ์ ์ ์ฅํด์ผ ํฉ๋๋ค. ๋ํ ํ๋ก์ธ์ค์์ ์ฌ์ฉํ ๋ชจ๋ ๋ ์ง์คํฐ๋ฅผ ์ ์ฅํด์ผ ํ๋ฏ๋ก PUSH.W {R10-R7,LR}์ ์ํํฉ๋๋ค. RXNUMX์์๋ ์คํ์ ํตํด ํจ์์ ์ ๋ฌ๋ ๋งค๊ฐ๋ณ์ ๋ชฉ๋ก์ ์ฃผ์๋ฅผ ์ป์ต๋๋ค.
๊ธฐ๋ฅ ์ฌ์ฉ ํฌํ ํ์ผ์ ์ด์ด๋ณด์ /๋ฐ์ดํฐ/๋ก์ปฌ/tmp/aes "ab" ๋ชจ๋์์
์ฆ, ์ถ๊ฐ๋ฅผ ์ํด. R0์์๋ ํ์ผ ์ด๋ฆ์ ์ฃผ์๋ฅผ ๋ก๋ํ๊ณ , R1์์๋ ๋ชจ๋๋ฅผ ๋ํ๋ด๋ ์ค์ ์ฃผ์๋ฅผ ๋ก๋ํฉ๋๋ค. ์ฌ๊ธฐ์ ๊ฐ๋น์ง ์ฝ๋๊ฐ ์ข
๋ฃ๋๋ฏ๋ก ๋ค์ ๊ธฐ๋ฅ์ผ๋ก ๋์ด๊ฐ๋๋ค. ๊ณ์ ์๋ํ๊ธฐ ์ํด ์ฐ๋ฆฌ๋ ์ฒ์์ ๊ฐ๋น์ง๋ฅผ ์ฐํํ์ฌ ํจ์์ ์ค์ ์ฝ๋๋ก์ ์ ํ์ ๋ฐฐ์นํ๊ณ ๊ฐ๋น์ง ๋์ ํจ์น์ ์ฐ์์ ์ถ๊ฐํฉ๋๋ค.
๋ถ๋ฆ ํฌํ.
ํจ์์ ์ฒ์ ์ธ ๋งค๊ฐ๋ณ์ ์์ด์ค ์ ํ์ด ์๋ค INT. ์ฒ์์ ๋ ์ง์คํฐ๋ฅผ ์คํ์ ์ ์ฅํ์ผ๋ฏ๋ก ๊ฐ๋จํ ํจ์๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค. ์ฐ๊ธฐ ์คํ์ ์๋ ์ฃผ์์ ๋๋ค.
๋ค์์ผ๋ก ๋ฐ์ดํฐ ํฌ๊ธฐ์ ํค, ์ด๊ธฐํ ๋ฒกํฐ ๋ฐ ์ํธํ๋ ๋ฐ์ดํฐ์ ๋ํ ๋ฐ์ดํฐ์ ๋ํ ํฌ์ธํฐ๋ฅผ ํฌํจํ๋ ์ธ ๊ฐ์ง ๊ตฌ์กฐ๊ฐ ์์ต๋๋ค.
๋ง์ง๋ง์ผ๋ก ํ์ผ์ ๋ซ๊ณ ๋ ์ง์คํฐ๋ฅผ ๋ณต์ํ ํ ์ ์ด๊ถ์ ์ค์ ๊ธฐ๋ฅ์ผ๋ก ์ด์ ํฉ๋๋ค. ์์ด์ค.
ํจ์น๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํฌํจ๋ APK๋ฅผ ์์งํ๊ณ ์๋ช ํ ํ ๊ธฐ๊ธฐ/์๋ฎฌ๋ ์ดํฐ์ ์ ๋ก๋ํ๊ณ ์คํํฉ๋๋ค. ๋คํ๊ฐ ์์ฑ๋๊ณ ์๊ณ ๊ฑฐ๊ธฐ์ ๋ง์ ๋ฐ์ดํฐ๊ฐ ๊ธฐ๋ก๋๊ณ ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ๋ธ๋ผ์ฐ์ ๋ ํธ๋ํฝ์๋ง ์ํธํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์๋๋ผ ๋ชจ๋ ์ํธํ๊ฐ ํด๋น ๊ธฐ๋ฅ์ ํต๊ณผํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ค ์ด์ ๋ก ํ์ํ ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉฐ ํ์ํ ์์ฒญ์ด ํธ๋ํฝ์ ํ์๋์ง ์์ต๋๋ค. UC ๋ธ๋ผ์ฐ์ ๊ฐ ํ์ํ ์์ฒญ์ ํ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์์ผ๋ ค๋ฉด ์ด์ ์ ๋ฐ์ ์๋ฒ์์ ์ํธํ๋ ์๋ต์ ๋ฐ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค์ ํจ์นํด ๋ณด๊ฒ ์ต๋๋ค. ๊ธฐ๋ณธ ํ๋์ onCreate์ ์ํธ ํด๋ ์ ์ถ๊ฐํฉ๋๋ค.
const/16 v1, 0x62
new-array v1, v1, [B
fill-array-data v1, :encrypted_data
const/16 v0, 0x1f
invoke-static {v0, v1}, Lcom/uc/browser/core/d/c/g;->j(I[B)[B
move-result-object v1
array-length v2, v1
invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
move-result-object v2
const-string v0, "ololo"
invoke-static {v0, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
์ฐ๋ฆฌ๋ ์กฐ๋ฆฝ, ์๋ช , ์ค์น, ์ถ์๋ฅผ ์งํํฉ๋๋ค. ๋ฉ์๋๊ฐ null์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ NullPointerException์ด ๋ฐ์ํฉ๋๋ค.
์ฝ๋๋ฅผ ์ถ๊ฐ๋ก ๋ถ์ํ๋ ๋์ "META-INF/" ๋ฐ ".RSA"๋ผ๋ ํฅ๋ฏธ๋ก์ด ์ค์ ํด๋ ํ๋ ๊ธฐ๋ฅ์ด ๋ฐ๊ฒฌ๋์์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ธ์ฆ์๋ฅผ ํ์ธํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ผ๋ก๋ถํฐ ํค๋ฅผ ์์ฑํ ์๋ ์์ต๋๋ค. ์ ๋ ์ธ์ฆ์์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง ๋ค๋ฃจ๊ณ ์ถ์ง ์์ผ๋ฏ๋ก ์ฌ๋ฐ๋ฅธ ์ธ์ฆ์๋ฅผ ์ ๋ฌํ๊ฒ ์ต๋๋ค. โMETA-INF/โ ๋์ โBLABLINF/โ๋ฅผ ์ป๋๋ก ์ํธํ๋ ๋ผ์ธ์ ํจ์นํ๊ณ , APK์ ํด๋น ์ด๋ฆ์ ํด๋๋ฅผ ์์ฑํ๊ณ ๊ฑฐ๊ธฐ์ Squirrel ๋ธ๋ผ์ฐ์ ์ธ์ฆ์๋ฅผ ์ถ๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
์ฐ๋ฆฌ๋ ์กฐ๋ฆฝ, ์๋ช , ์ค์น, ์ถ์๋ฅผ ์งํํฉ๋๋ค. ๋น๊ณ ! ์ฐ๋ฆฌ๋ ์ด์ ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค!
MitM
์ฐ๋ฆฌ๋ ํค์ ํค์ ๋์ผํ ์ด๊ธฐํ ๋ฒกํฐ๋ฅผ ๋ฐ์์ต๋๋ค. CBC ๋ชจ๋์์ ์๋ฒ ์๋ต์ ์ํธ๋ฅผ ํด๋ ํด ๋ณด๊ฒ ์ต๋๋ค.
MD5, "extract_unzipsize" ๋ฐ ์ซ์์ ์ ์ฌํ ์์นด์ด๋ธ URL์ด ํ์๋ฉ๋๋ค. ํ์ธํฉ๋๋ค: ์์นด์ด๋ธ์ MD5๊ฐ ๋์ผํ๊ณ , ์์ถ์ ํผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํฌ๊ธฐ๊ฐ ๋์ผํฉ๋๋ค. ์ฐ๋ฆฌ๋ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํจ์นํ์ฌ ๋ธ๋ผ์ฐ์ ์ ์ ๊ณตํ๋ ค๊ณ ํฉ๋๋ค. ํจ์น๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ก๋๋์์์ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด "PWNED!"๋ผ๋ ํ
์คํธ๊ฐ ํฌํจ๋ SMS๋ฅผ ์์ฑํ๋ ค๋ ์ธํ
ํธ๋ฅผ ์คํํฉ๋๋ค. ์๋ฒ์ ๋ ๊ฐ์ง ์๋ต์ ๋์ฒดํฉ๋๋ค.
๋ธ๋ผ์ฐ์ ๊ฐ ์์นด์ด๋ธ๋ฅผ ์ฌ๋ฌ ๋ฒ ๋ค์ด๋ก๋ํ๋ ค๊ณ ์๋ํ ํ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋ถ๋ช
ํ ๋ญ๊ฐ
๊ทธ๋ ์ข์ํ์ง ์๋๋ค. ์ด ๋ถ๋ถ๋ช
ํ ํ์์ ๋ถ์ํ ๊ฒฐ๊ณผ ์๋ฒ๊ฐ ์์นด์ด๋ธ์ ํฌ๊ธฐ๋ ์ ์กํ๋ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค.
LEB128๋ก ์ธ์ฝ๋ฉ๋ฉ๋๋ค. ํจ์น ์ดํ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํฌํจ๋ ์์นด์ด๋ธ์ ํฌ๊ธฐ๊ฐ ์กฐ๊ธ ๋ณ๊ฒฝ๋์ด ๋ธ๋ผ์ฐ์ ์์๋ ํด๋น ์์นด์ด๋ธ๊ฐ ๋น๋ค๊ฒ ๋ค์ด๋ก๋๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ์ฌ ์ฌ๋ฌ ๋ฒ ์๋ํ ๋์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
์์นด์ด๋ธ์ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํฉ๋๋ค... ๊ทธ๋ฆฌ๊ณ โ ์น๋ฆฌ! ๐ ๊ฒฐ๊ณผ๋ ์์์ ์์ต๋๋ค.
๊ฒฐ๊ณผ ๋ฐ ๊ฐ๋ฐ์ ๋ฐ์
๋ง์ฐฌ๊ฐ์ง๋ก ํด์ปค๋ UC ๋ธ๋ผ์ฐ์ ์ ์์ ํ์ง ์์ ๊ธฐ๋ฅ์ ์ด์ฉํด ์ ์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ฐฐํฌํ๊ณ ์คํํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ธ๋ผ์ฐ์ ์ ์ปจํ ์คํธ์์ ์๋ํ๋ฏ๋ก ๋ชจ๋ ์์คํ ๊ถํ์ ๋ฐ๊ฒ ๋ฉ๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ํผ์ฑ ์ฐฝ์ ํ์ํ๋ ๊ธฐ๋ฅ๊ณผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ ๋ก๊ทธ์ธ, ๋น๋ฐ๋ฒํธ ๋ฐ ์ฟ ํค๋ฅผ ํฌํจํ์ฌ ์ฃผํฉ์ ์ค๊ตญ ๋ค๋์ฅ์ ์์ ํ์ผ์ ๋ํ ์ก์ธ์ค ๊ธฐ๋ฅ์ด ์ ๊ณต๋ฉ๋๋ค.
์ฐ๋ฆฌ๋ UC ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์์๊ฒ ์ฐ๋ฝํ์ฌ ์ฐ๋ฆฌ๊ฐ ๋ฐ๊ฒฌํ ๋ฌธ์ ์ ๋ํด ์๋ฆฌ๊ณ ์ทจ์ฝ์ ๊ณผ ์ํ์ฑ์ ์ง์ ํ๋ ค๊ณ ๋
ธ๋ ฅํ์ง๋ง ๊ทธ๋ค์ ์ฐ๋ฆฌ์ ์๋ฌด๋ฐ ๋
ผ์๋ ํ์ง ์์์ต๋๋ค. ํํธ, ๋ธ๋ผ์ฐ์ ๋ ๋์ ์ ๋๋ ์ํํ ๊ธฐ๋ฅ์ ๊ณ์ํด์ ๊ณผ์ํ์ต๋๋ค. ํ์ง๋ง ์ผ๋จ ์ทจ์ฝ์ ์ ์ธ๋ถ์ฌํญ์ด ๊ณต๊ฐ๋์ ๋ ์ด์ ์์ ์ฒ๋ผ ์ด๋ฅผ ๋ฌด์ํ ์ ์์์ต๋๋ค. 27์ XNUMX์ผ์
HTTPS๋ฅผ ํตํด ์๋ฒ์ ์ก์ธ์คํ๋ UC Browser 12.10.9.1193์ ์ ๋ฒ์ ์ด ์ถ์๋์์ต๋๋ค.
๋ํ "์์ " ์ดํ ์ด ๊ธฐ์ฌ๋ฅผ ์์ฑํ ๋๊น์ง ๋ธ๋ผ์ฐ์ ์์ PDF๋ฅผ ์ด๋ ค๊ณ ํ๋ฉด "์ฃ์กํฉ๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค!"๋ผ๋ ํ
์คํธ์ ํจ๊ป ์ค๋ฅ ๋ฉ์์ง๊ฐ ํ์๋์์ต๋๋ค. PDF๋ฅผ ์ด๋ ค๊ณ ํ ๋ ์๋ฒ์ ๋ํ ์์ฒญ์ด ์ด๋ฃจ์ด์ง์ง ์์์ง๋ง ๋ธ๋ผ์ฐ์ ๊ฐ ์์๋ ๋ ์์ฒญ์ด ์ด๋ฃจ์ด์ก์ต๋๋ค. ์ด๋ Google Play ๊ท์น์ ์๋ฐํ์ฌ ์คํ ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ๊ณ์ ๋ค์ด๋ก๋ํ ์ ์์์ ์์ํฉ๋๋ค.
์ถ์ฒ : habr.com