[BEGIN]
PianoMeter 
Version: 3.x - 5.x

Patch By https://apkMagik.t.me


Patch Feature: Unlocks Pro
	
PatchType: ⚙ double patch ⚙
		 ( 'File changes' & 
		   'Patch for classes.dex' )


Patch options: 
	Enable Signature Killer (first option)

PatchVersion: v2 2026-03-17

	However in case you miss to enable Sign Killer 
	I added this 'fallback':
	lib-patch to add LuckyPatcher's sign as 'valid'.
	
	In detail: 
	The signature check 'lives' inside native code file: 
	libWilleyToneAnalyzerLib.so
	There the SHA1 is stored as string. "63D2...F46D"
	It checks that the sign is the original one.
	
	I replace it with 61ED...AF81. The 'TestSign' 
	LuckyPatcher uses to sign the apk after patching.
	
	Furthermore there are two 'valid' sign's in the app 
	If one of these matches the app will be 'happy.
	For the patch I make use the 'unused' one.
	So it won't interfere with the actual 
	"63D7...D2E89"( cn=Jukka Rauhala ) and mess things up


~~~ The following text only applies if you are using
    an older system like Android 10.
	Where no apk is patched - just the odex runtime 
	optimization file 
~~~
	
ODEX-Patch:
	
	In case the code patch crashes the app.
	Select "Remove ODEX with changes" 
	-> The remaining "shared_prefs mod" will do it's magic. ;)
	
Uninstall: 
	"clear data" + "Remove ODEX with changes" 

Tested Version:
	501 (130) 2/2026
	400	(120)
	340 (108) minSDK 21
	331 (101) minSDK 19 2024 
	202 (60) not working - too old different scheme
	103 (15) Settings.xml.xml ProVersion=True
	101 (12) minSDK 14

Notes:

	Pure Data hack:
	
	Kind da old "ProVersion=True" trick.
	Config is encrypted since v4, but strategy is same. 
	
	shared_prefs\metadata.pt.xml
		AES_KEY = "OGZXmr459CTF1FTH"
		(/ECB/PKCS5Padding 128Bit_Plain)
		https://anycript.com/crypto
		
		Testdata (BASE64): 
		Encr: voehctuiwZVoH2pv9IFWig 
		Decr: purchaseCache
		
		plaintext configdata:
		
			"products":
				"com.willeypianotuning.toneanalyzer.
				... pro"
				... subs.pro"
				... plus"
			"time": 
			forwarded time in future to avoid 
			re-triggering updatePurchases every day
		
		changed "products" with "skus" for backwards compatibility
		
	On non-rooted devices consider using the 
	'Data provider trick' to gain access to the apps configdata
		MT-Manager - "Inject Documents Provider"...
