zoukankan      html  css  js  c++  java
  • 一个简单的 IDA f5插件问题分析

    有人提出问题,以下汇编f5结果缺失代码:

    .text:00000C18 Java_com_a_b_c
    .text:00000C18                 PUSH    {R3,LR}
    .text:00000C1A                 CMP     R2, #2
    .text:00000C1C                 BEQ     loc_C38
    .text:00000C1E                 CMP     R2, #3
    .text:00000C20                 BEQ     loc_C2C
    .text:00000C22                 CMP     R2, #1
    .text:00000C24                 BNE     loc_C32
    .text:00000C26                 LDR     R1, =(aGoldVip - 0xC2C)
    .text:00000C28                 ADD     R1, PC          ; "Gold Vip"
    .text:00000C2A                 B       loc_C3C
    .text:00000C2C ; ---------------------------------------------------------------------------
    .text:00000C2C
    .text:00000C2C loc_C2C                                 ; CODE XREF: Java_com_a_b_c+8 j
    .text:00000C2C                 LDR     R1, =(aCopperVip - 0xC32)
    .text:00000C2E                 ADD     R1, PC          ; "Copper Vip"
    .text:00000C30                 B       loc_C3C
    .text:00000C32 ; ---------------------------------------------------------------------------
    .text:00000C32
    .text:00000C32 loc_C32                                 ; CODE XREF: Java_com_a_b_c+C j
    .text:00000C32                 LDR     R1, =(aNormalUser - 0xC38)
    .text:00000C34                 ADD     R1, PC          ; "Normal User"
    .text:00000C36                 B       loc_C3C
    .text:00000C38 ; ---------------------------------------------------------------------------
    .text:00000C38
    .text:00000C38 loc_C38                                 ; CODE XREF: Java_com_a_b_c+4 j
    .text:00000C38                 LDR     R1, =(aSilveryVip - 0xC3E)
    .text:00000C3A                 ADD     R1, PC          ; "Silvery Vip"
    .text:00000C3C
    .text:00000C3C loc_C3C                                 ; CODE XREF: Java_com_a_b_c+12 j
    .text:00000C3C                                         ; Java_com_a_b_c+18 j ...
    .text:00000C3C                 LDR     R2, [R0]
    .text:00000C3E                 MOVS    R3, #0x29C
    .text:00000C42                 LDR     R3, [R2,R3]
    .text:00000C44                 BLX     R3              ; NewStringUTF
    .text:00000C46                 POP     {R3,PC}
    .text:00000C46 ; End of function Java_com_a_b_c
    

    很容易从汇编看出,这是个简单的 switch…case{} 代码块。在break时,跳转到 loc_C3C 处。

    但f5,其结果如下,明显代码缺失:

    int __fastcall Java_com_a_b_c(int a1)
    {
      return (*(int (**)(void))(*(_DWORD *)a1 + 668))();
    }
    

    下面分析,为什么代码缺失。

    由于 Java_com_a_b_c 是一个 jni 函数,所以 r0 为 JNIEnv*, r1 为 jobject。loc_C3C 位置有个blx r3的跳转,分析一下这是个什么调用。

    首选将 r0 指向地址内容即 JNIEnv 赋值 r2,接着 ldr r3, [r2, r3] 将 r3 指向 JNIEnv + 0x29c 偏移的位置(JNINativeInterface 中第167个函数)。

    通过查看 jni.h,此时 r3 实际指向的是 NewStringUTF 函数,这个函数有2个变量,分别是 r0:JNIEnv* 和 r1:char* 。其返回值是一个jstring类型。

    也就是上面汇编代码大致伪C是这样:

    jstring Java_com_a_b_c(JNIEnv *env, jobject thiz, jint x)  {
            char *str = NULL;
            switch(x) {
                    case 1:
                            str = "Gold Vip";
                            break;
                    case 2:
                            str = "Silvery Vip";
                            break;
                    case 3:
                            str = "Copper Vip";
                            break;
                    default:
                            str = "Normal User";
                            break;
            }
            return (*env)->NewStringUTF(env, str);
    }
    

    switch…case {} 结构去哪儿了? 其实这是ida f5插件的一个特性:***代码优化***。由于使用了 blx r3寄存器跳转,ida并不知道r3即NewStringUTF函数的原型,参数情况。也就不知道str参数会被NewStringUTF函数所使用。因此它认为switch…case {}中对str的赋值(如str = “Copper Vip”;)并没有用,可以优化掉。

    因此f5就找不到这段汇编对应的C了。

    验证一下f5是否存在代码优化(与-O3编译选项类似):

    kiiim@ubuntu:~/Android_prj/re/jni_test$ cat test.c 
    int main()
    {
            int x = a();
    }
    int a()
    {
            int a = 123;
            int b = 22;
    
            return 123;
    }
    

    对应汇编:

    .text:00008304                 EXPORT a
    .text:00008304 a                                       ; CODE XREF: main+C p
    .text:00008304
    .text:00008304 var_C           = -0xC
    .text:00008304 var_8           = -8
    .text:00008304 var_s0          =  0
    .text:00008304
    .text:00008304                 STR     R11, [SP,#-4+var_s0]!
    .text:00008308                 ADD     R11, SP, #0
    .text:0000830C                 SUB     SP, SP, #0xC
    .text:00008310                 MOV     R3, #0x7B    #### int a = 123;
    .text:00008314                 STR     R3, [R11,#var_8]
    .text:00008318                 MOV     R3, #0x16        ### int b = 22; 明显存在2个变量赋值代码
    .text:0000831C                 STR     R3, [R11,#var_C]
    .text:00008320                 MOV     R3, #0x7B
    .text:00008324                 MOV     R0, R3
    .text:00008328                 SUB     SP, R11, #0
    .text:0000832C                 LDR     R11, [SP+var_s0],#4
    .text:00008330                 BX      LR
    .text:00008330 ; End of function a
    

    f5:

    signed int a()
    {
      return 123;
    }
    

    那怎么办呢?其实很简单,首先导入 JNINativeInterface 结构的函数原型信息。然后在f5窗口里面, 重新设置 NewStringUTF 函数参数。

    在函数上右键 ,*** Force call type ***:

  • 相关阅读:
    JavaSE--注解
    JavaSE--【JAVA】unicode为12288字符
    Spring--Spring 注入
    Spring--@configuration 和 @Bean
    JavaEE--分布式对象
    JavaSE--jdom解析之bom
    JavaEE--分布式与集群
    JavaEE--调用 WSDL -- httpclient 4.x.x
    JavaSE--RMI初识
    Redis--初识Redis
  • 原文地址:https://www.cnblogs.com/gm-201705/p/9863956.html
Copyright © 2011-2022 走看看