0% found this document useful (0 votes)
403 views7 pages

Development Tutorial Rovo89 - XposedBridge Wiki GitHub PDF

If you want to learn how you can create a new module for Xposed, then read this tutorial. This includes not only the technical "create this file and insert." but also the thinking behind it, which is the step where value is created. You will recreate the red clock example that can be found at Github as well.

Uploaded by

MelodySong
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
403 views7 pages

Development Tutorial Rovo89 - XposedBridge Wiki GitHub PDF

If you want to learn how you can create a new module for Xposed, then read this tutorial. This includes not only the technical "create this file and insert." but also the thinking behind it, which is the step where value is created. You will recreate the red clock example that can be found at Github as well.

Uploaded by

MelodySong
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

9/30/2015

Developmenttutorialrovo89/XposedBridgeWikiGitHub
Thisrepository Search

Explore

Features

Enterprise

rovo89 / XposedBridge

Pricing

Watch

Signup

Star

151

Developmenttutorial

792

Signin

Fork

312

rovo89editedthispageonAug13,201411revisions

Alright..youwanttolearnhowyoucancreateanewmoduleforXposed?Thenreadthis
tutorial(orlet'srathercallit"extensiveessay")andlearnhowtoapproachthis.This
includesnotonlythetechnical"createthisfileandinsert...",butalsothethinkingbehind

Pages

Home

it,whichisthestepwherevalueiscreatedandforwhichyoureallyneedtounderstand

Developmenttutorial

whatyoudoandwhy.Ifyoufeellike"TLDR",youcanjustlookatthefinalsourcecode

Helpers

andreadthe"MakingtheprojectanXposedmodule"chapter.Butyouwillgetabetter

Replacingresources

understandingifyoureadthewholetutorial.Youwillsavethetimespentforreadingthis
laterbecauseyoudon'thavetofigureeverythingoutyourself.

Clonethiswikilocally
https://github.com/rovo89/XposedBridge.wiki.git

Themodificationsubject

CloneinDesktop

YouwillrecreatetheredclockexamplethatcanbefoundatGithubaswell.Itincludes
changingthecolorofthestatusbarclocktoredandaddingasmiley.I'mchoosingthis
examplebecauseitisarathersmall,buteasilyvisiblechange.Also,itusessomeofthe
basicmethodsprovidedbytheframework.

HowXposedworks
Beforebeginningwithyourmodification,youshouldgetaroughideahowXposedworks
(youmightskipthissectionthoughifyoufeeltoobored).Hereishow:
Thereisaprocessthatiscalled"Zygote".ThisistheheartoftheAndroidruntime.Every
applicationisstartedasacopy("fork")ofit.Thisprocessisstartedbyan/init.rcscript
whenthephoneisbooted.Theprocessstartisdonewith/system/bin/app_process,
whichloadstheneededclassesandinvokestheinitializationmethods.
ThisiswhereXposedcomesintoplay.Whenyouinstalltheframework,anextended
app_processexecutableiscopiedto/system/bin.Thisextendedstartupprocessaddsan
additionaljartotheclasspathandcallsmethodsfromthereatcertainplaces.For
instance,justaftertheVMhasbeencreated,evenbeforethemainmethodofZygotehas
beencalled.Andinsidethatmethod,wearepartofZygoteandcanactinitscontext.
Thejarislocatedat/data/data/de.robv.android.xposed.installer/bin/XposedBridge.jar
anditssourcecodecanbefoundhere.LookingattheclassXposedBridge,youcansee
themainmethod.ThisiswhatIwroteaboutabove,thisgetscalledintheverybeginning
oftheprocess.Someinitializationsaredonethereandalsothemodulesareloaded(Iwill
comebacktomoduleloadinglater).

Methodhooking/replacing
WhatreallycreatesthepowerofXposedisthepossibilityto"hook"methodcalls.When
youdoamodificationbydecompilinganAPK,youcaninsert/changecommandsdirectly
whereveryouwant.However,youwillneedtorecompile/signtheAPKafterwardsandyou
canonlydistributethewholepackage.WiththehooksyoucanplacewithXposed,you
can'tmodifythecodeinsidemethods(itwouldbeimpossibletodefineclearlywhatkindof
changesyouwanttodoinwhichplace).Instead,youcaninjectyourowncodebeforeand
aftermethods,whicharethesmallestunitinJavathatcanbeaddressedclearly.
https://github.com/rovo89/XposedBridge/wiki/Developmenttutorial

1/7

9/30/2015

Developmenttutorialrovo89/XposedBridgeWikiGitHub

