杀毒so crash


51361051

backtrace:
    #00 pc 0000000000040d04  /system/lib64/libams-1.1.5-64b-mfr.so ams/AMS_BlueShark/inc/DexFile.h:375
    #01 pc 0000000000039f04  /system/lib64/libams-1.1.5-64b-mfr.so ams/AMS_BlueShark/src/MalwareScanner.cpp:483
    #02 pc 000000000003a2b8  /system/lib64/libams-1.1.5-64b-mfr.so ams/AMS_BlueShark/src/MalwareScanner.cpp:901
    #03 pc 000000000001c518  /system/lib64/libams-1.1.5-64b-mfr.so (Java_tmsdk_fg_module_qscanner_AmScannerStatic_scanApkBytes+824)
    #04 pc 0000000000049b04  /data/dalvik-cache/arm64/system@app@GuardProvider@GuardProvider.apk@classes.dex

51376555

10-09 19:08:50.027   211   211 I DEBUG   : backtrace:
10-09 19:08:50.027   211   211 I DEBUG   :     #00  pc 0001b734  /system/lib/libams-1.1.5-64b-mfr.so ams/AMS_BlueShark/inc/DexFile.h:378
10-09 19:08:50.027   211   211 I DEBUG   :     #01  pc 00034ca3  /system/lib/libams-1.1.5-64b-mfr.so stlport/stlport/stl/_threads.h:349

51376559 同第一个

backtrace:
    #00 pc 0000000000040d04  /system/lib64/libams-1.1.5-64b-mfr.so
    #01 pc 0000000000039f04  /system/lib64/libams-1.1.5-64b-mfr.so
    #02 pc 000000000003a2b8  /system/lib64/libams-1.1.5-64b-mfr.so
    #03 pc 000000000001c518  /system/lib64/libams-1.1.5-64b-mfr.so (Java_tmsdk_fg_module_qscanner_AmScannerStatic_scanApkBytes+824)
    #04 pc 0000000000049b04  /data/dalvik-cache/arm64/system@app@GuardProvider@GuardProvider.apk@classes.dex

51376565 同第二个

backtrace:
    #00  pc 0001b626  /system/lib/libams-1.1.5-64b-mfr.so ams/AMS_BlueShark/inc/DexFile.h:375
    #01  pc 00034ca3  /system/lib/libams-1.1.5-64b-mfr.so stlport/stlport/stl/_threads.h:349

<?prettify linenums=374?>

    inline const char* GetStringData(const DexStringId* pStringId) {
        const u1* ptr = mBaseAddr + pStringId->stringDataOff;
 
        // Skip the uleb128 length.
        while ((ptr++) > 0x7f) / empty / ;
 
        return (const char) ptr;
    }

该函数只被一个函数调用了

<?prettify linenums=392?>

    inline const char* GetStringById(u4 idx) {
        const DexStringId* pStringId = GetStringId(idx);
        return GetStringData(pStringId);
    }

继续跟踪上面的函数 在下面这两个地方被调用

DexFile.h

<?prettify linenums=409?>

    inline const char* GetStringByTypeIdx(u4 idx) {
        const DexTypeId* typeId = GetTypeId(idx);
        return GetStringById(typeId->descriptorIdx);
    }

ApkInfo.cpp

<?prettify linenums=274?>

AmsError ApkInfo::ParseClassList(vector<string>& classList) {
    ASSERTNOTNULL_RETURN(mDexFile, _AmsErrGeneral);
 
    int classCount = mDexFile->GetHeader()->classDefsSize;
    classList.resize(classCount);
 
    LOGD("ApkInfo::ParseClassList classCount[%d]", classCount);
 
    for (int i = 0; i < classCount; i++) {
        const DexClassDef* pClassDef = mDexFile->GetClassDef(i);
        LOGD("ApkInfo::ParseClassList i[%d]--[%d]", i, pClassDef->classIdx);
        if(!mDexFile->isTypeIdAvailable(pClassDef->classIdx)){
            return _AmsErrGeneral;
        }
 
        const DexTypeId* typeId = mDexFile->GetTypeId(pClassDef->classIdx);
        if(!mDexFile->isStringIdAvailable(typeId->descriptorIdx)){
            return _AmsErrGeneral;
        }
 
        const char* descriptor = mDexFile->GetStringByTypeIdx(pClassDef->classIdx);
        classList[i] = DescriptorToDot(descriptor);
    }
 
    LOGD("[End]ApkInfo::ParseClassList");
 
    return _AmsErrNone;
}

