首页
社区
课程
招聘
[求助]关于dex中的大端小端问题
发表于: 2013-11-28 00:48 5992

[求助]关于dex中的大端小端问题

2013-11-28 00:48
5992
在看这篇文章 【翻译】Android DEX安全攻防战 的时候,发现里面有提到
 7、大端小端反转理论
        当前还没有Android逆向工具实现DEX文件端反转(也许IDA支持)。
        Dalvik虚拟机在DEX优化过程中会检测DEX端模式是否适合当前设备,如果不适合会反转DEX文件端模式。
        我们需要做的是变换DEX文件所有字节端结构,反转后的DEX文件可以中断逆向工具但是仍然可以在设备上运行。
        这种攻击方式理论上是可行的。我们可以参考Android源代码实现端的反转,具体代码位于/dalvik2/libdex/dexSwapAndVerify.cpp


作为一个初学者,我有很多不明白,所以只能在这里向大家求助了。如果大家能够给我一点提示,我真是感激不尽。

一般地,我们通过exlipse打包出来的dex文件头中endianTag字段为0x12345678,即小端。
dalvik在安装apk的时候会调用dexSwapAndVerifyIfNecessary来验证dex文件并调整字节序。

在DexSwapVerify.cpp这个文件中有这样的宏定义:
#if __BYTE_ORDER == __LITTLE_ENDIAN
# define SWAP2(_value)      (_value)
# define SWAP4(_value)      (_value)
# define SWAP8(_value)      (_value)
#else
# define SWAP2(_value)      endianSwapU2((_value))
# define SWAP4(_value)      endianSwapU4((_value))
# define SWAP8(_value)      endianSwapU8((_value))

__BYTE_ORDER对应不同的平台应该是不同的定义,或者_LITTLE_ENDIAN或者_BIG_ENDIAN。所以它在不同端序的手机里应该是不一样的,所以只有当__BYTE_ORDER__为_BIG_ENDIAN时才会交换字节序吗?

在DexSwapVerify.cpp这个文件里还有这样的代码:
#define SWAP_FIELD4(_field) (_field) = SWAP4(_field)
static bool swapDexHeader(const CheckState* state, DexHeader* pHeader)
{
    CHECK_PTR_RANGE(pHeader, pHeader + 1);

    // magic is ok
    SWAP_FIELD4(pHeader->checksum);
    // signature is ok
    SWAP_FIELD4(pHeader->fileSize);
    SWAP_FIELD4(pHeader->headerSize);
    SWAP_FIELD4(pHeader->endianTag);
    SWAP_FIELD4(pHeader->linkSize);
    .........
    
     if (pHeader->endianTag != kDexEndianConstant) {
        LOGE("Unexpected endian_tag: %#x", pHeader->endianTag);
        return false;
    }
..........
}

而kDexEndianConstant被定义为0x12345678。最开始endianTag为0x12345678,如果大端的机器下,经过交换必然会变为0x87654321,那下面的条件判断一定会失败导致不能运行。
我哪里理解错了吗?

在eclipse生成dex的时候,有可能设置endianTag为0x87654321吗?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 77
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
kDexEndianConstant被定义为0x12345678
大端模式:
低地址 -----------------> 高地址
0x12  |  0x34  |  0x56  |  0x78
小端:
低地址 ------------------> 高地址
0x78  |  0x56  |  0x34  |  0x12
2013-11-28 09:59
0
雪    币: 473
活跃值: (178)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
恩,正常来讲应该是这样的。
但是在DexSwapVerify.cpp不是这样转换的,它有这样的函数定义:
static u8 endianSwapU8(u8 value) {
    /* ABCDEFGH --> EFGHABCD --> GHEFCDAB --> HGFEDCBA */
    value = (value >> 32) | (value << 32);
    value = ((value & 0xffff0000ffff0000ULL) >> 16) |
            ((value << 16) & 0xffff0000ffff0000ULL);
    return ((value & 0xff00ff00ff00ff00ULL) >> 8) |
           ((value << 8) & 0xff00ff00ff00ff00ULL);
}
2013-11-28 10:06
0
游客
登录 | 注册 方可回帖
返回
//