XposedBridgehasaprivate,nativemethodhookMethodNative.Thismethodis
implementedintheextendedapp_processaswell.Itwillchangethemethodtypeto
"native"andlinkthemethodimplementationtoitsownnative,genericmethod.That
meansthateverytimethehookedmethodiscalled,thegenericmethodwillbecalled
insteadwithoutthecallerknowingaboutit.Inthismethod,themethod
handleHookedMethodinXposedBridgeiscalled,passingovertheargumentstothemethod

call,thethisreferenceetc.Andthismethodthentakescareofinvokingcallbacksthat
havebeenregisteredforthismethodcall.Thosecanchangetheargumentsforthecall,
changeinstance/staticvariables,invokeothermethods,dosomethingwiththeresult...or
skipanythingofthat.Itisveryflexible.
Ok,enoughtheory.Let'screateamodulenow!

Creatingtheproject
Amoduleisnormalapp,justwithsomespecialmetadataandfiles.Sobeginwithcreating
anewAndroidproject.Iassumeyouhavealreadydonethisbefore.Ifnot,theofficial
documentationisquitedetailed.WhenaskedfortheSDK,Ichose4.0.3(API15).I
suggestyoutrythisaswellanddonotstartexperimentsyet.Youdon'tneedtocreatean
activitybecausethemodificationdoesnothaveanyuserinterface.Afteransweringthat
question,youshouldhaveablankproject.

MakingtheprojectanXposed
module
Nowlet'sturntheprojectintosomethingloadedbyXposed,amodule.Severalstepsare
requiredforthis.

AndroidManifest.xml
ThemodulelistintheXposedInstallerlooksforapplicationswithaspecialmetadataflag.
YoucancreateitbygoingtoAndroidManifest.xml=>Application=>ApplicationNodes(at
thebottom)=>Add=>MetaData.Thenameshouldbexposedmoduleandthevalue
true.Leavetheresourceempty.Thenrepeatthesameforxposedminversion(see

below)andxposeddescription(averyshortdescriptionofyourmodule).TheXMLsource
willnowlooklikethis:
<?xmlversion="1.0"encoding="utf8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="de.robv.android.xposed.mods.tutorial"
android:versionCode="1"
android:versionName="1.0">
<usessdkandroid:minSdkVersion="15"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<metadata
android:name="xposedmodule"
android:value="true"/>
<metadata
android:name="xposeddescription"
android:value="Easyexamplewhichmakesthestatusbarclockredandaddsasmiley
<metadata
android:name="xposedminversion"
android:value="30"/>
</application>
</manifest>

https://github.com/rovo89/XposedBridge/wiki/Developmenttutorial

2/7

9/30/2015

Developmenttutorialrovo89/XposedBridgeWikiGitHub

XposedBridgeApi.jar
Next,maketheXposedBridgeAPIknowntotheproject.Youcandownload
XposedBridgeApi<version>.jarfromthefirstpostofthisXDAthread.Copyitintoa

subfoldercalledlib.ThenrightclickonitandselectBuildPath=>AddtoBuildPath.
The<version>fromthefilenameistheoneyouinsertasxposedminversioninthe
manifest.
MakesurethattheAPIclassesarenotincluded(butonlyreferenced)inyour
compiledAPK,otherwiseyouwillgetanIllegalAccessError.Filesinthelibs(with
"s")folderareautomaticallyincludedbyEclipse,sodon'tputtheAPIfilethere.

Moduleimplementation
Nowyoucancreateaclassforyourmodule.Mineisnamed"Tutorial"andisinthe
packagede.robv.android.xposed.mods.tutorial:
packagede.robv.android.xposed.mods.tutorial;
publicclassTutorial{
}

Forthefirststep,wewilljustdosomeloggingtoshowthatthemodulewasloaded.A
modulecanhaveafewentrypoints.Whichone(s)youchoosedependsonthewhatyou
wanttomodify.YoucanhaveXposedcallafunctioninyourmodulewhentheAndroid
systemboots,whenanewappisabouttobeloaded,whentheresourcesforanappare
initialisedandsoon.
Abitfurtherdownthistutorial,youwilllearnthatthenecessarychangesneedtobedone
inonespecificapp,solet'sgowiththe"letmeknowwhenanewappisloaded"entry
point.AllentrypointsaremarkedwithasubinterfaceofIXposedMod.Inthiscase,it's
IXposedHookLoadPackagewhichyouneedtoimplement.It'sactuallyjustonemethod
withoneparameterthatgivesmoreinformationaboutthecontexttotheimplementing
module.Inourexample,let'slogthenameoftheloadedapp:
packagede.robv.android.xposed.mods.tutorial;
importde.robv.android.xposed.IXposedHookLoadPackage;
importde.robv.android.xposed.XposedBridge;
importde.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
publicclassTutorialimplementsIXposedHookLoadPackage{
publicvoidhandleLoadPackage(finalLoadPackageParamlpparam)throwsThrowable{
XposedBridge.log("Loadedapp:"+lpparam.packageName);
}
}

