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