Android安卓破解之逆向分析SO常用的IDA分析技巧

1、结构体的创建及导入,结构体指针等。

以JniNativeInterface, DexHeader为例。

解析Dex的函数如下:

F5后如下:

File->load file->parser c header file,导入Dex.h

上图中a1,右键转成结构体,选择dexheader,效果如下:

由于doCommandNative是thumb的函数,所以在0x9fa53cfc, 按alt+g,改为1

按 c, 把数据转为代码

2、函数指针时的参数个数调整,不定参数等。

以__android_log_print为例,选中该函数。

Edit->operand type-> set operand type,修改参数如下:

int (__cdecl *)(int, char *, char *, char *, int *, int *),F5刷新后,效果如下:

 

 

3、thumb/arm模式的转换

快捷键ALT +G,其中0x01是THUMB,0x00是ARM模式。一般4个字节ARM模式,两个字节为THUMB模式,如:

 

4、函数被误认为chunk,导致调用者函数多个入口。

以Java_by_Ericky_crackme01_JNI_EatRice为例,可以看到有两个入口。

来到第一个入口的结束位置为BX跳转指令, 应该让他跳转到第二个入口出,才正确。

所有首先要remove function tail,

选中,结尾处,然后edit->functions->remove function tail,效果:

然后再将跳转指令BL,修改为Call,edit->others->force bl call,效果

5、C++RTTI,类名识别。

来的 JNI_OnLoad处

sub_A558为构造函数。

可以得在该函数名为9ArtLoader,

 

6、创建函数,设定函数结尾地址。

F5,效果如下:

解决办法,按P,再F5。如果P没有效果,则可以选中后再按P。

7、Elf的修复,内存dump该so及其以来文件,然后修改dump出来的基址,File-->LoadFile-->binary file。

dump命令为:

dd if=/proc/1935/mem of=/sdcard/alimsc4 skip=1578049536 ibs=1 count=3993600

8、数据复制、patch。

选中数据,然后edit->export data,即可

9、脚本,idc,IDAPython

http://magiclantern.wikia.com/wiki/IDAPython/intro

http://drops.wooyun.org/tips/11849

http://drops.wooyun.org/tips/12060

 

10、lsof查看被删除的文件,cat从内存中得到被删除的文件

root@android:/ # lsof |busybox grep com.sxiaoao.car3d3

system_se 523 system 298 /data/app/com.sxiaoao.car3d3-2.apk

com.sxiao 10370 u0_a65 44 /data/data/com.sxiaoao.car3d3/files/app_sdk103700_.jar (deleted)

com.sxiao 10370 u0_a65 48 /data/app/com.sxiaoao.car3d3-2.apk

com.sxiao 10370 u0_a65 49 /data/app/com.sxiaoao.car3d3-2.apk

 

10370是进程号 44是打开文件的fd 文件fd映射在/prop/pid/fd里面

用cat命令把文件拷贝出来

1|root@android:/ # cat /proc/10370/fd/44 > /data/local/tmp/test.jar

 

11、arm指令模拟器

 

12、为什么不能F5, 不能全信F5

http://blog.csdn.net/asmcvc/article/details/51026030

关于IDA使用的几个技巧(收集)

1.IDA反编译生成c代码时,有时会出现sp-analysis failed错误。这一般是由于IDA分析某个外部函数call时出现了堆栈指针调整错误。可以先设置菜单option->General->Disassembly选中stack pointer.然后逐行看看哪些调用前后堆栈出现了偏差。
2.IDA可以通过定义struct/enum来增强生成C代码的可读性。但有时候在分析一个程序时定义的结构在另一个文件中也可能有用。这时怎样处理呢。答案是先导出,再导入。
结构体的导出可参见http://bbs.pediy.com/showthread.php?t=99931
导入比较简单,通过“菜单Load file/Parse C header file”直接导入头文件。导入成功后,在Structures里就可以insert,然后Add standard structure中去查找了。导入之后在local types可见,而后全选右键同步即可。
结构体导出的代码保存在这里,便于查阅。

 

