Change the virtual method lookup to dump the entire vtable for the class

git-svn-id: https://smali.googlecode.com/svn/trunk@439 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2009-09-08 20:18:01 +00:00
parent 285dfd013a
commit 4ef9fbbd21

View File

@ -43,6 +43,7 @@ typedef struct InlineSub {
int inlineIdx; int inlineIdx;
} InlineSub; } InlineSub;
static DexStringCache stringCache;
static ClassObject* findCommonSuperclass(ClassObject* c1, ClassObject* c2); static ClassObject* findCommonSuperclass(ClassObject* c1, ClassObject* c2);
@ -234,7 +235,7 @@ static ClassObject* findCommonSuperclass(ClassObject* c1, ClassObject* c2)
* This returns "false" if the world is too screwed up to do anything * This returns "false" if the world is too screwed up to do anything
* useful at all. * useful at all.
*/ */
loadAllClasses(DvmDex* pDvmDex) int loadAllClasses(DvmDex* pDvmDex)
{ {
u4 count = pDvmDex->pDexFile->pHeader->classDefsSize; u4 count = pDvmDex->pDexFile->pHeader->classDefsSize;
u4 idx; u4 idx;
@ -313,13 +314,13 @@ Field *lookupField(char *classType, int offset)
Method *lookupInlineMethod(int index) Method *lookupInlineMethod(int index)
{ {
InlineOperation *inlineTable = dvmGetInlineOpsTable(); const InlineOperation *inlineTable = dvmGetInlineOpsTable();
int count = dvmGetInlineOpsTableLength(); int count = dvmGetInlineOpsTableLength();
if (index >= count) if (index >= count)
return NULL; return NULL;
InlineOperation *inlineOp = &inlineTable[index]; const InlineOperation *inlineOp = &inlineTable[index];
ClassObject *clazz = dvmFindSystemClassNoInit(inlineOp->classDescriptor); ClassObject *clazz = dvmFindSystemClassNoInit(inlineOp->classDescriptor);
if (clazz == NULL) if (clazz == NULL)
@ -333,27 +334,41 @@ Method *lookupInlineMethod(int index)
return method; return method;
} }
Method *lookupVirtualMethod(char *classType, int index, ClassObject **clazz) int dumpVirtualMethods(char *classType, FILE *clientOut)
{ {
ClassObject *clazz;
if (classType[0] == '[') if (classType[0] == '[')
*clazz = dvmFindArrayClass(classType, NULL); clazz = dvmFindArrayClass(classType, NULL);
else else
*clazz = dvmFindSystemClassNoInit(classType); clazz = dvmFindSystemClassNoInit(classType);
if (*clazz == NULL)
return NULL; if (clazz == NULL)
{
fprintf(clientOut, "err: could not find class %s\n", classType);
return 0;
}
//interface classes don't have virtual methods, by definition. But it's possible //interface classes don't have virtual methods, by definition. But it's possible
//to call virtual methods defined on the Object class via an interface type //to call virtual methods defined on the Object class via an interface type
if (dvmIsInterfaceClass(*clazz)) if (dvmIsInterfaceClass(clazz))
*clazz = dvmFindSystemClassNoInit("Ljava/lang/Object;"); {
clazz = dvmFindSystemClassNoInit("Ljava/lang/Object;");
if (index >= (*clazz)->vtableCount) if (clazz == NULL)
return NULL; {
fprintf(clientOut, "err: could not find class %s\n", classType);
Method *method = (*clazz)->vtable[index]; return 0;
}
return method; }
int i;
for (i=0; i<clazz->vtableCount; i++)
{
Method *method = clazz->vtable[i];
fprintf(clientOut, "vtable: %s%s\n", method->name,
dexProtoGetMethodDescriptor(&method->prototype, &stringCache));
}
return 1;
} }
Method *lookupSuperMethod(char *classType, int index, ClassObject **clazz) Method *lookupSuperMethod(char *classType, int index, ClassObject **clazz)
@ -465,7 +480,7 @@ int main(int argc, char* const argv[])
mapAddr = mmap(NULL, inputInfo.st_size, PROT_READ|PROT_WRITE, mapAddr = mmap(NULL, inputInfo.st_size, PROT_READ|PROT_WRITE,
MAP_SHARED, odexFd, 0); MAP_SHARED, odexFd, 0);
if (mapAddr == MAP_FAILED) { if (mapAddr == MAP_FAILED) {
printf(stderr, "unable to mmap DEX cache: %s\n", strerror(errno)); fprintf(stderr, "unable to mmap DEX cache: %s\n", strerror(errno));
return 1; return 1;
} }
@ -517,9 +532,8 @@ int main(int argc, char* const argv[])
} }
char *command = NULL; char *command = NULL;
int len = 0; unsigned int len = 0;
DexStringCache cache; dexStringCacheInit(&stringCache);
dexStringCacheInit(&cache);
while ((command = fgetln(clientIn, &len)) != NULL) { while ((command = fgetln(clientIn, &len)) != NULL) {
while (len > 0 && (command[len-1] == '\r' || command[len-1] == '\n')) while (len > 0 && (command[len-1] == '\r' || command[len-1] == '\n'))
@ -528,9 +542,7 @@ int main(int argc, char* const argv[])
memcpy(buf, command, len); memcpy(buf, command, len);
buf[len] = 0; buf[len] = 0;
/*struct timeval tv; //printf("%s\n", buf);
gettimeofday(&tv, NULL);
printf("start %07d %s\n", tv.tv_usec, buf);*/
char *cmd = strtok(buf, " "); char *cmd = strtok(buf, " ");
if (cmd == NULL) { if (cmd == NULL) {
@ -615,7 +627,7 @@ int main(int argc, char* const argv[])
else else
methodType = "virtual"; methodType = "virtual";
fprintf(clientOut, "%s method: %s->%s%s\n", methodType, method->clazz->descriptor, method->name, dexProtoGetMethodDescriptor(&method->prototype, &cache)); fprintf(clientOut, "%s method: %s->%s%s\n", methodType, method->clazz->descriptor, method->name, dexProtoGetMethodDescriptor(&method->prototype, &stringCache));
fflush(clientOut); fflush(clientOut);
break; break;
} }
@ -624,38 +636,18 @@ int main(int argc, char* const argv[])
char *classType = strtok(NULL, " "); char *classType = strtok(NULL, " ");
if (classType == NULL) if (classType == NULL)
{ {
fprintf(clientOut, "err: no classType for virtual method lookup\n"); fprintf(clientOut, "err: no classType for vtable dump\n");
fflush(clientOut); fflush(clientOut);
break; break;
} }
char *indexStr = strtok(NULL, " "); if (!dumpVirtualMethods(classType, clientOut)) {
if (indexStr == NULL) fprintf(clientOut, "err: error encountered while dumping virtual methods\n");
{
fprintf(clientOut, "err: no vtable index for virtual method lookup\n");
fflush(clientOut);
break;
}
char *end;
int index = strtol(indexStr, &end, 10);
if (*end != '\0')
{
fprintf(clientOut, "err: vtable index not a valid number for virtual method lookup\n");
fflush(clientOut);
break;
}
ClassObject *clazz;
Method *method = lookupVirtualMethod(classType, index, &clazz);
if (method == NULL)
{
fprintf(clientOut, "err: method not found\n");
fflush(clientOut); fflush(clientOut);
break; break;
} }
fprintf(clientOut, "method: %s->%s%s\n", clazz->descriptor, method->name, dexProtoGetMethodDescriptor(&method->prototype, &cache)); fprintf(clientOut, "done\n");
fflush(clientOut); fflush(clientOut);
break; break;
} }
@ -695,7 +687,7 @@ int main(int argc, char* const argv[])
break; break;
} }
fprintf(clientOut, "method: %s->%s%s\n", clazz->descriptor, method->name, dexProtoGetMethodDescriptor(&method->prototype, &cache)); fprintf(clientOut, "method: %s->%s%s\n", clazz->descriptor, method->name, dexProtoGetMethodDescriptor(&method->prototype, &stringCache));
fflush(clientOut); fflush(clientOut);
break; break;
} }
@ -732,7 +724,7 @@ int main(int argc, char* const argv[])
if (clazz1 == NULL) if (clazz1 == NULL)
{ {
fprintf(clientOut, "err: class %s could not be found for common superclass lookup\n"); fprintf(clientOut, "err: class %s could not be found for common superclass lookup\n", classType1);
fflush(clientOut); fflush(clientOut);
break; break;
} }
@ -753,7 +745,7 @@ int main(int argc, char* const argv[])
if (clazz2 == NULL) if (clazz2 == NULL)
{ {
fprintf(clientOut, "err: class %s could not be found for common superclass lookup\n"); fprintf(clientOut, "err: class %s could not be found for common superclass lookup\n", classType2);
fflush(clientOut); fflush(clientOut);
break; break;
} }