Categories
discuss

How to strip symbols from Android NDK .so file?

How do you strip symbols from an Android .so native code library?

I have a .so built that has thousands of symbols clearly visible in a hex editor. IDA Pro automatically disassembles with proper symbols based on the ones in the executable.

However, if I ask nm to dump the symbol table, it says there are none. strip and objcopy also have no effect.

C:AndroidProject.apklibarmeabi-v7a>arm-linux-androideabi-strings.exe libMeow.so | findstr _ZN11SecretClass14SecretFunctionERKS_
_ZN11SecretClass14SecretFunctionERKS_

C:AndroidProject.apklibarmeabi-v7a>arm-linux-androideabi-nm.exe libMeow.so
arm-linux-androideabi-nm.exe: libMeow.so: no symbols

C:AndroidProject.apklibarmeabi-v7a>copy /y libMeow.so libMeow-test.so
        1 file(s) copied.

C:AndroidProject.apklibarmeabi-v7a>sha1sum libMeow.so libMeow-test.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow-test.so

C:AndroidProject.apklibarmeabi-v7a>arm-linux-androideabi-strip.exe libMeow-test.so

C:AndroidProject.apklibarmeabi-v7a>sha1sum libMeow.so libMeow-test.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow-test.so

C:AndroidProject.apklibarmeabi-v7a>arm-linux-androideabi-strip.exe -g libMeow-test.so

C:AndroidProject.apklibarmeabi-v7a>sha1sum libMeow.so libMeow-test.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow-test.so

Names have been changed to protect the guilty.

Answer

Since the .so is a shared library that will be loaded dynamically, it needs to have some amount of symbols available externally. To view these, use nm -D libMeow.so. Strip won’t remove these, or it would make the library unusable.

Since the some functions need to be loaded externally, you can’t just remove all dynamic symbols, because then nobody would be able to interface with the .so. If your .so is a JNI library, you need to have the JNI entry point functions visible externally, while if it is a shared library that another .so links against, you need to have at least the public interface of your library visible.

To make the internal symbols hidden, you can read https://gcc.gnu.org/wiki/Visibility for the full story. Roughly, your options are:

  • Use __attribute__ ((visibility ("hidden"))) on every symbol you don’t want to be visible outside of the library. (This probably is quite a few and it’s a lot of work to track down every single one.)
  • Build with -fvisibility=hidden, which implicitly sets this on every single external symbol, and add __attribute__ ((visibility ("default"))) on the ones that you actually need to have exported (probably much fewer)
  • Use a “version script” to limit what functions to export to a select list. When linking, pass -Wl,-version-script -Wl,mylib.ver.

For the version script case, mylib.ver should look like this:

{ global:
PublicFunction1;
PublicFunction2;
local: *; };
Categories
discuss

How to refer to a class when both simple and fully-qualified names clash

Consider the following pathological example:

class Ideone {
  static class ArrayList<T> {
    ArrayList() {
      System.out.println("!!");
    }
  }

  static class java {
    static class util {
      static class ArrayList<T> {
        ArrayList() {
          System.out.println("Here");
        }
      }
    }
  }

  public static void main(String[] args) {
    new ArrayList<>();
    new java.util.ArrayList<>();
    // Can I refer to the "usual" java.util.ArrayList?
  }
}

The two instances created in the constructor are of the nested classes.

But how might I refer to the java.util.ArrayList that we all know and love in the same class? We can’t import it, and we can’t use the fully-qualified name, as the nested class symbols would be used instead.

What can we do in this case? (Other than the obvious – stop using such wantonly evil names for the nested classes).

Answer

You can no longer directly reference java.util.ArrayList if you’ve done the 2 things you’ve done:

  1. Hide the simple name ArrayList with a static nested class in scope.
  2. Hide the fully qualified name java.util.ArrayList with a class ArrayList nested within class util, nested within nested class java.

You can’t even “split” the import in an attempt to use a “partially qualified” import.

import java.*;

...

// This doesn't work!
new util.ArrayList<>();

You can import java.*;, but that is worthless; no classes are defined in the java package directly.

However, you can reference the class java.util.ArrayList indirectly because it’s not final. Outside the scope of the class Ideone, declare a subclass with a different name.

class AnArrayList<T> extends java.util.ArrayList<T> {}

Then you can refer to that class and program to the interface:

List<Integer> al = new AnArrayList<>();  // won't print !! or Here
Categories
discuss

How to use Application Class-Data Sharing feature of java 10?

I read about CDS in Oracle doc https://docs.oracle.com/javase/8/docs/technotes/guides/vm/class-data-sharing.html

