/* * Dump a method. */ void dumpMethod(DexFile* pDexFile, const char* fileName, const DexMethod* pDexMethod, int i) { const DexMethodId* pMethodId; const DexCode* pCode; const char* classDescriptor; const char* methodName; int firstLine; /* abstract and native methods don't get listed */ if (pDexMethod->codeOff == 0) return; pMethodId = dexGetMethodId(pDexFile, pDexMethod->methodIdx); methodName = dexStringById(pDexFile, pMethodId->nameIdx); classDescriptor = dexStringByTypeIdx(pDexFile, pMethodId->classIdx); pCode = dexGetCode(pDexFile, pDexMethod); assert(pCode != NULL); /* * If the filename is empty, then set it to something printable * so that it is easier to parse. * * TODO: A method may override its class's default source file by * specifying a different one in its debug info. This possibility * should be handled here. */ if (fileName == NULL || fileName[0] == 0) { fileName = "(none)"; } firstLine = -1; dexDecodeDebugInfo(pDexFile, pCode, classDescriptor, pMethodId->protoIdx, pDexMethod->accessFlags, positionsCallback, NULL, &firstLine); char* className = descriptorToDot(classDescriptor); char* desc = dexCopyDescriptorFromMethodId(pDexFile, pMethodId); u4 insnsOff = pDexMethod->codeOff + offsetof(DexCode, insns); if (gParms.methodToFind != NULL && (strcmp(gParms.classToFind, className) != 0 || strcmp(gParms.methodToFind, methodName) != 0)) { goto skip; } printf("0x%08x %d %s %s %s %s %d\n", insnsOff, pCode->insnsSize * 2, className, methodName, desc, fileName, firstLine); skip: free(desc); free(className); }
/* * Get information about a method. */ bool getMethodInfo(DexFile* pDexFile, u4 methodIdx, FieldMethodInfo* pMethInfo) { const DexMethodId* pMethodId; if (methodIdx >= pDexFile->pHeader->methodIdsSize) return false; pMethodId = dexGetMethodId(pDexFile, methodIdx); pMethInfo->name = dexStringById(pDexFile, pMethodId->nameIdx); pMethInfo->signature = dexCopyDescriptorFromMethodId(pDexFile, pMethodId); pMethInfo->classDescriptor = dexStringByTypeIdx(pDexFile, pMethodId->classIdx); return true; }
/* * Dump a method. */ void dumpMethod(DexFile* pDexFile, const DexMethod* pDexMethod, int i) { const DexMethodId* pMethodId; const char* backDescriptor; const char* name; char* typeDescriptor; char* accessStr; pMethodId = dexGetMethodId(pDexFile, pDexMethod->methodIdx); name = dexStringById(pDexFile, pMethodId->nameIdx); typeDescriptor = dexCopyDescriptorFromMethodId(pDexFile, pMethodId); backDescriptor = dexStringByTypeIdx(pDexFile, pMethodId->classIdx); accessStr = createAccessFlagStr(pDexMethod->accessFlags, kAccessForMethod); printf(" #%d : (in %s)\n", i, backDescriptor); printf(" name : '%s'\n", name); printf(" type : '%s'\n", typeDescriptor); printf(" access : 0x%04x (%s)\n", pDexMethod->accessFlags, accessStr); if (pDexMethod->codeOff == 0) { printf(" code : (none)\n"); } else { printf(" code -\n"); dumpCode(pDexFile, pDexMethod); } if (gOptions.disassemble) putchar('\n'); free(typeDescriptor); free(accessStr); }