查看原文
其他

ollvm算法还原案例分享

咸鱼炒白菜 看雪学苑 2022-07-01

本文为看雪论坛文章

看雪论坛作者ID:咸鱼炒白菜



本文为看雪安卓高研3w班(8月班)优秀学员作品。


下面先让我们来看看讲师对学员学习成果的点评,以及学员的学习心得吧!


讲师点评

逆向分析被ollvm混淆的算法的通用过程,使用Frida hook固定所有随机变量,使得输入一个参数能得到唯一的输出结果。 Frida hook Native定位到数据加密的关键函数,再使用trace分析出加密函数的执行过程,由此分析整个算法源码。
本道题是基于zlib进行了少量魔改的算法,本意是想考察如何快速分析魔改的开源代码,没想到咸鱼炒白菜同学把整个算法都分析出来了。
下面是算法原貌:文中sub_011094对应的函数compress2
int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; int level;{ //。。。省略部分compress2原来的代码 *destLen = stream.total_out; deflateEnd(&stream); unsigned char r2 = 0x75; unsigned char r5 = 0; unsigned char r4 = r5 + (r5 << 1); for (int i = 2; i < *destLen; ++i) { unsigned char r6 = dest[i]; r4 = r2 + (r4 << 1); r4 = r4 ^ r6; dest[i] = r4; } dest[0] = 0x75; dest[1] = 0x8F; return err == Z_STREAM_END ? Z_OK : err;}




学员感想


本题来自于3W班8月的ollvm题,主要考察ollvm算法还原能力


ps. 题目附件请点击“阅读原文”下载。

好消息!!


现在看雪《安卓高级研修班》线下班 & 网课(12月班)开始同步招生啦!


以前没报上高研班的小伙伴赶快抓紧机会报名,升职加薪唾手可得!!





解题过程


1、找到对应产生结果的函数MainActivity中的public native byte[] e(byte[] arg1)


package com.kanxue.ollvm8; import android.os.Bundle;import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import okio.ByteString;import org.apache.commons.lang3.RandomStringUtils; public class MainActivity extends AppCompatActivity { static { System.loadLibrary("xxxxdun"); } public native byte[] e(byte[] arg1) { } @Override // androidx.appcompat.app.AppCompatActivity protected void onCreate(Bundle arg3) { super.onCreate(arg3); this.setContentView(0x7F09001C); // layout:activity_main TextView v3 = (TextView)this.findViewById(0x7F070061); // id:sample_text StringBuilder v0 = new StringBuilder(); v0.append(RandomStringUtils.randomAlphabetic(10)); v0.append("_pediy_imyang_"); v3.setText(ByteString.of(this.e(v0.toString().getBytes())).hex()); }}

2、frida固定入参


function hook_java(){ Java.perform(function () { //org.apache.commons.lang3.RandomStringUtils.randomAlphabetic(int): java.lang.String var RandomStringUtils = Java.use("org.apache.commons.lang3.RandomStringUtils"); RandomStringUtils.randomAlphabetic.overload('int').implementation = function(arg){ var result = this.randomAlphabetic(arg); //console.log("org.apache.commons.lang3.RandomStringUtils.randomAlphabetic:", result); result = "elDIkbaKit"; return result; } //com.kanxue.ollvm5.MainActivity.encryt(byte[]): byte[] var ByteString = Java.use("com.android.okhttp.okio.ByteString"); var MainActivity = Java.use("com.kanxue.ollvm8.MainActivity"); MainActivity.e.implementation = function(arg){ var result = this.e(arg); console.log("com.kanxue.ollvm8.MainActivity arg:", ByteString.of(arg).hex()); console.log("com.kanxue.ollvm8.MainActivity result:", ByteString.of(result).hex()); return result; } });}

3、ida打开libxxxxdun.so找到对应函数,本层无混淆


int __fastcall Java_com_kanxue_ollvm8_MainActivity_e(JNIEnv *a1, int a2, int a3){ int v5; // r6 int v6; // r8 int v7; // r0 int v8; // r10 int v9; // r6 int v10; // r0 _DWORD v12[3]; // [sp+4h] [bp-44h] BYREF char v13[12]; // [sp+10h] [bp-38h] BYREF char v14[12]; // [sp+1Ch] [bp-2Ch] BYREF v5 = ((int (__fastcall *)(JNIEnv *, int))(*a1)->GetArrayLength)(a1, a3); v6 = ((int (__fastcall *)(JNIEnv *, int, _DWORD))(*a1)->GetByteArrayElements)(a1, a3, 0); sub_ED80((int)v14, v6, v5); sub_EDA4(v12, (int)v14); sub_B940(v13, v12); sub_BE34((int)v12); v7 = sub_BA18(v13); v8 = sub_F060(a1, v7); v9 = sub_BA18(v13); v10 = sub_BB44(v13); ((void (__fastcall *)(JNIEnv *, int, _DWORD, int, int))(*a1)->SetByteArrayRegion)(a1, v8, 0, v9, v10); sub_F178(a1, a3, v6, 0); sub_BE34((int)v13); sub_BE34((int)v14); return v8;}

根据hook结果


sub_0E210 onEnter: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEFcda0e034 21 00 00 00 18 00 00 00 40 e0 5f cc 58 e0 a0 cd !.......@._.X...cda0e044 11 18 df d1 16 00 00 00 21 00 00 00 18 00 00 00 ........!.......cda0e054 c0 0f 94 cc b1 a1 eb ac 00 00 00 00 00 c4 fd dd ................cda0e064 88 e1 a0 cd 14 e1 a0 cd 44 c0 e0 eb 02 00 00 00 ........D.......cda0e074 00 00 00 00 a8 e2 a0 cd 77 80 fd cc 44 c0 e0 eb ........w...D...cda0e084 00 00 00 00 02 00 00 00 b0 19 30 14 c0 a8 70 13 ..........0...p.cda0e094 01 00 00 00 70 79 20 cc 01 00 00 00 24 fa 00 00 ....py .....$...cda0e0a4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 3f ...............?cda0e0b4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cda0e0c4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cda0e0d4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cda0e0e4 02 00 00 00 00 00 00 00 a8 e2 a0 cd 00 00 00 00 ................cda0e0f4 88 e1 a0 cd 14 e1 a0 cd 77 c5 10 e9 00 00 00 00 ........w.......cda0e104 b0 19 30 14 c0 a8 70 13 76 11 5e d2 00 01 00 00 ..0...p.v.^.....cda0e114 00 00 00 00 02 00 00 00 00 00 00 00 a8 e2 a0 cd ................cda0e124 4e 00 00 00 48 e1 a0 cd 88 e1 a0 cd 00 00 00 00 N...H...........sub_0E210 onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEFcc5fe040 65 6c 44 49 6b 62 61 4b 69 74 5f 70 65 64 69 79 elDIkbaKit_pediycc5fe050 5f 69 6d 79 61 6e 67 5f 00 69 76 69 74 79 00 00 _imyang_.ivity..cc5fe060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe0a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe0b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe0c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe0d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe0e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe0f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc5fe130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

可发现,有一个结构体:


struct { int n1; int nlen; char* buff; //指向input/output的二进制}

其中sub_B940(outputobj, inputobj);函数传入了入参和出参的结构体,分别打印该函数调用前和调用后出参:


var output;var sub_0B940 = base_libxxxxdun.add(0xB940 + 1);Interceptor.attach(sub_0B940, { onEnter: function (args) { arg0 = args[0]; arg1 = args[1]; output = args[0]; var input = ptr(arg1).add(8); //console.log("sub_0B940 onEnter:", hexdump((ptr(arg0).add(8)).readPointer())); //console.log("sub_0B940 onEnter:", hexdump(input.readPointer())); }, onLeave: function (ret) { var input = ptr(arg1).add(8); output = ptr(arg0).add(8); console.log("sub_0B940 onLeave:", hexdump(output.readPointer())); //console.log("sub_0B940 onLeave:", hexdump(input.readPointer())); }});


得到的结果为算法结果,所以sub_B940为算法关键函数:


sub_0B940 onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEFcc4fc0a0 75 8f 3e 3c 9c 5c e1 79 2d 3b 25 93 12 b6 a9 8a u.><.\.y-;%.....cc4fc0b0 40 59 ab 04 b1 7a 25 73 00 74 69 76 69 74 79 00 @Y...z%s.tivity.cc4fc0c0 65 6c 44 49 6b 62 61 4b 69 74 5f 70 65 64 69 79 elDIkbaKit_pediycc4fc0d0 5f 69 6d 79 61 6e 67 5f 00 69 76 69 74 79 00 00 _imyang_.ivity..cc4fc0e0 75 8f 3e 3c 9c 5c e1 79 2d 3b 25 93 12 b6 a9 8a u.><.\.y-;%.....cc4fc0f0 40 59 ab 04 b1 7a 25 73 00 74 69 76 69 74 79 00 @Y...z%s.tivity.cc4fc100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc4fc110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc4fc120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc4fc130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc4fc140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc4fc150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc4fc160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc4fc170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc4fc180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc4fc190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

跟进sub_B940,大致分析一下函数,发现sub_11094传入了input,且有一个用于传出的参数,比较像算法函数:


int __fastcall func_B940(int outputobj, unsigned __int8 *inputobj){ int len1; // r0 int v5; // r6 int inputbuff; // r4 int len1_; // r0 int v8; // r5 int v9; // r0 int v11; // [sp+8h] [bp-30h] BYREF int len2; // [sp+Ch] [bp-2Ch] BYREF unsigned __int8 v13[12]; // [sp+10h] [bp-28h] BYREF int v14; // [sp+1Ch] [bp-1Ch] sub_B9F8(v13); len1 = getlen_BA18(inputobj); sub_BA10(v13, len1); len2 = getlen_BA18(v13); v5 = getbuff_BB44(v13); inputbuff = getbuff_BB44(inputobj); len1_ = getlen_BA18(inputobj); sub_11094(v5, (int)&len2, inputbuff, len1_, 9); v8 = sub_BB54((int)v13); v11 = sub_BB54((int)v13); v9 = sub_BCB8(&v11, len2); sub_BE1C((_DWORD *)outputobj, v8, v9); sub_BE34((int)v13); return _stack_chk_guard - v14;}

hook一下sub_011094:


var a0,a1,a2;var sub_011094 = base_libxxxxdun.add(0x11094 + 1);Interceptor.attach(sub_011094, { onEnter: function (args) { a0 = args[0]; a1 = args[1]; a2 = args[2]; console.log("sub_011094 onEnter:", hexdump(args[0])); console.log("sub_011094 onEnter:", hexdump(args[1])); console.log("sub_011094 onEnter:", hexdump(args[2])); console.log("sub_011094 onEnter:", args[3]); }, onLeave: function (ret) { //var pLeave = ptr(ret).readPointer() //console.log("sub_011094 onLeave:", hexdump(ret)); console.log("sub_011094 onLeave:", hexdump(a0)); console.log("sub_011094 onLeave:", hexdump(a1)); console.log("sub_011094 onLeave:", hexdump(a2)); }});

hook结果发现执行完毕有算法结果:


sub_011094 onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEFcc840a00 75 8f 3e 3c 9c 5c e1 79 2d 3b 25 93 12 b6 a9 8a u.><.\.y-;%.....cc840a10 40 59 ab 04 b1 7a 25 73 00 74 69 76 69 74 79 00 @Y...z%s.tivity.cc840a20 75 8f 3e 3c 9c 5c e1 79 2d 3b 25 93 12 b6 a9 8a u.><.\.y-;%.....cc840a30 40 59 ab 04 b1 7a 25 73 00 74 69 76 69 74 79 00 @Y...z%s.tivity.cc840a40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc840a50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc840a60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc840a70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc840a80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc840a90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc840aa0 00 00 00 00 34 00 00 00 00 00 00 00 00 00 00 00 ....4...........cc840ab0 00 00 00 00 51 00 00 00 00 00 14 42 00 00 00 00 ....Q......B....cc840ac0 69 6e 64 69 72 65 63 74 20 72 65 66 20 74 61 62 indirect ref tabcc840ad0 6c 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 le..............cc840ae0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cc840af0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................sub_011094 onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEFcda10ffc 18 00 00 00 21 00 00 00 18 00 00 00 00 0a 84 cc ....!...........cda1100c b1 a1 eb ac 58 79 a5 cc 90 10 a1 cd b8 91 da e9 ....Xy..........cda1101c 4c 10 a1 cd 50 07 27 e9 18 00 00 00 78 10 a1 cd L...P.'.....x...cda1102c f7 0c e5 cc 16 00 00 00 21 00 00 00 18 00 00 00 ........!.......cda1103c e0 09 84 cc 58 10 a1 cd 11 48 df d1 16 00 00 00 ....X....H......cda1104c 21 00 00 00 18 00 00 00 c0 09 84 cc b1 a1 eb ac !...............cda1105c 00 00 00 00 00 1e fd dd 88 11 a1 cd 14 11 a1 cd ................cda1106c 44 c0 e0 eb 02 00 00 00 00 00 00 00 a8 12 a1 cd D...............cda1107c 77 00 fe cc 44 c0 e0 eb 00 00 00 00 02 00 00 00 w...D...........cda1108c 98 21 dc 13 c0 a8 90 13 01 00 00 00 60 a9 26 cc .!..........`.&.cda1109c 01 00 00 00 24 fa 00 00 00 00 00 00 00 00 00 00 ....$...........cda110ac 00 00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 00 .......?........cda110bc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cda110cc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................cda110dc 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................cda110ec a8 12 a1 cd 00 00 00 00 88 11 a1 cd 14 11 a1 cd ................sub_011094 onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEFcc8409e0 65 6c 44 49 6b 62 61 4b 69 74 5f 70 65 64 69 79 elDIkbaKit_pediycc8409f0 5f 69 6d 79 61 6e 67 5f 00 69 76 69 74 79 00 00 _imyang_.ivity..cc840a00 75 8f 3e 3c 9c 5c e1 79 2d 3b 25 93 12 b6 a9 8a u.><.\.y-;%.....758f3e3c9c5ce1792d3b259312b6a98a4059ab04b17a2573

跟进sub_011094,发现混淆比较严重,trace一下试试。



由trace逆出一轮中间值以及怎样算出最终结果的:



void func(){//最终结果// CC840A00 75 8F 3E 3C 9C 5C E1 79 2D 3B 25 93 12 B6 A9 8A u.><.\...;%.....// CC840A10 40 59 AB 04 B1 7A 25 73 00 74 69 76 69 74 79 00 @Y...z%s.tivity. char input[0x19] = {0x65, 0x6c, 0x44, 0x49, 0x6b, 0x62, 0x61, 0x4b, 0x69, 0x74, 0x5f, 0x70, 0x65, 0x64, 0x69, 0x79, 0x5f, 0x69, 0x6d, 0x79, 0x61, 0x6e, 0x67, 0x5f, 0x00}; char output[0x64] = {0}; //中间结果,猜测是由input转换而得// CC840A00 78 DA 4B CD 71 F1 CC 4E 4A F4 CE 2C 89 2F 48 4D x............/HM// CC840A10 C9 AC 8C CF CC AD 4C CC 00 74 69 76 69 74 79 00 ɬ ....L..tivity. char temp[0x64] = {0x78, 0xDA, 0x4B, 0xCD, 0x71, 0xF1, 0xCC, 0x4E, 0x4A, 0xF4, 0xCE, 0x2C, 0x89, 0x2F, 0x48, 0x4D, 0xC9, 0xAC, 0x8C, 0xCF, 0xCC, 0xAD, 0x4C, 0xCC }; //中间结果转为最终结果的算法: for(int i = 2; i < strlen(temp); i++){ int v94 = ((temp[i] & 0x64) + (~temp[i] & 0x9B)) ^ (((2 * output[i-1] + 117) & 0x64) + (~(2 * output[i-1] + 117) & 0x9B)); output[i] = v94; LOGI("v94 = : %0x\n", v94); } //前两个字节是定值 output[0] = 0x75; output[1] = 0x8f;}}

追溯中间结果是怎么生成的。



调试发现这个关键赋值位置的BLX R2,实际调用了sub_257F4:



.text:0001CC84 loc_1CC84 ; CODE XREF: sub_18D48+E86↑j.text:0001CC84 LDR R1, [SP,#0x238+var_88].text:0001CC86 LDR R2, =(unk_79230 - 0x1CC92).text:0001CC88 LDR R0, [SP,#0x238+var_174].text:0001CC8A ADD.W R1, R1, R1,LSL#1.text:0001CC8E ADD R2, PC ; unk_79230.text:0001CC90 ADD.W R1, R2, R1,LSL#2.text:0001CC94 LDR R2, [R1,#8].text:0001CC96 LDR R1, [SP,#0x238+var_194].text:0001CC98 BLX R2 ; 调用0x257F4

跟进sub_257F4,找到sub_1ECFC,跟进sub_1ECFC,从memcpy往上追溯。根据memcpy的参数来源:


struct { char nop[28]; obj* ptr;} struct obj { char nop[16]; char* outTmp;}

由此hook查看其中间结果:


var sub_01ECFC = base_libxxxxdun.add(0x1ECFC + 1);Interceptor.attach(sub_01ECFC, { onEnter: function (args) { arg0 = args[0]; //console.log("sub_01ECFC onEnter:", hexdump(ptr(arg0).add(28))); var addTmp = (ptr(arg0).add(28)).readPointer(); //console.log("sub_01ECFC onEnter:", hexdump(addTmp)); var addResult = ptr(addTmp).add(16).readPointer(); console.log("sub_01ECFC onEnter:", hexdump(addResult)); }, onLeave: function (ret) { }});

得到结果:


sub_01ECFC onEnter: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEFd65df440 78 da 71 f1 cc 4e 4a f4 ce 2c 89 2f 48 4d c9 ac x.q..NJ..,./HM..d65df450 8c cf cc ad 4c cc 4b 8f 07 00 00 00 00 00 00 00 ....L.K.........d65df460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................sub_01ECFC onEnter: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEFd65df440 4b cd 71 f1 cc 4e 4a f4 ce 2c 89 2f 48 4d c9 ac K.q..NJ..,./HM..d65df450 8c cf cc ad 4c cc 4b 8f 07 00 00 00 00 00 00 00 ....L.K.........d65df460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

sub_1ECFC调用了两次,第二次调用时结果已经生成了,故而往上追溯sub_257F4。追溯参数来源按照同样的格式进行hook:


var sub_0257F4 = base_libxxxxdun.add(0x257F4 + 1);Interceptor.attach(sub_0257F4, { onEnter: function (args) { arg0 = args[0]; //console.log("sub_0257F4 onEnter:", hexdump(arg0)); arg0 = arg0.readPointer(); //console.log("sub_0257F4 onEnter:", hexdump(arg0)); var addTmp = (ptr(arg0).add(28)).readPointer(); var addResult = ptr(addTmp).add(16).readPointer(); console.log("sub_0257F4 onEnter:", hexdump(addResult)); }, onLeave: function (ret) { var addTmp = (ptr(arg0).add(28)).readPointer(); var addResult = ptr(addTmp).add(16).readPointer(); console.log("sub_0257F4 onLeave:", hexdump(addResult)); }});

得到的是一个初始结果:


sub_0257F4 onEnter: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEFd65df440 78 da 71 f1 cc 4e 4a f4 ce 2c 89 2f 48 4d c9 ac x.q..NJ..,./HM..d65df450 8c cf cc ad 4c cc 4b 8f 07 00 00 00 00 00 00 00 ....L.K.........d65df460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................


搜索sub_257F4里调用sub_1ECFC的位置,发现全部是类似这样的BB:


v2 = a1;v172 = a1;...sub_566B4(v2, input_, *v208 - *v215, 0);*v215 = *v208;sub_1ECFC(*v172);

于是尝试按照结构体格式hook sub_566B4 打印结果:


var sub_0566B4 = base_libxxxxdun.add(0x566B4 + 1);Interceptor.attach(sub_0566B4, { onEnter: function (args) { arg0 = args[0]; arg0 = arg0.readPointer(); //console.log("sub_0566B4 onEnter:", hexdump(arg0)); var addTmp = (ptr(arg0).add(28)).readPointer(); var addResult = ptr(addTmp).add(16).readPointer(); console.log("sub_0566B4 onEnter:", hexdump(addResult)); // console.log("sub_0566B4 onEnter:", hexdump(args[1])); //inputbuff // console.log("sub_0566B4 onEnter:", args[2]); // console.log("sub_0566B4 onEnter:", args[3]); }, onLeave: function (ret) { var addTmp = (ptr(arg0).add(28)).readPointer(); var addResult = ptr(addTmp).add(16).readPointer(); console.log("sub_0566B4 onLeave:", hexdump(addResult)); }});


得到结果:


sub_0566B4 onEnter: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEFd65df440 78 da 71 f1 cc 4e 4a f4 ce 2c 89 2f 48 4d c9 ac x.q..NJ..,./HM..d65df450 8c cf cc ad 4c cc 4b 8f 07 00 00 00 00 00 00 00 ....L.K.........d65df460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................sub_0566B4 onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEFd65df440 4b cd 71 f1 cc 4e 4a f4 ce 2c 89 2f 48 4d c9 ac K.q..NJ..,./HM..d65df450 8c cf cc ad 4c cc 4b 8f 07 00 00 00 00 00 00 00 ....L.K.........d65df460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................


调试该函数,得到sub_5A6DC函数,在此处赋值:


.text:0005B2E2 ADD R6, R12.text:0005B2E4 STR R6, [R0,#0x14].text:0005B2E6 STRB R2, [R4,R5]

trace一下sub_5A6DC,得到算法全貌:


int ary[] = { 0x8000C, 0x8008C, 0x8004C, 0x800CC, 0x8002C, 0x800AC, 0x8006C, 0x800EC, 0x8001C, 0x8009C, 0x8005C, 0x800DC, 0x8003C, 0x800BC, 0x8007C, 0x800FC, 0x80002, 0x80082, 0x80042, 0x800C2, 0x80022, 0x800A2, 0x80062, 0x800E2, 0x80012, 0x80092, 0x80052, 0x800D2, 0x80032, 0x800B2, 0x80072, 0x800F2, 0x8000A, 0x8008A, 0x8004A, 0x800CA, 0x8002A, 0x800AA, 0x8006A, 0x800EA, 0x8001A, 0x8009A, 0x8005A, 0x800DA, 0x8003A, 0x800BA, 0x8007A, 0x800FA, 0x80006, 0x80086, 0x80046, 0x800C6, 0x80026, 0x800A6, 0x80066, 0x800E6, 0x80016, 0x80096, 0x80056, 0x800D6, 0x80036, 0x800B6, 0x80076, 0x800F6, 0x8000E, 0x8008E, 0x8004E, 0x800CE, 0x8002E, 0x800AE, 0x8006E, 0x800EE, 0x8001E, 0x8009E, 0x8005E, 0x800DE, 0x8003E, 0x800BE, 0x8007E, 0x800FE, 0x80001, 0x80081, 0x80041, 0x800C1, 0x80021, 0x800A1, 0x80061, 0x800E1, 0x80011, 0x80091, 0x80051, 0x800D1, 0x80031, 0x800B1, 0x80071, 0x800F1, 0x80009, 0x80089, 0x80049, 0x800C9, 0x80029, 0x800A9, 0x80069, 0x800E9, 0x80019, 0x80099, 0x80059, 0x800D9, 0x80039, 0x800B9, 0x80079, 0x800F9, 0x80005, 0x80085, 0x80045, 0x800C5, 0x80025, 0x800A5, 0x80065, 0x800E5, 0x80015, 0x80095, 0x80055, 0x800D5, 0x80035, 0x800B5, 0x80075, 0x800F5, 0x8000D, 0x8008D, 0x8004D, 0x800CD, 0x8002D, 0x800AD, 0x8006D, 0x800ED, 0x8001D, 0x8009D, 0x8005D, 0x800DD, 0x8003D, 0x800BD, 0x8007D, 0x800FD, 0x90013, 0x90113, 0x90093, 0x90193, 0x90053, 0x90153, 0x900D3, 0x901D3, 0x90033, 0x90133, 0x900B3, 0x901B3, 0x90073, 0x90173, 0x900F3, 0x901F3, 0x9000B, 0x9010B, 0x9008B, 0x9018B, 0x9004B, 0x9014B, 0x900CB, 0x901CB, 0x9002B, 0x9012B, 0x900AB, 0x901AB, 0x9006B, 0x9016B, 0x900EB, 0x901EB, 0x9001B, 0x9011B, 0x9009B, 0x9019B, 0x9005B, 0x9015B, 0x900DB, 0x901DB, 0x9003B, 0x9013B, 0x900BB, 0x901BB, 0x9007B, 0x9017B, 0x900FB, 0x901FB, 0x90007, 0x90107, 0x90087, 0x90187, 0x90047, 0x90147, 0x900C7, 0x901C7, 0x90027, 0x90127, 0x900A7, 0x901A7, 0x90067, 0x90167, 0x900E7, 0x901E7, 0x90017, 0x90117, 0x90097, 0x90197, 0x90057, 0x90157, 0x900D7, 0x901D7, 0x90037, 0x90137, 0x900B7, 0x901B7, 0x90077, 0x90177, 0x900F7, 0x901F7, 0x9000F, 0x9010F, 0x9008F, 0x9018F, 0x9004F, 0x9014F, 0x900CF, 0x901CF, 0x9002F, 0x9012F, 0x900AF, 0x901AF, 0x9006F, 0x9016F, 0x900EF, 0x901EF, 0x9001F, 0x9011F, 0x9009F, 0x9019F, 0x9005F, 0x9015F, 0x900DF, 0x901DF, 0x9003F, 0x9013F, 0x900BF, 0x901BF, 0x9007F, 0x9017F, 0x900FF, 0x901FF, 0x70000, 0x70040, 0x70020, 0x70060, 0x70010, 0x70050, 0x70030, 0x70070, 0x70008, 0x70048, 0x70028, 0x70068, 0x70018, 0x70058, 0x70038, 0x70078, 0x70004, 0x70044, 0x70024, 0x70064, 0x70014, 0x70054, 0x70034, 0x70074, 0x80003, 0x80083, 0x80043, 0x800C3, 0x80023, 0x800A3, 0x80063, 0x800E3, 0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000C, 0x5001C, 0x50002, 0x50012, 0x5000A, 0x5001A, 0x50006, 0x50016, 0x5000E, 0x5001E, 0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000D, 0x5001D, 0x50003, 0x50013, 0x5000B, 0x5001B, 0x50007, 0x50017};void test() {// 最终结果// CC840A00 75 8F 3E 3C 9C 5C E1 79 2D 3B 25 93 12 B6 A9 8A u.><.\...;%.....// CC840A10 40 59 AB 04 B1 7A 25 73 00 74 69 76 69 74 79 00 @Y...z%s.tivity. char input[0x19] = {0x65, 0x6c, 0x44, 0x49, 0x6b, 0x62, 0x61, 0x4b, 0x69, 0x74, 0x5f, 0x70, 0x65, 0x64, 0x69, 0x79, 0x5f, 0x69, 0x6d, 0x79, 0x61, 0x6e, 0x67, 0x5f, 0x00}; //char input[0x19] = {0x6a,0x6b,0x4c,0x4d,0x6e,0x6f,0x60,0x41,0x62,0x73,0x54,0x75,0x66,0x67,0x68,0x79,0x5a,0x6b,0x6c,0x7d,0x6e,0x6f,0x60,0x51}; char output[0x64] = {0}; // d65df440 4b cd 71 f1 cc 4e 4a f4 ce 2c 89 2f 48 4d c9 ac K.q..NJ..,./HM..// d65df450 8c cf cc ad 4c cc 4b 8f 07 00 00 00 00 00 00 00 ....L.K......... unsigned char inputTmp[0x19] = {0x78, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; int i = 0; for(int i = 0; i<strlen(input); i = i+2) { unsigned short* tbTmp = (unsigned short*)&ary[input[i]]; unsigned short t1 = tbTmp[0]; unsigned short t2 = tbTmp[1]; unsigned int v10 = 0; // ???? unsigned int v18 = 0x0003; //????? unsigned int v115 = t1; //取表下面 D489ABE6 unsigned int v110 = t2; if(i - 1 >= 0) { tbTmp = (unsigned short*)&ary[input[i - 1]]; t1 = tbTmp[0]; t2 = tbTmp[1]; } unsigned int v15 = t1; unsigned int v19 = i - 1 >= 0 ? (v15 >> (16 - (v110 + v18))) : 0x3; //D489A6DC+C32 unsigned int v109 = ((v115 << v18) & v10 | v10 ^ (v115 << v18))^v19; //D489B10C tbTmp = (unsigned short*)&ary[input[i + 1]]; t1 = tbTmp[0]; t2 = tbTmp[1]; unsigned short v116 = t2; //取表上面 0x008 D489ABFC unsigned int v63 = 0x0003; //D489B31E ?????? unsigned int v118 = v63 + v116; //0x000B D489B118 unsigned int v70 = t1; //取表下面 unsigned int v71 = (v70 << v118) & v109 | v109 ^ (v70 << v118); //D489B2D4 tbTmp = (unsigned short*)&v71; t1 = tbTmp[0]; t2 = tbTmp[1]; LOGI("xxxxxxxTmp %0x %0x", t1, t2); memcpy(inputTmp + i + 2, &t1, 2); } for(int i = 0; i<strlen(input); i++) { LOGI("xxxxxxx %0x", inputTmp[i]); } // CC840A00 78 DA 4B CD 71 F1 CC 4E 4A F4 CE 2C 89 2F 48 4D x............/HM// CC840A10 C9 AC 8C CF CC AD 4C CC 00 74 69 76 69 74 79 00 ɬ ....L..tivity.// unsigned char temp[0x64] = {0x78, 0xDA, 0x4B, 0xCD, 0x71, 0xF1, 0xCC, 0x4E, 0x4A, 0xF4, 0xCE, 0x2C, 0x89, 0x2F, 0x48, 0x4D, 0xC9, 0xAC, 0x8C, 0xCF, 0xCC, 0xAD, 0x4C, 0xCC}; for(int i = 2; i < 0x18; i++){ int v94 = ((inputTmp[i] & 0x64) + (~inputTmp[i] & 0x9B)) ^ (((2 * output[i-1] + 117) & 0x64) + (~(2 * output[i-1] + 117) & 0x9B)); output[i] = v94; LOGI("v94 = : %0x\n", v94); } output[0] = 0x75; output[1] = 0x8f;}



- End -


看雪ID:咸鱼炒白菜

https://bbs.pediy.com/user-home-752228.htm

  *本文由看雪论坛 咸鱼炒白菜 原创,转载请注明来自看雪社区。



推荐文章++++

* Linux Kernel Pwn_1_Double fetch

Linux Kernel Pwn_0_kernel ROP与驱动调试

* 使用Frida分析动态注册jni函数绑定流程

* OneFuzz踩坑教程

* 最右sign-v2签名算法追踪及逆向还原






公众号ID:ikanxue
官方微博:看雪安全商务合作:wsc@kanxue.com



求分享

求点赞

求在看


“阅读原文”一起来充电吧!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存