[APP][XPOSED][7.0+] WeiJu2 - Scriptable Xposed Module

Search This thread

wanting2521

New member
Oct 1, 2022
4
0
File access causes me a lot of headache, and current implementation still have some flaw it.

Why would want load script from file?

ref: https://github.com/ikws4/WeiJu2/issues/7#issuecomment-1248109818
I have multiple devices and code on computer will be a lot faster than Android.

Currently I try to override function getAllCellInfo of TelephonyManager class.
But the return is a List<CellInfo>. I don't know how to write the return for a List. Could you help me, please? Both return=List and return=List<CellInfo> doesn't work :(

Code:
local TelephonyManager = import("android.telephony.TelephonyManager")
local List = import("java.util.List")

hook {
  class = TelephonyManager,
  returns = List,
  method = "getAllCellInfo",
  params = {
  },
  replace = function(this, params)
    return nil
  end,
}

Thank you in advance.
 

VD171

Senior Member
Jun 21, 2012
2,935
2
2,172
127.0.0.1
LG K10
Samsung Galaxy J7
Great app !
Certainly, I will give a try.
I Love XPrivacyLua but it doesn't provide a full integration from Lua to Java.

I have two questions:
Can I set specific hooks to specific apps or all hooks are applied to all apps ?
Can I set variables on hooks and then set a different variable for each app ?
 
Last edited:

zhipingne

Member
Mar 20, 2018
22
34
I have multiple devices and code on computer will be a lot faster than Android.

Currently I try to override function getAllCellInfo of TelephonyManager class.
But the return is a List<CellInfo>. I don't know how to write the return for a List. Could you help me, please? Both return=List and return=List<CellInfo> doesn't work :(

Code:
local TelephonyManager = import("android.telephony.TelephonyManager")
local List = import("java.util.List")

hook {
  class = TelephonyManager,
  returns = List,
  method = "getAllCellInfo",
  params = {
  },
  replace = function(this, params)
    return nil
  end,
}

Thank you in advance.

Try this one, If it doesn't work, could you paste the debug log?
Code:
local TelephonyManager = import("android.telephony.TelephonyManager")
local ArrayList = import("java.util.ArrayList")
local List = import("java.util.List")


hook {
  class = TelephonyManager,
  returns = List,
  method = "getAllCellInfo",
  replace = function(this, params)
    local ret = ArrayList()
    return ret
  end,
}
 
  • Like
Reactions: wanting2521

zhipingne

Member
Mar 20, 2018
22
34
Can I set specific hooks to specific apps or all hooks are applied to all apps ?
For now, the workflow is you write a script for a specific app. But I am prepare to implement a "global app" feature (the script you write can be injected for all other apps).


Can I set variables on hooks and then set a different variable for each app ?
Yes, this is what the WeiJu2's package feature made for, you can import any script.
check them out on https://github.com/ikws4/WeiJu2-Scripts
 

wanting2521

New member
Oct 1, 2022
4
0
Try this one, If it doesn't work, could you paste the debug log?
Code:
local TelephonyManager = import("android.telephony.TelephonyManager")
local ArrayList = import("java.util.ArrayList")
local List = import("java.util.List")


hook {
  class = TelephonyManager,
  returns = List,
  method = "getAllCellInfo",
  replace = function(this, params)
    local ret = ArrayList()
    return ret
  end,
}
Thank you. It works after I change List to ArrayList :D

One more thing, Can I view or copy 'My Scripts' directly from Android Studio/computer, instead of editing directly from Weiju app?
I mean the path to 'My Scripts' on the device, so we can copy/paste the script?
 

zhipingne

Member
Mar 20, 2018
22
34
Thank you. It works after I change List to ArrayList :D

One more thing, Can I view or copy 'My Scripts' directly from Android Studio/computer, instead of editing directly from Weiju app?
I mean the path to 'My Scripts' on the device, so we can copy/paste the script?
Can or can't that depends you, for now the script are save inside a share preferences called `script_store`, and script are encoded in base64, you can take look at it.
 
  • Like
Reactions: wanting2521

wanting2521

New member
Oct 1, 2022
4
0
Can or can't that depends you, for now the script are save inside a share preferences called `script_store`, and script are encoded in base64, you can take look at it.
Strangely, I check both path:
- data/data/io.ikws4.weiju
- /data/user_de/0/io.ikws4.weiju
But no shared_prefs folder there. where can it be, sir? :(
 

Attachments

  • Untitled.png
    Untitled.png
    36.8 KB · Views: 39

zhipingne

Member
Mar 20, 2018
22
34
Strangely, I check both path:
- data/data/io.ikws4.weiju
- /data/user_de/0/io.ikws4.weiju
But no shared_prefs folder there. where can it be, sir? :(

Oops, I recall that, the XSharedPreferences was store in a random path, tricky

To read the preference from the hooked app, you can simply use XSharedPreferences(String packageName) or XSharedPreferences(String packageName, String prefFileName) to retrieve the preference. Notice that you cannot use the XSharedPreferences(File prefFile) because the preference file is stored in a random directory.
 

VD171

Senior Member
Jun 21, 2012
2,935
2
2,172
127.0.0.1
LG K10
Samsung Galaxy J7
For now, the workflow is you write a script for a specific app. But I am prepare to implement a "global app" feature (the script you write can be injected for all other apps).


Yes, this is what the WeiJu2's package feature made for, you can import any script.
check them out on https://github.com/ikws4/WeiJu2-Scripts
Nice !
Definitely, global scripts are totally useful.

About package feature, why not some place/activity for setting each variable for each app, like XPrivacyLua Pro feature? Instead of opening and editting each script.
 

Attachments

  • Screenshot_2022-12-10-12-39-40-800_eu.faircode.xlua.pro.jpg
    Screenshot_2022-12-10-12-39-40-800_eu.faircode.xlua.pro.jpg
    96.1 KB · Views: 54
  • Screenshot_2022-12-10-12-39-50-253_eu.faircode.xlua.pro.jpg
    Screenshot_2022-12-10-12-39-50-253_eu.faircode.xlua.pro.jpg
    120.8 KB · Views: 52

zhipingne

Member
Mar 20, 2018
22
34
Nice !
Definitely, global scripts are totally useful.

About package feature, why not some place/activity for setting each variable for each app, like XPrivacyLua Pro feature? Instead of opening and editting each script.
Not a big fan of making these ui, I think using code to define the behaviors is much better way to manage configurations and it gives the user more flexibility.
 
Last edited:

Schroeder09

Senior Member
Nov 6, 2017
1,089
198
Google Pixel 7 Pro
Anyone having any interesting use case for this that they have been using? This looked really exciting when it came out. Idk enough about hooks to write them myself though.
 

anuraag.neo

Senior Member
Aug 7, 2013
96
56
After some investigating, I found that it has many custom parameters and other stuff going on, so creating a complete compatible converter would be very difficult. Therefore, I probably won’t work on it, sorry.
ok but there is a hook which i wonder how to do.

Code:
      "className": "android.content.Intent",
      "methodName": "CREATOR:createFromParcel",
      "parameterTypes": [
        "android.os.Parcel"
      ],
      "returnType": "android.content.Intent",

It's hooking intent.

Another one
Code:
      "className": "android.content.ClipData",
      "methodName": "CREATOR:createFromParcel",
      "parameterTypes": [
        "android.os.Parcel"
      ],
      "returnType": "android.content.ClipData",
 

zhipingne

Member
Mar 20, 2018
22
34
ok but there is a hook which i wonder how to do.

Code:
      "className": "android.content.Intent",
      "methodName": "CREATOR:createFromParcel",
      "parameterTypes": [
        "android.os.Parcel"
      ],
      "returnType": "android.content.Intent",

It's hooking intent.

Another one
Code:
      "className": "android.content.ClipData",
      "methodName": "CREATOR:createFromParcel",
      "parameterTypes": [
        "android.os.Parcel"
      ],
      "returnType": "android.content.ClipData",

Code:
local Intent = import("android.content.Intent")
local Parcel = import("android.os.Parcel")
local ClipData = import("android.content.ClipData")

hook {
  class = Intent.CREATOR:getClass(),
  returns = Intent,
  method = "createFromParcel",
  params = {
    Parcel
  },
  replace = function(this, params)
    print("replace Intent.CREATOR.createFromParcel")
    return Intent(params[1])
  end
}

hook {
  class = ClipData.CREATOR:getClass(),
  returns = ClipData,
  method = "createFromParcel",
  params = {
    Parcel
  },
  replace = function(this, params)
    print("replace ClipData.CREATOR.createFromParcel")
    return Intent(params[1])
  end
}

Refs:
 

anuraag.neo

Senior Member
Aug 7, 2013
96
56
Code:
local Intent = import("android.content.Intent")
local Parcel = import("android.os.Parcel")
local ClipData = import("android.content.ClipData")

hook {
  class = Intent.CREATOR:getClass(),
  returns = Intent,
  method = "createFromParcel",
  params = {
    Parcel
  },
  replace = function(this, params)
    print("replace Intent.CREATOR.createFromParcel")
    return Intent(params[1])
  end
}

hook {
  class = ClipData.CREATOR:getClass(),
  returns = ClipData,
  method = "createFromParcel",
  params = {
    Parcel
  },
  replace = function(this, params)
    print("replace ClipData.CREATOR.createFromParcel")
    return Intent(params[1])
  end
}
Thanks for this but I'm still struggling to find Intent action. XprivicyLua has getResult() function which returns Intent.

I think below code will give me action?
Code:
Intent(params[1]):getAction()
 
Last edited:

zhipingne

Member
Mar 20, 2018
22
34
Thanks for this but I'm still struggling to find Intent action. XprivicyLua has getResult() function which returns Intent.

I think below code will give me action?
Code:
Intent(params[1]):getAction()

Try this snippet, If any error please send to me.
Code:
local Intent = import("android.content.Intent")
local Parcel = import("android.os.Parcel")

hook {
  class = Intent.CREATOR:getClass(),
  returns = Intent,
  method = "createFromParcel",
  params = {
    Parcel
  },
  replace = function(this, params)
    print("replace Intent.CREATOR.createFromParcel")
    local ret = Intent(params[1])
    print("action " .. ret:getAction())
    return ret
  end
}

Here maybe is what you want, but now WeiJu2 cannot read the method's original return value `ret' for now (this is a bug I'll fix it later)
Code:
local Intent = import("android.content.Intent")
local Parcel = import("android.os.Parcel")

hook {
  class = Intent.CREATOR:getClass(),
  returns = Intent,
  method = "createFromParcel",
  params = {
    Parcel
  },
  --                                   Not Implemented: Should have access for original return value
  --                                                v
  after = function(this, params, ret)
    print("action " .. ret:getAction())
    return ret
  end
}
 

Top Liked Posts

  • There are no posts matching your filters.
  • 2
    ok but there is a hook which i wonder how to do.

    Code:
          "className": "android.content.Intent",
          "methodName": "CREATOR:createFromParcel",
          "parameterTypes": [
            "android.os.Parcel"
          ],
          "returnType": "android.content.Intent",

    It's hooking intent.

    Another one
    Code:
          "className": "android.content.ClipData",
          "methodName": "CREATOR:createFromParcel",
          "parameterTypes": [
            "android.os.Parcel"
          ],
          "returnType": "android.content.ClipData",

    Code:
    local Intent = import("android.content.Intent")
    local Parcel = import("android.os.Parcel")
    local ClipData = import("android.content.ClipData")
    
    hook {
      class = Intent.CREATOR:getClass(),
      returns = Intent,
      method = "createFromParcel",
      params = {
        Parcel
      },
      replace = function(this, params)
        print("replace Intent.CREATOR.createFromParcel")
        return Intent(params[1])
      end
    }
    
    hook {
      class = ClipData.CREATOR:getClass(),
      returns = ClipData,
      method = "createFromParcel",
      params = {
        Parcel
      },
      replace = function(this, params)
        print("replace ClipData.CREATOR.createFromParcel")
        return Intent(params[1])
      end
    }

    Refs:
    2
    Thanks for this but I'm still struggling to find Intent action. XprivicyLua has getResult() function which returns Intent.

    I think below code will give me action?
    Code:
    Intent(params[1]):getAction()

    Try this snippet, If any error please send to me.
    Code:
    local Intent = import("android.content.Intent")
    local Parcel = import("android.os.Parcel")
    
    hook {
      class = Intent.CREATOR:getClass(),
      returns = Intent,
      method = "createFromParcel",
      params = {
        Parcel
      },
      replace = function(this, params)
        print("replace Intent.CREATOR.createFromParcel")
        local ret = Intent(params[1])
        print("action " .. ret:getAction())
        return ret
      end
    }

    Here maybe is what you want, but now WeiJu2 cannot read the method's original return value `ret' for now (this is a bug I'll fix it later)
    Code:
    local Intent = import("android.content.Intent")
    local Parcel = import("android.os.Parcel")
    
    hook {
      class = Intent.CREATOR:getClass(),
      returns = Intent,
      method = "createFromParcel",
      params = {
        Parcel
      },
      --                                   Not Implemented: Should have access for original return value
      --                                                v
      after = function(this, params, ret)
        print("action " .. ret:getAction())
        return ret
      end
    }
    1
    After some investigating, I found that it has many custom parameters and other stuff going on, so creating a complete compatible converter would be very difficult. Therefore, I probably won’t work on it, sorry.
    1
    Try this snippet, If any error please send to me.
    Code:
    local Intent = import("android.content.Intent")
    local Parcel = import("android.os.Parcel")
    
    hook {
      class = Intent.CREATOR:getClass(),
      returns = Intent,
      method = "createFromParcel",
      params = {
        Parcel
      },
      replace = function(this, params)
        print("replace Intent.CREATOR.createFromParcel")
        local ret = Intent(params[1])
        print("action " .. ret:getAction())
        return ret
      end
    }

    Here maybe is what you want, but now WeiJu2 cannot read the method's original return value `ret' for now (this is a bug I'll fix it later)
    Code:
    local Intent = import("android.content.Intent")
    local Parcel = import("android.os.Parcel")
    
    hook {
      class = Intent.CREATOR:getClass(),
      returns = Intent,
      method = "createFromParcel",
      params = {
        Parcel
      },
      --                                   Not Implemented: Should have access for original return value
      --                                                v
      after = function(this, params, ret)
        print("action " .. ret:getAction())
        return ret
      end
    }

    Wrap up you code inside a other hook will do.
    Code:
    local Intent = import("android.content.Intent")
    local Parcel = import("android.os.Parcel")
    local Application = import("android.app.Application")
    
    hook {
      class = Application,
      returns = void,
      method = "onCreate",
      -- if won't work, try replace `before` with `after`
      before = function(this, params)
        local applicationContext = this
    
        hook {
          class = Intent.CREATOR:getClass(),
          returns = Intent,
          method = "createFromParcel",
          params = {
            Parcel
          },
          replace = function(this, params)
            print("replace Intent.CREATOR.createFromParcel")
            local ret = Intent(params[1])
            print("action " .. ret:getAction())
            print("context " .. applicationContext)
            return ret
          end
        }
      end
    }
    1
    Thanks for all help. I'll use this when needed.

    There is one thing i dislike that when a script is need to apply on multiple apps then we have to create same script multiple times. Can you make it automatically available in Available Scripts for other apps or something better?

    Edit: Ok there is Global scope option. So that might work.

    Edit2: There is some serious bug present where your app unable to save preferences, scripts. On restarting app loads some old state.

    For Edit2: I couldn't reproduce this on my devices. Please make sure when you modify scripts WeiJu2 was checked in LSPosed, because the scripts are save at two different path in the active and non-active states.
  • 7
    logo_white.png


    The first scriptable xposed module, provides a new way to change the application behavior.

    Powered by Lua and made with ♥

    Features​

    • Lua scripting
    • Simple and intuitive hook API
    • Share your package with others by publish it at WeiJu2-Scripts

    Q&A​

    How to write a hook?​

    Code:
    local Toast = import("android.widget.Toast")
    local Activity = import("android.app.Activity")
    local Bundle = import("android.os.Bundle")
    local StringBuilder = import("java.lang.StringBuilder")
    
    hook {
      class = Activity,
      returns = void,
      method = "onCreate",
      params = {
        Bundle
      },
      after = function(this, params)
        -- This will call the `StringBuilder(CharSequence seq)` constructor
        -- to instantiate a StringBuilder object
        local sb = StringBuilder("Hello, ")
        sb:append("WeiJu2")
     
        Toast:makeText(this, sb:toString(), Toast.LENGTH_SHORT):show()
        --              ^
        -- Note: `this` is the Activity instance
      end,
    }


    How to modify class fields?​

    Code:
    -- With the `import` function you can bind any java class, and access all the fields and methods that defined
    -- in that class. No more `XposedHelper.setStaticObjectField(Build.class, "DEVICE", "coral")` much cleaner!
    local Build = import("android.os.Build")
    
    Build.DEVICE = "coral"
    Build.PRODUCT = "coral"
    Build.MODEL = "Google Pixel 4XL"
    Build.BRAND = "google"
    Build.MANUFACTURER = "google"
    Build.VERSION.RELEASE = "13"

    How to import a package?​

    Code:
    require("ikws4.system_variable").setup {
      -- configs goes here
    }


    How to create a package?​


    A basic package template:

    Code:
    --[[
    @metadata
      return {
        name = "my_package",
        author = "you",
        version = "1.0.0",
        description = "Describle your package"
      }
    @end
    --]]
    
    local config = {
    }
    
    local M = {}
    
    M.setup = function(opts)
      config = table.extend(config, opts or {})
    end
    
    return M


    Want to share your work with others? Create a PR at WeiJu2-Scripts

    Screenshots​

    183251553-9dce66f7-953c-45b9-b741-0ae8e0b567af.png



    Video guide​


    Download​

    Github release: nightly build
    5
    Code:
    {
          "builtin": false,
          "collection": "Privacy",
          "group": "Use.Tracking",
          "name": "DeviceIntegrityCheck\/checkIntegrity",
          "author": "B!",
          "version": 0,
          "description": "Skip asitplus device integrity check",
          "className": "at.asitplus.utils.deviceintegrity.DeviceIntegrityCheck",
          "methodName": "checkIntegrity",
          "parameterTypes": [],
          "returnType": "void",
          "minSdk": 1,
          "maxSdk": 999,
          "minApk": 0,
          "maxApk": 2147483647,
          "enabled": true,
          "optional": false,
          "usage": true,
          "notify": false,
          "luaScript": "function before(hook, param)\n  param:setResult(nil)\n  return true\nend\n"
        }

    (Thanks to B!GBOY)

    Is it possible to run such a XPrivacyLua script? If so, how formatted?


    Code:
    local DeviceIntegrityCheck = import("at.asitplus.utils.deviceintegrity.DeviceIntegrityCheck")
    
    hook {
      class = DeviceIntegrityCheck,
      returns = void,
      method = "checkIntegrity",
      before = function(this, params)
        return nil
      end
    }

    Maybe, I can write a convertor for this.
    2
    The version is not available...
    I'm sorry for the late response.
    What do you mean not available? Is it can not be downloaded?
    If so, here is the google drive link https://drive.google.com/file/d/1upurJDTJ5nS3RodsqLTCJKFg9daN4EaH/view?usp=sharing
    2
    Code:
    {
          "builtin": false,
          "collection": "Privacy",
          "group": "Use.Tracking",
          "name": "DeviceIntegrityCheck\/checkIntegrity",
          "author": "B!",
          "version": 0,
          "description": "Skip asitplus device integrity check",
          "className": "at.asitplus.utils.deviceintegrity.DeviceIntegrityCheck",
          "methodName": "checkIntegrity",
          "parameterTypes": [],
          "returnType": "void",
          "minSdk": 1,
          "maxSdk": 999,
          "minApk": 0,
          "maxApk": 2147483647,
          "enabled": true,
          "optional": false,
          "usage": true,
          "notify": false,
          "luaScript": "function before(hook, param)\n  param:setResult(nil)\n  return true\nend\n"
        }

    (Thanks to B!GBOY)

    Is it possible to run such a XPrivacyLua script? If so, how formatted?
    2
    @zhipingne
    Awesome. Worked right away. Thank you very much!