How can I find all paths to access an java API? - java

I'm analyzing an Android App, looking for security flaws. I've decompiled the APK with JEB and I found a vulnerable method in it.
My problem is: The App logic is too complex and it is very difficult to find a way to trigger this vulnerable method.
I would like to know if there exists a tool to find all the "paths" in the code to access some method.
For example, for the code below:
private void methodX() {
// This is the method I want to call
}
private void methodA() {
methodX();
}
private void methodB() {
methodA();
}
private void methodC() {
methodX();
}
The paths to access methodX are:
methodA( ) -> methodX( )
methodC( ) -> methodX( )
methodB( ) -> methodA( ) -> methodX( )
By the way, I'm using eclipse in the analysis, maybe there is some command on it to do this, but I haven't found yet.

In Eclipse, Ctrl+Alt+H will open the call hierarchy for a method, showing a tree view you can expand for finding "indirect" references to that method.
Here is an example tracing a method from Spring MVC's DispatcherServlet:

Ctrl+Shift+G on methodX() will show you all references

Related

AspectJ trouble using around advice and ProceedingJoinPoint

I'm new to AOP and I need to use AspectJ on my project.
I need to use around advice but I have a problem using it, I've the following code in my .aj class,
pointcut checkUser(ProceedingJoinPoint jp,User user): call(* com.example.UserAccount.MyUI.checkUser(..))&& args(jp,user);
void around(ProceedingJoinPoint jp,User user) throws Throwable : checkUser(jp,user){
// Condition checks one of the user boolean property
if(condition){
jp.proceed();
}else{
// Do nothing
}
}
but I get this warning all the time,
advice defined in Aspects.UserAccount has not been applied [Xlint:adviceDidNotMatch]
By the way, I tried it without ProceedingJoinPoint and tried just proceed(); but then got this warning, too few arguments to proceed, expected 1
I'm thankful for any single help or hint!
Reza
First I recommend to read the AspectJ documentation in order to learn the syntax. As you are using native AspectJ syntax, this is like learning a new programming language or at least a Java extension. What you are doing is mix native syntax with annotation-based syntax. Try to stick with one. I am sure that you did not find this in any tutorial but ended up with that syntax via trial and error.
You do not need to bind a joinpoint parameter in native syntax because it is there implicitly and automatically. The automatically bound joinpoint is always named thisJoinPoint as all tutorials surely show you. Only in annotation-based syntax you need to bind the joinpoint and can name it as you wish, but even then I recommend to stick with thisJoinPoint because then refactoring from annotation to native syntax is easier and your eyes get used to spotting that variable name in your aspect code.
The warning you get means that the pointcut you defined does not match any part of your code, at least not any part which is visible to the aspect weaver or compiler. There could be plenty of reasons why this can occur, e.g. misspelled package or class names, wrong around advice return type (return type must be Object for non-void methods or more specifically match what the method you want to intercept returns). Assuming that e.g. checkUser(..) returns a boolean, the around advice should do the same. I made up an example using your package and class names. Besides, package names should be lower-case but I used yours, assuming they are really package names and not inner classes:
Helper class:
package com.example.UserAccount;
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
#Override
public String toString() {
return "User(" + name + ")";
}
}
Class targeted by aspect + sample main method:
package com.example.UserAccount;
public class MyUI {
public boolean checkUser(User user) {
return user.getName().toUpperCase().contains("ADMIN");
}
public static void main(String[] args) {
MyUI ui = new MyUI();
System.out.println(ui.checkUser(new User("Administrator")));
System.out.println(ui.checkUser(new User("john")));
System.out.println(ui.checkUser(new User("xander")));
System.out.println(ui.checkUser(new User("admiral")));
System.out.println(ui.checkUser(new User("SySaDmiN")));
}
}
As you can see, we expect an output of "true" for the first and last entry, but "false" for the ones in between due to the check logic I made up for checkUser(..).
Now let us write an aspect which also returns "true" for a user named "Xander", e.g. in order to give him admin rights or whatever. I am making this up because you did not provide an MCVE as you always should on StackOverflow, but just an incoherent code snippet which keeps everyone trying to answer your question guessing what the heck you might want to achieve and how to reproduce your problem.
Aspect:
package Aspects;
import com.example.UserAccount.User;
import com.example.UserAccount.MyUI;
public aspect UserAccount {
pointcut checkUser(User user) :
execution(boolean MyUI.checkUser(*)) && args(user);
boolean around(User user) : checkUser(user) {
System.out.println(thisJoinPoint + " -> " + user);
if (user.getName().equalsIgnoreCase("xander"))
return true;
return proceed(user);
}
}
I just imported the MyUI class, so there is no need to use a fully-qualified class name here. Again, this is an advantage of native syntax, in annotation-based syntax you would have to use the fully qualified name.
I also replaced the generic * MyUI.checkUser(..) (which would also work) by the more explicit boolean MyUI.checkUser(*) because we already know that the method returns a boolean and has exactly one parameter, which both we assume anyway by returning a boolean from the around advice and by binding exactly one parameter via args(). You could also be even more specific and use boolean MyUI.checkUser(User).
Furthermore, I am using execution() rather than call() because it is more efficient, as it weaves the advice code just into the executing method once instead of five times for each method call in the main method. You only need to use call() if the MyUI class is out of reach of the AspectJ weaver/compiler, i.e. because it is not in the module you compile with AspectJ Maven.
Console log:
execution(boolean com.example.UserAccount.MyUI.checkUser(User)) -> User(Administrator)
true
execution(boolean com.example.UserAccount.MyUI.checkUser(User)) -> User(john)
false
execution(boolean com.example.UserAccount.MyUI.checkUser(User)) -> User(xander)
true
execution(boolean com.example.UserAccount.MyUI.checkUser(User)) -> User(admiral)
false
execution(boolean com.example.UserAccount.MyUI.checkUser(User)) -> User(SySaDmiN)
true
Et voilà, the aspect works. It makes the target method return "true" for user "xander".