MalwareScanner.cpp

<?prettify linenums=477?>

AmsError MalwareScanner::CheckClasses(ApkInfo* apkInfo, ApkInfoCache* apkInfoCache) {
    AmsError err = _AmsErrGeneral;
 
    vector<string> classList;
    vector<sstring> reverseClassList;
    do {
        if ((err = apkInfo->ParseClassList(classList)) != _AmsErrNone) {
            LOGE("ParseClassList error\n");
            break;
        }
        reverseClassList = classList;
 
        sort(classList.begin(), classList.end());
        sort(reverseClassList.begin(), reverseClassList.end(), ClassSuffixCompare);
 
        PrefixMatch(classList, apkInfoCache);
        SuffixMatch(reverseClassList, apkInfoCache);

上面这条调用路径可以和调用堆栈对上

下面看另一条调用路径

ApkInfo.cpp

<?prettify linenums=310?>

AmsError ApkInfo::ParseConstantList(vector& constantList) {
    ASSERTNOTNULL_RETURN(mDexFile, _AmsErrGeneral);
 
    int constantSize = mDexFile->GetHeader()->stringIdsSize;
    constantList.resize(constantSize);
    for (int i = 0; i < constantSize; i++) {
        const char* descriptor = mDexFile->GetStringById(i);

if 0

    // constantList[i] = TruncateString(descriptor, MAX_CONST_STRING_LEN);
    if (strlen(descriptor) < MAX_CONST_STRING_LEN) {
        constantList[newSize++] = string(descriptor);
        if (newSize >= MAX_CONST_STRING_SIZE) {
            break;
        }
    }

endif

    constantList[i] = string(descriptor);
}

  return _AmsErrNone; }

MalwareScanner.cpp

<?prettify linenums=546?>

AmsError MalwareScanner::CheckConstantStrings(ApkInfo* apkInfo, ApkInfoCache* apkInfoCache) {
    AmsError err = _AmsErrGeneral;
 
    vector constantList;
    do {
        if ((err = apkInfo->ParseConstantList(constantList)) != _AmsErrNone) {
            LOGE("ParseConstantList error\n");
            break;
        }
 
        ConstantMatch(constantList, apkInfoCache);
    } while(0);
 
    return err;
}

<?prettify linenums=823?>

AmsError MalwareScanner::ScanApk(const QQPIM::ApkKey apkKey, QQPIM::QScanResult& result) {

和调用堆栈并不很相符

初步断定出错的是第一个调用栈

问题的关键是dexfile数据结构

class DexFile {
    /* directly-mapped "opt" header */
    const DexOptHeader* mOptHeader;

    /* pointers to directly-mapped structs and arrays in base DEX */
    const DexHeader*    mHeader;
    const DexStringId*  mStringIds;
    const DexTypeId*    mTypeIds;
    const DexFieldId*   mFieldIds;
    const DexMethodId*  mMethodIds;
    const DexProtoId*   mProtoIds;
    const DexClassDef*  mClassDefs;
    const DexLink*      mLinkData;
 
    /* mapped in "auxillary" section */
    const DexClassLookup* mClassLookup;
 
    /* points to start of DEX file data */
    const u1*           mBaseAddr;
 
    /* track memory overhead for auxillary structures */
    int                 mOverhead;
 
    /* additional app-specific data structures associated with the DEX */
    void*               mAuxData;
};

重点看下DexStringId 类型

typedef struct DexStringId {
    u4  stringDataOff;      /* file offset to string_data_item */
} DexStringId;
    /* return the StringId with the specified index */
    inline const DexStringId* GetStringId(u4 idx) {
        assert(idx < mHeader->stringIdsSize);
        return &mStringIds[idx];
    }

dex文件结构如下

google的官方文档说明

可见pStringId必须位于string_ids section,而ptr必须位于data section

<?prettify linenums=374?>

    inline const char* GetStringData(const DexStringId* pStringId) {
        const u1* ptr = mBaseAddr + pStringId->stringDataOff;
 
        // Skip the uleb128 length.
        while ((ptr++) > 0x7f) / empty / ;
 
        return (const char) ptr;
    }

最终修改如下:


Copyright © FengGuangtu 2017