#include "idc.idc"
static Save2HStart(ofile)
{
    writestr(ofile,"/***************************************************************************************\n");
    writestr(ofile,"本程序用来导出结构体.并且暂时支持BYTE,WORD,DWORD和结构体。其他的类型被转换成BYTE数组.\n");    
    writestr(ofile,"如需支持其他的数据类型请自己在函数Save2HAddItem内加入.\n");
    writestr(ofile,"                                                        Author   GUANRI\n");
    writestr(ofile,"                                                        2009年11月8日\n");    
    writestr(ofile,"****************************************************************************************/\n");
  writestr(ofile,"#include \"stdafx.h\"\n");
  writestr(ofile,"#include \"windows.h\"\n");
  writestr(ofile,"#ifndef _WRITE_BY_GRUANRI_\n");
  writestr(ofile,"#define _WRITE_BY_GRUANRI_\n");
}
static Save2HEnd(ofile)
{
    writestr(ofile,"#endif");
}
static Save2HAddItem(ofile,id,add)
{
    auto type,itemsize,MemName;
    type = GetMemberFlag(id,add) & DT_TYPE;
              if ( type == FF_BYTE     ) 
                  {
                  type = "BYTE";
                  itemsize=GetMemberSize(id,add);
                  }
                    else if ( type == FF_WORD     ) 
                    {
                        type = "WORD";
                        itemsize=GetMemberSize(id,add)/2;
                    }
                    else if ( type == FF_DWRD     ) 
                    {
                        type = "DWORD";
                        itemsize=GetMemberSize(id,add)/4;
                    }
                    else if ( type == FF_DWRD     ) 
                    {
                        type = "DWORD";
                        itemsize=GetMemberSize(id,add)/4;
                    }
                    else if ( type == FF_STRU     ) 
                    {
                        type = GetStrucName(GetMemberStrId(id,add));
                        itemsize=GetMemberSize(id,add)/GetStrucSize(GetMemberStrId(id,add));
                    }
                    else 
                        {
                          type = "BYTE";
                      itemsize=GetMemberSize(id,add);
                        }
    MemName=GetMemberName(id,add);
    if(MemName=="")
        {
            return;
        }                        
    writestr(ofile,"                  "+type+"   "+MemName);
    if(itemsize!=1)
    {
       writestr(ofile,"["+ltoa(itemsize,10)+"];\n");
    }
    else
    {
        writestr(ofile,";\n");
    }
}
static Save2HAddItems(ofile,id)
{
    auto add,MemName;
    for ( add= 0;(add!=GetStrucSize(id))&&(add!=-1);add=GetStrucNextOff(id,add) ) 
    {
        MemName=GetMemberName(id,add);

      if (strstr(MemName,"::")==-1) 
          {
            Save2HAddItem(ofile,id,add);
          } 
          else
          {
              return;
          }

          
    }
}
static Save2HStruct(ofile,id)
{
    auto structname;
    structname=GetStrucName(id);
    writestr(ofile,"/***************************************************************************************\n");
    writestr(ofile,"结构体名称:"+GetStrucName(id)+"\n");
    writestr(ofile,"固定  注释:"+GetStrucComment(id,0)+"\n");
    writestr(ofile,"重复  注释:"+GetStrucComment(id,1)+"\n");
    writestr(ofile,"结构体大小:"+ltoa(GetStrucSize(id),10)+"\n");
    writestr(ofile,"成员  个数:"+ltoa(GetMemberQty(id),10)+"\n");
    writestr(ofile,"****************************************************************************************/\n");
    writestr(ofile,"typedef struct \n");
    writestr(ofile,"                {\n");
    Save2HAddItems(ofile,id);
    writestr(ofile,"                }"+structname+",*p"+structname+";\n");
}
static main()
{
    auto file,filename,idx,id,structname;
    filename=AskFile(1,"*.h","保存头文件名");
    if(filename==0)
        {
            Warning("请输入一个文件名,谢谢!!!!!!");
      return;
        }
    file=fopen(filename,"w+");
    Message("写入中"+filename+"\n");
    Save2HStart(file);

    for ( idx=GetFirstStrucIdx(); idx != -1; idx=GetNextStrucIdx(idx) ) 
  {
      id=GetStrucId(idx);
       structname=GetStrucName(id);

      if(strstr(structname,"::")==-1)  //这个是过滤结构名带::的
          {
                Save2HStruct(file,id);
                Message("结构名:  "+structname+"\n");
            }
  }
    Save2HEnd(file);
    fclose(file);
}

http://www.cppblog.com/huyutian/articles/102223.html

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值