Android annotation processing - generate different code for different build flavor

I'm building a library that requires some annotation processing to generate code. I now run into an issue that the release build doesn't need to have as much code as the debug build does (since this is a library for modifying configuration variants - primarily used for testing purposes). The following code illustrates the situations. Let's say I want to create a class ConfigManager from some annotated classes and properties. In debug builds, I need this much:
public class ConfigManager {
public Class getConfigClass() {
return abc.class;
}
public void method1() {
doSomething1();
}
public void method2() {
doSomething2();
}
public void method3() {
doSomething3();
}
}
While in release builds, I only need this much:
public class ConfigManager {
public Class getConfigClass() {
return abc.class;
}
}
I have a feeling it may be possible by writing a Gradle plugin to check for build flavor at compile time and invoke a different processor/or somehow pass a parameter to a processor to generate different code. However this topic is pretty new to me so I'm not sure how to achieve this. A couple hours of googling also didnt help. So I'm wondering if anyone could give me a direction or example? Thanks
Pass an option (release=true/false) to your processor.
From javac https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html
-Akey[=value]
Specifies options to pass to annotation processors. These options are not interpreted by javac directly, but are made available for use by individual processors. The key value should be one or more identifiers separated by a dot (.).
In combination with Processor.html#getSupportedOptions https://docs.oracle.com/javase/8/docs/api/javax/annotation/processing/Processor.html#getSupportedOptions
Returns the options recognized by this processor. An implementation of the processing tool must provide a way to pass processor-specific options distinctly from options passed to the tool itself, see getOptions.
Implementation outline:
public Set<String> getSupportedOptions() {
Set<String> set = new HashSet<>();
set.add("release");
return set;
}
// -Arelease=true
boolean isRelease(ProcessingEnvironment env) {
return Boolean.parseBoolean(env.getOptions().get("release"));
}
See Pass options to JPAAnnotationProcessor from Gradle for how to pass options in a gradle build.

Find Method usages only for specified class in Intelij-Idea

I am using IntelliJ IDEA and I have problem with method usage finding.
Suppose I have interface Worker.
public interface Worker {
void startWork();
void endWork();
}
And I have two implementations.
public class Develper implements Worker {
#Override
public void startWork() {
System.out.println("Developer Start Working");
}
#Override
public void endWork() {
}
}
public class Qa implements Worker {
#Override
public void startWork() {
System.out.println("QA start Work");
}
#Override
public void endWork() {
}
}
I open the Developer class and trying to find usages of startWork().
I want only to view usage of the Developer.startWork() implemented method.
But when I find usages it shows both Developer and Qa.startWork() method usages. How can I avoid Qa.startWork() method usage when finding Developer.startWork() usages?
Using Ctrl+Shift+Alt+F7 (⌘+⇧+⌥+F7 for Mac) should show the prompt from Jim Hawkins answer.
See: https://www.jetbrains.com/help/idea/find-usages-method-options.html
When you search for usages of a method implementation with this dialog Ctrl+Shift+Alt+F7, IntelliJ IDEA will ask whether or not you want to search for the base method. With any other find usages actions such as Alt+F7 or Ctrl+Alt+F7, the base method will be included in the search results automatically.
I'm using IntelliJ IDEA 15.0.1 .
I think what you see when using the "find usages" functionality depends from the context.
If you place the cursor in method name Developer.startWork and invoke find usages , you should see a small dialog. You are asked "Do you want to find usages of the base method?" .
If you say "No", and in your sources you did only call the method via the base class or interface (Worker.start() in your example), IDEA doesn't show you any hits. Thats correct.
If you call the overridden method via Developer.startWork() , and press "No" in the dialog, then you will see the usages of the specific implementation.
Update:
After reading the answer from #JimHawkins, I think the elephant is still in the room :) The question is, do you want to see where Developer.startWork() is actually called, or do you want to see where it is statically referenced?
Eg:
Developer developer = new Developer();
developer.startWork(); // you want to find only this?
Worker worker = developer;
worker.startWork(); // ..or this as well?
The find usages method can only tell, where a given method is statically referenced, but not where it is actually used (that is determined runtime via the mechanism of polymorphism).