Thislogmethodwritesthemessagetothestandardlogcat(tagXposed)andto
/data/data/de.robv.android.xposed.installer/log/debug.log`(whichiseasilyaccessiblevia
theXposedInstaller).

assets/xposed_init
TheonlythingthatisstillmissingnowisahintforXposedBridgewhichclassescontain
suchentrypoints.Thisisdoneviaafilecalledxposed_init.Createanewtextfilewith
thatnameintheassetsfolder.Inthisfile,eachlinecontainsonefullyqualifiedclass
name.Inthiscase,thisisde.robv.android.xposed.mods.tutorial.Tutorial.

https://github.com/rovo89/XposedBridge/wiki/Developmenttutorial

3/7

9/30/2015

Developmenttutorialrovo89/XposedBridgeWikiGitHub

Tryingitout
Saveyourfiles.ThenrunyourprojectasAndroidapplication.Asthisisthefirsttimeyou
installit,youneedtoenableitbeforeyoucanuseit.OpentheXposedInstallerappand
makesureyouhaveinstalledtheframework.Thengotothe"Modules"tab.Youshould
findyourappinthere.Checktheboxtoenableit.Thenreboot.Youwillnotseea
differenceofcourse,butifyoucheckthelog,youshouldseesomethinglikethis:
LoadingXposed(forZygote)...
Loadingmodulesfrom/data/app/de.robv.android.xposed.mods.tutorial1.apk
Loadingclassde.robv.android.xposed.mods.tutorial.Tutorial
Loadedapp:com.android.systemui
Loadedapp:com.android.settings
...(manymoreappsfollow)

Voil!Thatworked.YounowhaveanXposedmodule.Itcouldjustbeabitmoreuseful
thanwritinglogs...

Exploringyourtargetandfindinga
waytomodifyit
Ok,sonowbeginsthepartthatcanbeverydifferentdependingonwhatyouwanttodo.If
youhavemoddedAPKsbefore,youprobablyknowhowtothinkhere.Ingeneral,youfirst
needtogetsomedetailsabouttheimplementationofthetarget.Inthistutorial,thetarget
istheclockinthestatusbar.Ithelpstoknowthatthestatusbarandlotsofotherthingsare
partoftheSystemUI.Solet'sbeginoursearchthere.
Possibilityone:Decompileit.Thiswillgiveyoutheexactimplementation,butitishardto
readandunderstandbecauseyougetsmaliformat.Possibilitytwo:GettheAOSP
sources(e.g.hereorhereandlookthere.ThiscanbequitedifferentfromyourROM,but
inthiscaseitisasimilaroreventhesameimplementation.IwouldlookatAOSPfirstand
seeifthatisenough.IfIneedmoredetails,lookattheactualdecompiledcode.
Youcanlookforclasseswith"clock"intheirnameorcontainingthatstring.Otherthings
tolookforareresourcesandlayoutused.IfyoudownloadedtheofficialAOSPcode,you
canstartlookinginframeworks/base/packages/SystemUI.Youwillfindquiteafewplaces
where"clock"appears.Thisisnormalandindeedtherewillbedifferentwaystoimplement
amodification.Keepinmindthatyoucan"only"hookmethods.Soyouhavetofinda
placewhereyoucaninsertsomecodetodothemagiceitherbefore,afterorreplacinga
method.Youshouldhookmethodsthatareasspecificaspossible,notonesthatare
calledthousandsoftimestoavoidperformanceissuesandunintendedsideeffects.
Inthiscase,youmightfindthatthelayoutres/layout/status_bar.xmlcontainsa
referencetoacustomviewwiththeclasscom.android.systemui.statusbar.policy.Clock.
Multipleideasmightcometoyourmindnow.Thetextcolorisdefinedviaa
textAppearanceattribute,sothecleanestwaytochangeitwouldbetochangethe

appearancedefinition.However,thethisisnotpossibletochangestyleswiththeXposed
frameworkandprobablywon'tbe(it'stoodeepinnativecode).Replacingthelayoutfor
thestatusbarwouldbepossible,butanoverkillforthesmallchangeyouaretryingto
make.Instead,lookatthisclass.ThereisamethodcalledupdateClock,whichseemsto
becalledeveryminutetoupdatethetime:
finalvoidupdateClock(){
mCalendar.setTimeInMillis(System.currentTimeMillis());
setText(getSmallTime());
}

https://github.com/rovo89/XposedBridge/wiki/Developmenttutorial

4/7

9/30/2015

Developmenttutorialrovo89/XposedBridgeWikiGitHub

Thatlooksperfectformodificationsbecauseitisaveryspecificmethodwhichseemsto
betheonlymeansofsettingthetextfortheclock.Ifweaddsomethingaftereverycallto
thismethodthatchangesthecolorandthetextoftheclock,thatshouldwork.Solet'sdo
it.
Forthetextcoloralone,thereisanevenbetterway.Seetheexamplefor"Modifying
layouts"on"Replacingresources".

Usingreflectiontofindandhooka
method
Whatdowealreadyknow?WehaveamethodupdateClockinclass
com.android.systemui.statusbar.policy.Clockthatwewanttointercept.Wefoundthis

classinsidetheSystemUIsources,soitwillonlybeavailableintheprocessforthe
SystemUI.Someotherclassesbelongtotheframeworkandareavailableeverywhere.If
wetriedtogetanyinformationandreferencestothisclassdirectlyinthe
handleLoadPackagemehod,thiswouldfailbecauseitisthewrongprocess.Solet's

implementaconditiontoexecutecertaincodeonlywhenaspecifiedpackageisaboutto
beloaded:
publicvoidhandleLoadPackage(LoadPackageParamlpparam)throwsThrowable{
if(!lpparam.packageName.equals("com.android.systemui"))
return;
XposedBridge.log("weareinSystemUI!");
}

Usingtheparameter,wecaneasilycheckifweareinthecorrectpackage.Oncewe
verifiedthat,wegetaccesstotheclassesinthatpackageswiththeClassLoaderwhichis
alsoreferencedfromthisvariable.Nowwecanlookforthe
com.android.systemui.statusbar.policy.ClockclassanditsupdateClockmethodandtell

XposedBridgetohookit:
packagede.robv.android.xposed.mods.tutorial;
importstaticde.robv.android.xposed.XposedHelpers.findAndHookMethod;
importde.robv.android.xposed.IXposedHookLoadPackage;
importde.robv.android.xposed.XC_MethodHook;
importde.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
publicclassTutorialimplementsIXposedHookLoadPackage{
publicvoidhandleLoadPackage(finalLoadPackageParamlpparam)throwsThrowable{
if(!lpparam.packageName.equals("com.android.systemui"))
return;
findAndHookMethod("com.android.systemui.statusbar.policy.Clock",lpparam.classLoader,
@Override
protectedvoidbeforeHookedMethod(MethodHookParamparam)throwsThrowable
//thiswillbecalledbeforetheclockwasupdatedbytheoriginalmethod
}
@Override
protectedvoidafterHookedMethod(MethodHookParamparam)throwsThrowable{
//thiswillbecalledaftertheclockwasupdatedbytheoriginalmethod
}
});
}
}

findAndHookMethodisahelperfunction.Notethestaticimport,whichisautomatically

addedifyouconfigureitasdescribedinthelinkedpage.ThismethodlooksuptheClock
https://github.com/rovo89/XposedBridge/wiki/Developmenttutorial

5/7

9/30/2015

Developmenttutorialrovo89/XposedBridgeWikiGitHub

classusingtheClassLoaderfortheSystemUIpackage.ThenitlooksfortheupdateClock
methodinit.Iftherewereanyparameterstothismethod,youwouldhavetolistthetypes
(classes)oftheseparametersafterwards.Therearedifferentwaystodothis,butasour
methoddoesn'thaveanyparameters,let'sskipthisfornow.Asthelastargument,you
needtoprovideanimplementationoftheXC_MethodHookclass.Forsmallermodifications,
youcanuseaanonymousclass.Ifyouhavemuchcode,it'sbettertocreateanormal
classandonlycreatetheinstancehere.Thehelperwillthendoeverythingnecessaryto
hookthemethodasdescribedabove.
TherearetwomethodsinXC_MethodHookthatyoucanoverride.Youcanoverridebothor
evennone,butthelattermakesabsolutelynosense.Thesemethodsare
beforeHookedMethodandafterHookedMethod.It'snottoohardtoguessthattheare

executedbefore/aftertheoriginalmethod.Youcanusethe"before"methodto
evaluate/manipulatetheparametersofthemethodcall(viaparam.args)andevenprevent
thecalltotheoriginalmethod(sendingyourownresult).The"after"methodcanbeused
todosomethingbasedontheresultoftheoriginalmethod.Youcanalsomanipulatethe
resultatthispoint.Andofcourse,youcanaddyourowncodewhichshouldbeexecuted
exactlybefore/afterthemethodcall.
Ifyouwanttoreplaceamethodcompletely,havealookatthesubclass
XC_MethodReplacementinstead,whereyoujustneedtooverride
replaceHookedMethod.

XposedBridgekeepsalistofregisteredcallbacksforeachhookedmethod.Thosewith
highestpriority(asdefinedinhookMethod)arecalledfirst.Theoriginalmethodhas
alwaysthelowestpriority.SoifyouhavehookedamethodwithcallbacksA(priohigh)
andB(priodefault),thenwheneverthehookedmethodiscalled,thecontrolflowwillbe
this:A.before>B.before>originalmethod>B.after>A.after.SoAcouldinfluencethe
argumentsBgetstosee,whichcouldfurtherchangethembeforepassingthemon.The
resultoftheoriginalmethodcanbeprocessedbyBfirst,butAhasthefinalwordwhatthe
originalcallergets.

Finalsteps:Executeyourowncode
before/afterthemethodcall
Alright,youhavenowamethodthatiscalledeverytimetheupdateClockmethodis
called,withexactlythatcontext(i.e.you'reintheSystemUIprocess).Nowlet'smodify
something.
Firstthingtocheck:DowehaveareferencetotheconcreteClockobject?Yeswehave,
it'sintheparam.thisObjectparameter.Soifthemethodwascalledwith
myClock.updateClock(),thenparam.thisObjectwouldbemyClock.

Next:Whatcanwedowiththeclock?TheClockclassisnotavailable,youcan'tcast
param.thisObjecttoclass(don'teventryto).HoweveritinheritsfromTextView.Soyou

canusemethodslikesetText,getTextandsetTextColoronceyouhavecastedthe
ClockreferencetoTextView.Thechangesshouldbedoneaftertheoriginalmethodhas

setthenewtime.Asthereisnothingtodobeforethemethodcall,wecanleaveoutthe
beforeHookedMethod.Callingthe(empty)"super"methodisnotnecessary.

Sohereisthecompletesourcecode:
packagede.robv.android.xposed.mods.tutorial;
importstaticde.robv.android.xposed.XposedHelpers.findAndHookMethod;
importandroid.graphics.Color;
importandroid.widget.TextView;
importde.robv.android.xposed.IXposedHookLoadPackage;
importde.robv.android.xposed.XC_MethodHook;

https://github.com/rovo89/XposedBridge/wiki/Developmenttutorial

6/7

9/30/2015

Developmenttutorialrovo89/XposedBridgeWikiGitHub

importde.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
publicclassTutorialimplementsIXposedHookLoadPackage{
publicvoidhandleLoadPackage(finalLoadPackageParamlpparam)throwsThrowable{
if(!lpparam.packageName.equals("com.android.systemui"))
return;
findAndHookMethod("com.android.systemui.statusbar.policy.Clock",lpparam.classLoader,
@Override
protectedvoidafterHookedMethod(MethodHookParamparam)throwsThrowable{
TextViewtv=(TextView)param.thisObject;
Stringtext=tv.getText().toString();
tv.setText(text+":)");
tv.setTextColor(Color.RED);
}
});
}
}

Behappyabouttheresult
Nowinstall/startyourappagain.AsyouhavealreadyenableditintheXposedInstaller
whenyoustarteditthefirsttime,youdonotneedtodothatagain,rebootingisenough.
However,youwillwanttodisabletheredclockexampleifyouwereusingit.Bothusethe
defaultpriorityfortheirupdateClockhandler,soyoucannotknowwhichonewillwin(it
actuallydependsonthestringrepresentationofthehandlermethod,butdon'trelyon
that).

Conclusion
Iknowthatthistutorialwasverylong.ButIhopeyoucannownotonlyimplementagreen
clock,butalsosomethingcompletelydifferent.Findinggoodmethodstohookisamatter
ofexperience,sostartwithsomethingrathereasy.Tryusingthelogfunctionsalotinthe
beginningtomakesurethateverythingiscalledwhenyouexpectit.Andnow:Havefun!

2015GitHub,Inc. Terms Privacy Security Contact Help

https://github.com/rovo89/XposedBridge/wiki/Developmenttutorial

Status API Training Shop Blog About Pricing

7/7

You might also like