How do i hook function using zygisk? - android

I am tryinh to hook function Hassystemfeature in android.app.ApplicationPackageManager, but it is not working, i am using api->hookJniNativeMethods in zygisk but not able to hook it.
jboolean (*orig_hasSystemFeature)(JNIEnv *, jobject, jstring, jint);
jboolean (*orig_hasSystemFeature_1)(JNIEnv *, jobject, jstring);
static jboolean my_has_system_feature(JNIEnv *env, jobject thiz, jstring name, jint version)
{
    if (strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2022_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2022_MIDYEAR_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2021_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2021_MIDYEAR_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2020_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2020_MIDYEAR_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2019_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2019_PRELOAD") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2019_MIDYEAR_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2018_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2018_PRELOAD") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2017_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2017_PRELOAD") != nullptr)
    {
        // Release the string resources
        env->ReleaseStringUTFChars(name, env->GetStringUTFChars(name, nullptr));
        // Return false if the package name and feature name match
        return JNI_FALSE;
    }
    // Release the string resources
    env->ReleaseStringUTFChars(name, env->GetStringUTFChars(name, nullptr));
    return orig_hasSystemFeature(env, thiz, name, version);
}
static jboolean my_has_system_feature_1(JNIEnv *env, jobject thiz, jstring name)
{
    if (strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2022_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2022_MIDYEAR_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2021_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2021_MIDYEAR_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2020_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2020_MIDYEAR_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2019_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2019_PRELOAD") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2019_MIDYEAR_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2018_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2018_PRELOAD") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2017_EXPERIENCE") != nullptr ||
        strstr(env->GetStringUTFChars(name, nullptr), "PIXEL_2017_PRELOAD") != nullptr)
    {
        // Release the string resources
        env->ReleaseStringUTFChars(name, env->GetStringUTFChars(name, nullptr));
        // Return false if the package name and feature name match
        return JNI_FALSE;
    }
    // Release the string resources
    env->ReleaseStringUTFChars(name, env->GetStringUTFChars(name, nullptr));
    return orig_hasSystemFeature_1(env, thiz, name);
}
void patch_sys()
{
JNINativeMethod methods[] = {
{"hasSystemFeature", "(Ljava/lang/String;I)Z", (void *)my_has_system_feature},
{"hasSystemFeature", "(Ljava/lang/String;I)", (void *)my_has_system_feature_1}
};
api->hookJniNativeMethods(env, "android/app/ApplicationPackageManager", methods, 2);
*(void **)&orig_hasSystemFeature = methods[0].fnPtr;
*(void **)&orig_hasSystemFeature_1 = methods[1].fnPtr;
}

Related

Parse Int image array to Byte array in Android fails when using BitmapFactory

Try to use BitmapFactory.decodeByteArray to generate Bitmap and assign into ImageView.
Original file is a Int String like the following "77 78 255 0 ..."
Following code is for converting from String to ByteArray:
fun serialize(imageDataString: String): ByteArray {
val imageDataArray = imageDataString.split(" ").toTypedArray()
val bDataArray = ByteArray(imageDataArray.size)
for (i in imageDataArray.indices) {
val optionalIntValue = imageDataArray[i].toIntOrNull()
if(optionalIntValue != null) {
bDataArray[i] = optionalIntValue.toByte()
}
}
return bDataArray
}
But it did not work and show null after apply converted byteArray to BitmapFactory.decodeByteArray
Working fine by applying similar logic in IOS              
let array = imageData.description.split(separator: " ")                               
var imageBytes : [UInt8] = []               
array.forEach({ (substringData) in                   
let stringData = String(substringData)                   
if let intData = UInt8(stringData) {                       
imageBytes.append(intData)                   
}               
})
               
let parsedImageData = NSData(bytes: imageBytes, length: imageBytes.count)

How can i change this code To AsyncTask?