What I understood is the system class files needed for loading the jvm are parsed, verified and then stored in a archive at jre/lib/[arch]/client/classes.jsa. Moreover they also provide their memory mapping for jvm,so jvm directly maps the memory according to the mapping information given in the archive. So this reduces the overhead of class loading everytime a jvm instance starts. Please correct me if was wrong.

Now coming to java 10, how can I achieve this for my application code ? Secondly, would the complete application code be eligible for CDS or are there some restrictions?

Answer

There are three essential steps to creating and using an archive with application class-data (for more details, read my post about application class-data sharing):

  1. Creating a list of classes to include in the archive:

    java -XX:+UseAppCDS
        -XX:DumpLoadedClassList=classes.lst
        -jar app.jar
    
  2. Creating an archive:

    java -XX:+UseAppCDS -Xshare:dump 
        -XX:SharedClassListFile=classes.lst
        -XX:SharedArchiveFile=app-cds.jsa
        --class-path app.jar
    
  3. Using the archive:

    java -XX:+UseAppCDS -Xshare:on 
        -XX:SharedArchiveFile=app-cds.jsa
        -jar app.jar
    

Keep the following in mind:

  • you can’t use wildcards or exploded JARs for the class path when creating the archive
  • the class path used to launch the application must have the one used to create the archive as a prefix
  • if you have any problems, use -Xlog:class+load (more on -Xlog) to get more information
Categories
discuss

How to pass variables to a function reference?

In react native when you have functions that need to run at render and must pass variables, most people suggest that one should use

onPress{() => this.functionName(variable)}

However when working with large lists and complex components you have to optimize your code. Creating a new function for every renderItem in a flatList reduces performance, sometimes hugely so depending on how many functions per renderItem you are creating. So the suggestion is to move from creating a function at render to using a function reference. Like this:

functionName = () => {
   //code
}

onPress={this.functionName}

However I haven’t been able to figure out how to pass variables to the function with this method.

If you do this:

onPress={this.functionName(variable}

It will just run the function instantly on component load.

Any ideas?

Answer

As Esther Cuan suggests, currying is the way to go. Chances are, if you are using dynamically created functions dependent on variable changes. Then the time spent on creating these functions is much less than the time spent rerendering the components every time the variables change. Efficiency wise, the priority should be to minimize variable changes in order to minimize rerenders long before the constant redecleration of functions.

If however you are certain that some functions are consistent, even through rerenders, and do not want them to be redeclared here’s how you can achieve that:

class Component extends React.Component {
  functionName = (e) => {
    const { variable } = this.props
    // run logic on the event and variable
  } 

  render() {
    // some code
    onPress={this.functionName}
  }
}

You’ll notice with this approach functionName is only declared once.

The performance flaw with this approach is that now you have to create another component (and possibly the lifecycle methods that come with the class) in order to pass variable as a prop, in order to bypass the need for currying.

Categories
discuss

How to dispatch multiple actions in ngrx/effect (redux-observable)?

I am using Angular 6, ngrx/store. I have such effect that is responsible for updating things. Depends on some logic I want to dispatch different actions. What is the difference if I use switchMap insted of map?

This is what I tried but it doesn’t work:

 @Effect()
  dispathMultipleActions$ = this.actions$.pipe(
    ofType(ActionTypes.UpdateSomething),
    map(() => {
      const actions: Action[] = [];
      const array = [1, 2, 3, 4, 5];
      array.forEach(item => {
        if (item > 3) {
          actions.push(new DeleteAction(item));
        } else {
          actions.push(new ChangeAction(item));
        }
      });
      return actions;
    })
  );

Answer

An effect transforms a stream of actions, so you have a stream of actions as input and output. In your example, you map an action to an array of actions. A stream of arrays of actions is not a valid output type. You need to flatten that array, meaning that you do not emit the array itself into the output stream but instead each of its elements.

Instead of:

input:  --a-------a------>
output: --[b,c]---[b,c]-->

You should do:

input:  --a-------a------>
output: --b-c-----b-c-->

For flattening an Observable of array into Observables of each element, you can use one of the operators mergeMap, switchMap, exhaustMap. In most cases, mergeMap will be the right choice. If you want to learn more about these operators, have a look at this answer.

@Effect()
register$: Observable<Action> = this.actions$.pipe(
  ofType(AuthActionTypes.REGISTER_REQUEST),
  mergeMap((action: RegisterRequest) => {
    // check for register request success
    return [
      new RegisterSuccess(),
      new LoginRequest(action.payload)
    ]
  })
);
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..