___________________________________________________
	Notes for mod-maintenance and curios people

		Okay we are close to the display limit.
		
		Open that file directly to read on.
		Path is somewhat like this:		\sdcard\Android\data\ru.accjydvg.phbnfjnuy\files\LuckyPatcher\CustomPatches\com.willeypianotuning.toneanalyzer.txt
		
	The antiTamper
	
		30 seconds countdown on MainActivity 
		
		"It looks like you might be using an unauthorized version of PianoMeter. If this app has helped you to tune a piano, please consider downloading and unlocking a licensed version of PianoMeter directly from the Google Play Store. Doing so will ensure that you always stay updated with the newest releases, and you can be assured that the app will not have any 3rd party malware. Your support will also help make the continuing development and maintenance of PianoMeter sustainable"
		Rawtext: "ODGiMOwYJl75nxOQNhEp...
		{Open Play Store}									{30}
		"market://details?id="
		"com.willeypianotuning.toneanalyzer"
		Raw:"oouepynneor.wlciin.lntztanigymalea"
		-> use that raw-string to located "antiTamper"-class

		called from: 
			purchaseStore$builder;->save() Retval_not_used
			antiTamper;->validateLicenseAndSignature()
		Lcom/willeypianotuning/toneanalyzer/security/SecurityBridge;
			boolean nativeIsSignatureValid(Context) {

			WilleyToneAnalyzerLib
				SHA-1 SignatureV2 ( getPackageInfo ... )
				"63D2ADCFB94427028F753D44971000746FAAF46D"
				"63D7C0C971CF15C09B05C7DB6214B997DE5D2E89"
				Jukka Rauhala 2017

				
		on SignatureV2 mismatch:
			* calls com/willeypianotuning/toneanalyzer/AppSettings$.../enableTamperMode()
			* Tramperflag to 0
			* returns 0
		
			void nativePing(Context) {
				nativeIsSignatureValid(...)
			}
			called from willeypianotuning.toneanalyzer.TuningApplication::onCreate()


		boolean nativeTamperDetected() 
			gets flag from IsSignatureValid


	enableTamperMode
		sets "tamperflag" in Settings.xml.xml 

	the 'tamperflag' in shared_prefs 
		Settings.xml.xml
			"g_6013d8c0" = true 
	-> check for that on testing !!!
	
	"NoteSwitch" = 1 is another 'fake' setting
	
The "antiTamper" fix 
	Search'n'Replace in all 
	libWilleyToneAnalyzerLib.so
	search "63D2A...F46D" and replace with the 
	SHA-1 of the signature you use for signing the apk (in Uppercase letters)
	
	Tooling: "Apktool M" ... 
	"View Content" libs/ delete all but arm64
	"Library Editor" rodata search "63D2..
	
In newer versions the class name will change
and that patch will fail.
Use a Tool MT-Manager / NP-Manager to search 
the code(classes.dex) for this unique string:
"iabPreferences" purchaseStoreBuilder class
or better
"re pu" "...restore purchase" ->the target class purchaseStore

Tooling:
	* JEB
	* baksmali + script to split "big.smali" back into files
	* Debugging via WLAN (ADB)
	* Notepad++
	
	- JEB and VIBRE AI-Assistant are your friends ins quick automated renaming
	-Since JEB 5.38 run Global Analysis with "code matching" 
		will do some good renaming job.
	- Kotlin intrinsic's to recover 'lost' names in JEB
		RestoreBeanFromtoString.py 	https://gist.github.com/cw2k/45fa95aa16fa26789a3f9669cd317b39

 [SHARED-PREFERENCES]
 
 {"file_name":"metadata.pt.xml"}
 
 {"insert":"String"}
 {"pref_name":"voehctuiwZVoH2pv9IFWig=="}
 {"value":"epAve9cy4gph1SoZAaFZ+jOizu1IlWpoBRY+L/Eg4cPg8MwQIPFsea1sz1utfaattW/8exPrK/pyZeDCZa9mDP7dnNtpxoFcjlZ+xRu8r1gbDUPuBq6h6ZdT7+OhJY1YdNtmBy5C5lqzm8AXW21HuNmC9oW5iFwjhFRy3WfplRmk28AXdh4qM8FrGnBThnflQp3KfvwVfnFYIY0OHTTikFlMpS4dnClVsvBMipth4GnQ1LKY31yQgySmz3JIGA2KftwylO0rgWlF5jnPHPWTluC7OTdE6N6crzUUc2KcAER8A0JnEcCgGMTiBYBVmdn/GP7blEY4cwfnBqBJUQkBcQVG8Bw7Vp7pFZSLaO3FvOVSh++a24H8F1rpFSf4f5V0BVDGBbz6U079htLjPkxXPw"}
// 
//[PACKAGE]
[CLASSES]


//
// Code Patch #1 -  Has all Purchases
//
// {"class name":"LQg0;"}
{"group":"1"}
{"method name":"h"} // version 5
{"parameter types":"Ljava/lang/String;"}
{"return type":"I"}

// 6E 10 D8 13 08 00   invoke-virtual     purchaseStore->getPurchasesLiveData()Uw0, p0
{"original":" 6E 10 ?? ?? 08 00 "}	
{"replaced":" 12 10  0f 00  12 10 "}	// const/4 v0, 0x0 		Ret v0
//Offset: 129114  Version 128
//Offset: 128158  Version 127


{"group":"1"}
{"method name":"f"} // version 4
{"parameter types":"Ljava/lang/String;"}
{"return type":"I"}

{"original":" 6E 10 ?? ?? 08 00 "}	// 6E 10 D8 13 08 00       invoke-virtual     purchaseStore->getPurchasesLiveData()Uw0, p0
{"replaced":" 12 10 0f 00 12 10 "}	// const/4 v0, 0x0 		Ret v0


{"group":"1"}
{"method name":"f"} // version 3
{"parameter types":"Ljava/lang/String;"}
{"return type":"I"}

{"original":" 6E 10 ?? ?? 04 00 "}	// 6E 10 D8 13 08 00       invoke-virtual     purchaseStore->getPurchasesLiveData()Uw0, p0
{"replaced":" 12 10 0f 00 12 10 "}	// const/4 v0, 0x0 		Ret v0

[LIB]
{ "name" : "libWilleyToneAnalyzerLib.so"} //lib\arm64-v8a\libWilleyToneAnalyzerLib.so

{ "original":" 36 33 44 32 41 44 43 46 42 39 34 34 32 37 30 32 38 46 37 35 33 44 34 34 39 37 31 30 30 30 37 34 36 46 41 41 46 34 36 44 " }	// 63D2ADCFB94427028F753D44971000746FAAF46D PianoMeters alternativeSign

{ "replaced":" 36 31 45 44 33 37 37 45  38 35 44 33 38 36 41 38  44 46 45 45 36 42 38 36  34 42 44 38 35 42 30 42  46 41 41 35 41 46 38 31 " }	// 61ED377E85D386A8DFEE6B864BD85B0BFAA5AF81 LuckyPatcher TestSign 

// Obsolated:	S&R-Code Patch #10 -  IsPro IsPlus 
//				Version: No false return
//
// {"class name":"LQg0;"}
// {"method name":"l"}
// {"parameter types":""}
// {"return type":"I"}
//
// {"original":"00 0f ?? 12 00 0f ??"}	// const/4 v0, 0x0
// {"replaced":"00 0f ?? 12 S1 0f ??"}	// const/4 v0, 0x1 
// 

//
// Obsolated:	ReplaceCode Patch #10 -  IsPro IsPlus 
//				Version: return true straight away
//
// {"class name":"LQg0;"}
// {"method name":"k"}
// {"parameter types":""}
// {"return type":"I"}
// {"replaced":"12 S1 0f 00"} 

[END]
Good Luck and happy piano tuning.

Master understanding the subject 'inharmonicity' and 
'Railsback curve'
https://en.wikipedia.org/wiki/Piano_tuning#Stretch

what is way more 'important' what temperament ya put on.