-
-
[原创]2w班8月份第二题hook init_array中函数解密ollvm加密字符串
-
发表于: 2020-12-19 12:03 2730
-
前言
这是2W班8月份的练习题。题目要求是:
ollvm针对加密字符串的解密都是在位于init_array节当中的函数。请编写Xposed插件,完成对测试apk中位于init_array节中的函数的hook,并获取对应的解密后的字符串。
思路:刚刚开始只是为了解题怎么方便怎么来,app是32位的,所以在android 6下 使用这个支持32位的hook库,https://github.com/ele7enxxh/Android-Inline-Hook ,在加载Xposed的时候动态载入libnative-lib.so ,然后对init_array中的函数进行hook,在进行主动调用,打印关键字符串。
解题过程
1.ida载入libnative-lib.so,简单看了下
有静态注册的shell函数,猜想是这个方法sub_87c4里的一个比较,点击进入看看,byte_1B008= v2从一个地址1b008取值跟a1来比较,字符长度为5,重命名mystr.
2.点击看看byte_1b008,【0x9F, 0x94, 0x99, 0x9F, 0x97, 0xFC, 0, 0】,交叉引用看下,发现解密在datadiv_decode9080531325931451386这个里面, byte_1B008[v11++] ^= 0xFCu; 这样一个异或,计算一下看看,其实已经看到check了
3.继续分析,去.init_array,有2个函数,一个解密的.datadiv_decode,一个里面有对byte_1b008进行参数传值的方法.
4.这步解密字符串在调用sub_85e4,是不是hook它打印第一个参数就能得到我们要的结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | unsigned long base = NULL; Dl_info dlinfo; __attribute__ ((visibility ( "hidden" ))) void hookMyGetstr() { void * handle = dlopen_compat( "libnative-lib.so" , RTLD_NOW); if (handle ! = nullptr) { __android_log_print( 4 , "test02" , "libnative-lib.so handle is not nullptr" ); void * temp = dlsym_compat(handle, "Java_com_kanxue_hookinit_1array_MainActivity_Shell" ); int rc = dladdr(temp,&dlinfo); if (dlinfo.dli_fbase! = nullptr){ base = reinterpret_cast<unsigned long >(dlinfo.dli_fbase); } } / / unsigned long mtem = findBaseOff( "libnative-lib.so" ); if (base> 0L ){ / / unsigned long func_addr = base + 0x85E4 + 1 ; unsigned long func_addr = base + 0x85E4 + 1 ; if (ELE7EN_OK = = registerInlineHook((uint32_t) func_addr, (uint32_t) mygetstr, (uint32_t * * ) &getstr)) { if (ELE7EN_OK = = inlineHook((uint32_t) func_addr)) { __android_log_print( 4 , "XposedFART" , "inlineHook getstr success" ); } else { __android_log_print( 4 , "XposedFART" , "inlineHook getstr failure" ); } } } else { LOGD( "NOT FOUND THE BASE .SO" ); } } |
使用dlsym_compat的时候不确定能不能找到需要hook的函数地址,所以我先dlsym_compat有导出函数名的Java_com_kanxue_hookinit_1array_MainActivity_Shell得到基址手动计算函数偏移,thumb模式,,所以需要+1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | void * ( * getstr)(void * , void * , void * ) = nullptr; void * mygetstr(void * str , void * size, void * c){ char * tempStr = (char * ) str ; __android_log_print( 4 , "XposedFART" , "getOriArgsStr:%s" ,tempStr); void * result = getstr( str , size, c); __android_log_print( 4 , "XposedFART" , "getResultStr:%s" ,(char * )result); return result; } void zhudongmyGetstry(){ typedef void * ( * xxtest)(); if (base> 0L ){ / / 随便对一个有执行了hook方法的调用 xxtest xxtestfucnc = reinterpret_cast<xxtest>(base + 0x876C + 1 ); xxtestfucnc(); __android_log_print( 4 , "XposedFART" , "call xxtestfucnc" ); } } extern "C" void _init(void) { __android_log_print( 4 , "XposedFART" , "go into _init" ); hookMyGetstr(); zhudongmyGetstry(); } |
5.到处hook模块差不多了,传到手机,Xposed加载验证
打印出来了
整个过程还是比较简单的,小菜鸟一枚有什么错误的地方,欢迎指出,特别感谢r0ysue,寒冰老师~~~
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!