Method refactoring in Eclipse

I try to do the following refactoring steps in Eclipse IDE (JDT) and can not find the required refactoring and can not remember the name of all of the steps. I checked the refactoring at SourceMacking and do not find the correct one.
Let's take for example the following scenario:
class A {
method(B b) {
doSomethingWithA();
b.doSomethingWithB();
}
[...]
}
class B {
[...]
}
1) Make method static (missing name of the refactoring?):
class A {
static method(A a, B b) {
a.doSomethingWithA();
b.doSomethingWithB();
}
[...]
}
class B {
[...]
}
2) Move method:
class A {
[...]
}
class B {
static method(A a, B b) {
a.doSomethingWithA();
b.doSomethingWithB();
}
[...]
}
3) Convert to instance method:
class A {
[...]
}
class B {
method(A a) {
a.doSomethingWithA();
doSomethingWithB();
}
[...]
}
So anyone knowing something to do this step by step in Eclipse or do know the name of the refactoring is welcome. The goal is to have IDE support for every step.
Unfortunately, Eclipse's refactoring functionality is not as complete as other IDEs (for example Jetbrains' IntelliJ). I'll include instructions on how to perform each of the refactorings you requested with both IntelliJ and Eclipse.
With IntelliJ
Make Method Static
Move Instance Method
Convert to Instance Method
With Eclipse
Make Method Static: Eclipse doesn't directly support it, but we can achieve this using two other refactorings.
1.1. Introduce Indirection
Result
public static void method(A a, B b) {
a.method(b);
}
public void method(B b){
doSomethingWithA();
b.doSomethingWithB();
}
1.2. Inline
Result
public static void method(A a, B b) {
a.doSomethingWithA();
b.doSomethingWithB();
}
Move Static Members
Convert to Instance Method: Now, this is where it gets tricky. If you want to go from step 1 to step 3, you could just use Eclipse's Move Method and it'll handle everything perfectly fine. However, there are no ways that I know of to go from step 2 to step 3 using Eclipse's automated refactorings.
After having learned the refactoring is called 'Convert to Instance Method' I searched the bug database of Eclipse JDT and I found bad news:
Bug 10605
Bug 118032
Bug 338449
So basically it is a Won't-Fix noone cares feature request and so it might be time that I also switch to IntelliJ. I have to contemplate about this... .
Emond Papegaaij suggested in the discussion of Bug 118032 a work around:
A simple workaround is to create the static method, call this static method from the method you want to become static and inline the method call. This works for me in 4.3.1.
This is interesting but again would not be an automatic refactoring and defeat the purpose of refactoring in the first place. Adding someone's own code introduce the chance of failure and requires the rerun of the test-suite resulting in no chance of safely refactoring legacy code.

log all the attribute changes of a Class

For debugging purposes I need to keep track of a Class attributes changes.
For example consider the following class:
class Test {
int myInt;
String myString;
...
public void setMyInt(int a) ...
public void setMyString(String s) ...
public printDebugLog();
}
void main() {
Test t = new Test();
t.setMyInt(5);
t.setMyString("Hello");
t.printDebugLog();
}
I want to output to be something like:
myInt => 5
myString => Hello
The easy solution is to create logs instantly. i.e. adding a Log function as follow:
void Log(String s) {
System.out.println(s);
}
and then code the set functions like below:
void setMyString(String s) {
myString = s;
Log("myString => " + s);
}
this requires all the set functions to be written variously and I wonder if there are any better solution for such matter. For example it might be easier (if possible) to create a SetValue function which accepts two variables and set the first attribute to the value of the second object. or something like this.
Any idea?
To do this you should wrap your class with orthogonal code that performs logging.
Since your class does not implement interface you cannot use dynamic proxy, so you have to use one of solutions that use byte code engineering.
The strongest solution I know is AspectJ. But probably you even do not need it. You can use Javassist or CGLIb - the byte code engineering libraries that allow creating proxies that wrap classes, so you can add code that performs logging.
You can use AOP to intercept the setter methods and log when they are called. A quick google should give you a few examples.
If you debug via JPDA,
you can create a Breakpoint
on a field you like to watch.

Categories

Resources