I'm tryin to do Socket program between Java(pc) and Android.APP selects a image from gallery.Displays the image which i selected.And send to Java pc with socket.I want change this code to AsyncTask but i couldnt do it.i read about example about AsyncTask but how can i turn this code.Can anyone help me to solve this problem?
public class SendfileActivity extends Activity {
/** Called when the activity is first created. */
private static final int SELECT_PICTURE = 1;
private String selectedImagePath;
private ImageView img;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("34");
img = (ImageView) findViewById(R.id.ivPic);
System.out.println("36");
((Button) findViewById(R.id.bBrowse))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
System.out.println("40");
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Select Picture"),
SELECT_PICTURE);
System.out.println("47");
}
});
;
System.out.println("51");
Button send = (Button) findViewById(R.id.bSend);
final TextView status = (TextView) findViewById(R.id.tvStatus);
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Socket sock;
try {
sock = new Socket("192.168.0.3", 27015);
System.out.println("Connecting...");
// sendfile
File myFile = new File (selectedImagePath);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
sock.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
TextView path = (TextView) findViewById(R.id.tvPath);
path.setText("Image Path : " + selectedImagePath);
img.setImageURI(selectedImageUri);
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}
AsyncTask is not required for socket communication in here as there is no UI element is touched. Instead you can use Thread and Runnable.
If there is constant message passing between Client and Server then one can use combination of HandlerThread and Handlerto make it happen.
For simple Thread usage in here you can :
class SocketThread implements Runnable {
#Override
public void run() {
Socket sock;
try {
sock = new Socket("192.168.0.3", 27015);
System.out.println("Connecting...");
// sendfile
File myFile = new File(selectedImagePath);
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray, 0, mybytearray.length);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray, 0, mybytearray.length);
os.flush();
sock.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
and can start this runnable on onClick of send button
new Thread(new SocketThread()).start();
I hope this helps
If you do want to use an AsyncTask:
public class ImagePicker extends AsyncTask<String, String, String> {
     protected String doInBackground(String imgPath) {
//Your socket code here from the onclick
     }
protected void onProgressUpdate(String progressString) {
System.out.println("Sending...");
     }
     protected void onPostExecute(String result) {
// print result
sock.close();
     }
 }
And then you can execute the task in your onclick:
send.setOnClickListener{
new ImagePicker().execute(imgPathString);
}

How can i restore my database to its original directory?

Here is the code to save/copy my data in to SDcard,when i click on Backup Button my database saved in sdcard in NOTEIT directory and now i want to restore this database when i click on restore button into my default directory so can anyone tell me how to achieve this?
public static void backupDatabase() throws IOException
{
try
{
File dbFile = new File(Environment.getDataDirectory() + "/data/com.neelrazin.noteit/databases/data");
File exportDir = new File(Environment.getExternalStorageDirectory()+"/NOTEIT");
if (!exportDir.exists())
{
exportDir.mkdirs();
}
File file = new File(exportDir, dbFile.getName());
file.createNewFile();
FileChannel inChannel = new FileInputStream(dbFile).getChannel(); //fails here
FileChannel outChannel = new FileOutputStream(file).getChannel();
try
{
inChannel.transferTo(0, inChannel.size(), outChannel);
}
finally
{
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
I believe the restore is an exact opposite of your backup.
Like this:
public static void restoreDatabase() throws IOException
{
try
{
File dbFile = new File(Environment.getDataDirectory() + "/data/com.neelrazin.noteit/databases/data");
File importDir = new File(Environment.getExternalStorageDirectory()+"/NOTEIT");
if (!importDir.exists())
{
throw new IOException("External 'NOTEIT' directory does not exist.");
return;
}
File file = new File(importDir, dbFile.getName());
if (!file.exists()) 
{
    throw new IOException("Does not exist external db file: NOTEIT/" + dbFile.getName());
    return;
}
FileChannel outChannel = new FileOutputStream(dbFile).getChannel();
FileChannel inChannel = new FileInputStream(file).getChannel();
try
{
inChannel.transferTo(0, inChannel.size(), outChannel);
}
finally
{
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}

How to create a file in the internal storage only during the installation process?

I would like to know how to create a file in the internal storage only during the .apk installing.
My problem is that when I put the file with the onCreate method of MainActivity, everytime I relaunch the application, the content of my file is deleted.
I also tried to use file.exists but it didn't help.
Here is the code I'm using :
public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       Internal internal = new Internal();
       String file_name = "profil1.txt";
       String file_name1 = "profil2.txt";
       File f = new File(file_name);
       try {
           if(f.exists()){
           Log.d(TAG, "les fichiers sont deja cree");
           }else {
               FileOutputStream fos = openFileOutput(file_name, Context.MODE_WORLD_WRITEABLE);
               FileOutputStream fos1 = openFileOutput(file_name1, Context.MODE_WORLD_WRITEABLE);    
               
           }
       } catch (FileNotFoundException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }
       File file =getFilesDir();
       Log.d("TAG", file.getAbsolutePath());
       Path = file.getAbsolutePath();
       //internal.setFile();
       setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
       setContentView(R.layout.main_grid);
       mGrid = (GridView) findViewById(R.id.gridview);
       mGrid.setColumnWidth(95);
       mGrid.setVisibility(0x00000000);
       // content.dispatchSystemUiVisibilityChanged(BIND_ADJUST_WITH_ACTIVITY);
       registerIntentReceivers();
       // requestWindowFeature(Window.FEATURE_NO_TITLE);
       appManager = new ApplicationManager(this, getPackageManager());
       appManager.loadApplications(true);
       
       bindApplications();
       bindButtons();
       // Try to find activity to auto-start on create.
       int i = 0;
       while (i < APPLICATION_START_NAMES.length) {
           Intent startIntent = appManager
                   .getIntentByName(APPLICATION_START_NAMES[i]);
           if (startIntent != null) {
               // Found it, let's start and continue.
               startActivity(startIntent);
               break;
           }
           i++;
           Log.d("TAG", "application number" + i);
           // we will try to hid the stat bar temporory because to hid it w e
           // neeed root acces
           getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                   WindowManager.LayoutParams.FLAG_FULLSCREEN);
       }
       // Administrat.SINGLETON.init(this);
   }
You can't execute code during installation. The code you've got in onCreate() is almost right. The problem is that when you check the existence of the file, you haven't said where to look for it. You need to specify the application's private directory. Try this:
String file_name = "profil1.txt";
String file_name1 = "profil2.txt";
File f = new File(getFilesDir(), file_name); // File in the private directory
try {
if(f.exists()){
...
}
}

Saving jpg to file messes it up

When I save and load a jpg image (with a white background) to external storage, it looks like this:
The code:
Save:
try {
outStream = new FileOutputStream(fileUri);
image.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
        outStream.flush();
      outStream.close();
} catch (Exception e) {
Log.e("cache", e.getMessage());
e.printStackTrace();
}
Load:
Bitmap bm = BitmapFactory.decodeFile(fileUri.toString());
What am I doing wrong? Thanks.
This is the code I use (should work for you):
Save Bitmap:
public void writeBitmapToMemory(String filename, Bitmap bitmap) {
FileOutputStream fos;
// Use the compress method on the Bitmap object to write image to the OutputStream
try {
fos = game.openFileOutput(filename, Context.MODE_PRIVATE);
// Writing the bitmap to the output stream
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
And to read:
public Bitmap readBitmapFromMemory(String filename) {
Bitmap defautBitmap = null;
File filePath = game.getFileStreamPath(filename);
FileInputStream fi;
try {
fi = new FileInputStream(filePath);
defautBitmap = BitmapFactory.decodeStream(fi);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
return defautBitmap;
}

Categories

Resources