mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 12:20:11 +02:00
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:
parent
285dfd013a
commit
4ef9fbbd21
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user