so file call
With the rapid development of Android mobile security, whether for execution efficiency or program security, the key code sinking native layer has become the basic operation.
The development of native layer refers to the development of JNI/NDK. Through JNI, the calls between java layer and native layer (mainly C/C++) can be realized. Native layer generates so dynamic link library after compiling. So file has the advantages of wide portability, high execution efficiency and strong confidentiality.
So the problem arises. How to call so file is very important. Of course, you can directly analyze the pseudo code of so file and directly simulate the key operation with the powerful programming skills. But I think hair is more important for ordinary people.
The current main operation for invoking so files should be:
1. Various implementations based on Unicorn (still under study, not yet listed)
2. The Android server is built, and the http service is started in App to fulfill the requirement of so invocation (provided, of course, that the operation of so has been done, etc.)
As for why AndServer was chosen, well, no, just because it was searched.
Why do you know the life cycle of service when you study Android development with Service? Personally, it's better to use Service to create Http service.
Of course, there is also a simple use of Application, because in the formal environment, most of the so file logic has some package names of context, signed validation, etc., if you customize the application, you can get context parameters.
Introduction to libyemu.so
This is a so file I compiled, which is a simple string splicing based on the input (the following is the c code before the compilation of the native layer)
extern "C" JNIEXPORT jstring JNICALL Java_com_fw_myapplication_ndktest_NdkTest_stringFromUTF(JNIEnv *env, jobject instance, jstring str_) { jclass String_clazz = env->FindClass("java/lang/String"); jmethodID concat_methodID = env->GetMethodID(String_clazz, "concat", "(Ljava/lang/String;)Ljava/lang/String;"); jstring str = env->NewStringUTF(" from so --[NightTeam Curtain of night]"); jobject str1 = env->CallObjectMethod(str_, concat_methodID, str); const char *chars = env->GetStringUTFChars((jstring)str1, 0); return env->NewStringUTF(chars); }
This part of the code is still necessary to paste, simple static registration uses the idea of reflection, reflection is essential in the reverse.
Next comes the java code, which defines the native function
package com.fw.myapplication.ndktest; public class NdkTest { public static native String stringFromUTF(String str); static { System.loadLibrary("yemu"); } }
If you come here a little confused students may need to fill the Android development foundation.
Android project test so
Let's start with my environment, because the environmental impact is too big.
1,AndroidStudio 3.4
2. Mobile Android 6 Architecture armeabi-v7a
Open Android Studio to create a new project
Add this sentence to the module build, and sync
Copy the compiled so file to the libs folder (corresponding to jniLibs.srcDirs)
copy the java code corresponding to so, and pay attention to the consistency of package name class names
Open the activity_main.xml file to add id for TextView
Open MainActiviy.java and start coding
The meaning of these two lines is to find the TextView of the corresponding id from the layout, and then set the Text for it (the return value of the call to the native function)
Let's test our so call
You can see that our so file was successfully invoked (here our so is not valid, just to test whether the app can be invoked properly)
AndServer Coding
AndServer Official Documents: https://yanzhenjie.com/AndServer/
Open official documents, see the introduction of others, new java files
As you can see from the classic MV C, we have defined a nightteam_sign interface. The request mode is get, the request parameter is sign, we call the native function, and then return to json. But here I want to use Application to get the context object, remove the package name, and then customize the application.
package com.nightteam.httpso; import android.app.Application; public class MyApp extends Application { private static MyApp myApp; public static MyApp getInstance() { return myApp; } @Override public void onCreate() { super.onCreate(); myApp = this; } }
Then specify the Application to start in the manifest file
Then modify MyController.java's code
Next, copy the official document-server code.
Import some packages and modify some of the code as follows
The new version of AndServer. SerrBuilder already needs to pass context. Here, the network address and port number are also modified to get from the construction parameters. The AndServer thing is basically finished here. In fact, we will build an interface to adjust so. There is not too much business logic, so the code is the most used. Ordinary
Service Coding
Let's start the Service with the click event of the button, so add a button to the activity_main.xml and specify the click event.
Next, write custom Service code
package com.nightteam.httpso.Service; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; import com.nightteam.httpso.ServerManager; import java.net.InetAddress; import java.net.UnknownHostException; public class MyService extends Service { private static final String TAG = "NigthTeam"; @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate: MyService"); new Thread() { @Override public void run() { super.run(); InetAddress inetAddress = null; try { inetAddress = InetAddress.getByName("0.0.0.0"); Log.d(TAG, "onCreate: " + inetAddress.getHostAddress()); ServerManager serverManager = new ServerManager(getApplicationContext(), inetAddress, 8005); serverManager.startServer(); } catch (UnknownHostException e) { e.printStackTrace(); } } }.start(); } @Override public IBinder onBind(Intent intent) { return null; } }
With a few log s, start AndServer's services in the sub-threads (when using UI threads and sub-threads is Android's foundation, I won't dwell on that here)
Note that you can get inetAddress from 0.0.0.0, but don't write it wrong. The difference between localhost and 0.0.0.0 is to move to the search engine.
Then you pass context, inetAddress, to the constructor of ServerManager, which port s use for new objects, and then open the service.
Finally, take note of the Service declaration in the manifest file
Open Service and get native ip
Go back to our MainActivity.java operation (button click event) and write the startup Service code
public void operate(View view) { switch (view.getId()){ case R.id.id_bt_index: //Start Services: Create - > Start - > Destroy //If the service has been created, it will be restarted again and again, and the operation will be the same service, and it will not be recreated unless you destroy it first. Intent it1 = new Intent(this, MyService.class); Log.d(TAG, "operate: button"); startService(it1); ((Button) view).setText("Service has been opened"); break; } }
Our service is basically built up here, but for convenience, I want to display our native ip on App, so we don't need to set it up and check it again.
I found a tool class to get the ip address on the internet. The source code is as follows:
package com.nightteam.httpso; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Enumeration; import java.util.regex.Pattern; public class NetUtils { private static final Pattern IPV4_PATTERN = Pattern.compile("^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); private static boolean isIPv4Address(String input) { return IPV4_PATTERN.matcher(input).matches(); } //Get the local IP address public static InetAddress getLocalIPAddress() { Enumeration<NetworkInterface> enumeration = null; try { enumeration = NetworkInterface.getNetworkInterfaces(); } catch (SocketException e) { e.printStackTrace(); } if (enumeration != null) { while (enumeration.hasMoreElements()) { NetworkInterface nif = enumeration.nextElement(); Enumeration<InetAddress> inetAddresses = nif.getInetAddresses(); if (inetAddresses != null) while (inetAddresses.hasMoreElements()) { InetAddress inetAddress = inetAddresses.nextElement(); if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) { return inetAddress; } } } } return null; } }
copy the tool class into our Android project and continue coding in MainActivity.java
Get the local address and Android SDK version (different way to start Service after Android 8)
App permission, start App
The last step is to apply for network privileges for app.
Then connect to our mobile phone, run the project, test it, and click on Open Service.
Look at Android Studio logs
As if everything was okay, try it with browser access (ip is the IP address shown in App)
Figure normal access to what we want
Looking back on Service, open the settings of our mobile phones and find the application management-running services (different mobile phones, different ways)
You can see that our program runs a service, which is the MyService we coded.
Next, kill the App process and review the running service again
I have set up automatic operation in the privilege management to keep the service running. (This place still varies according to the size of the system)
So far, the http service tuning so is completed with App
Well, the above is the overall idea and process of using Android Server to build Android Server so file. If you are too lazy to see it, it is also possible to patch it directly with the App I wrote, just send a message [AndServer to build Web Service so] to the public number [NightTeam].
Author: "Night Team" - Delusions
Night Team was established in 2019. Its members include Cui Qingcai, Zhou Ziqi, Chen Xiangan, Tang Yifei, Feng Wei, Cai Jin, Dai Huangjin, Zhang Yeqing and Wei Shidong.
The main programming languages are Python, Rust, C++, Go, covering crawlers, in-depth learning, service development and object storage. Teams are neither good nor evil. They only do what they think is right. Please be careful.