[APP][4.1+][v0.91 - 20141220] Easy Token - OSS SecurID token with lock screen widgets - Android Apps and Games

Highlights
Convenient lock screen and home screen widgets provide instant tokencodes without navigating to an app.
Optionally save your PIN.
Supports SDTID files, importing http://127.0.0.1/... tokens from email, and QR tokens.
100% open source (GPLv2+)
Click to expand...
Click to collapse
Requirements
A token seed file from your system administrator
JB 4.1+
Click to expand...
Click to collapse
Downloads
Binaries are attached to this post and available from Google Play.
Source code: https://github.com/cernekee/EasyToken
Click to expand...
Click to collapse
Changelog
Code:
v0.91 - 2014/12/20
- Use more specific MIME type matches so that Easy Token associations don't
show up in Contacts.
- Update libstoken to v0.81 and switch from tomcrypt to nettle. Most of
the changes in v0.8/v0.81 won't matter on Android, but it is now possible
to import hard token seed files if desired.
Older changelogs:
Code:
v0.90 - 2014/07/26
- Rework handling of bound device IDs during token import. Try to guess
it based on the current (unique) device ID and all known class GUIDs.
Allow the user to override it, in case of a collision.
- Limit import string to 64kB to avoid OutOfMemoryError crashes on invalid
tokens.
v0.81 - 2014/07/06
- Fix bug in lock screen widget where it would "bounce" between the tokencode
display and the clock display for no apparent reason
- Show the "confirm import" screen unconditionally, so there is a clear
indication that email import succeeded
v0.80 - 2014/07/05
- Initial public release
Click to expand...
Click to collapse
XDA:DevDB Information
Easy Token, App for all devices (see above for details)
Contributors
cernekee
Source Code: https://github.com/cernekee/EasyToken
Version Information
Status: Beta
Created 2014-07-05
Last Updated 2014-12-21

Attaching a couple of randomly generated tokens, in case it is necessary to test Easy Token without a real seed file. These were created with:
Code:
qrencode -l H `stoken export --random --android` -o v2.png
qrencode -l H `stoken export --file pinless.sdtid --v3` -o v3.png
stoken export --random --sdtid > token.sdtid
The rightmost (denser, v3) QR code is a 6-digit PINless token. You may need to zoom in to scan it.

Verrr niice..
Thanks for making this, it works great and looks much better than the official RSA one. One thing, though, what is the network access permission for?

phigan said:
Thanks for making this, it works great and looks much better than the official RSA one. One thing, though, what is the network access permission for?
Click to expand...
Click to collapse
It isn't currently used, but future uses could include:
Internet token provisioning via CTKIP
NTP clock sync, so that if multiple devices use the same seed, they all read back the same tokencode at the same time
Better problem reporting; currently ACRA is set up to use email but there are some limitations associated with that approach. All problem reporting in this app is user-initiated.

Reported via email as well, but here's the problem I'm having:
Trying to import a token given via an http 127.0.0.1] url in an email:
USER_COMMENT=importing new key via (http link omitted, because xda forums don't like it) failed, with chrome saying "connection refused"
ANDROID_VERSION=4.4.4
APP_VERSION_NAME=0.90
BRAND=oneplus
PHONE_MODEL=A0001
CUSTOM_DATA=
STACK_TRACE=java.lang.Exception: Report requested by developer
at org.acra.ErrorReporter.handleException(ErrorReporter.java:626)
at org.acra.ErrorReporter.handleException(ErrorReporter.java:583)
at app.easytoken.MainActivity.sendProblemReport(MainActivity.java:121)
at app.easytoken.MainActivity.onOptionsItemSelected(MainActivity.java:139)
at android.app.Activity.onMenuItemSelected(Activity.java:2600)
at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:1065)
at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:741)
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:884)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
at com.android.internal.view.menu.MenuPopupHelper.onItemClick(MenuPopupHelper.java:177)
at android.widget.AdapterView.performItemClick(AdapterView.java:298)
at android.widget.AbsListView.performItemClick(AbsListView.java:1113)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:2911)
at android.widget.AbsListView$3.run(AbsListView.java:3645)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(Native Method)
Screenshot of Chrome attached.

gehrehmee said:
Trying to import a token given via an http 127.0.0.1] url in an email:
Screenshot of Chrome attached.
Click to expand...
Click to collapse
When you clicked on the email link, did it send you straight to Chrome? Android should notice that the URL matches a pattern that can be handled by two different apps, and let you choose whether to open the link with Chrome (incorrect) or Easy Token (correct).
If this doesn't happen, you may need to clear the default association for Chrome.
If you still can't convince it to pop up the app chooser, another option is to copy the URL to the clipboard (long-press may do it), navigate to Easy Token, then choose Manual Entry.

cernekee said:
When you clicked on the email link, did it send you straight to Chrome? Android should notice that the URL matches a pattern that can be handled by two different apps, and let you choose whether to open the link with Chrome (incorrect) or Easy Token (correct).
If this doesn't happen, you may need to clear the default association for Chrome.
If you still can't convince it to pop up the app chooser, another option is to copy the URL to the clipboard (long-press may do it), navigate to Easy Token, then choose Manual Entry.
Click to expand...
Click to collapse
Interesting:
I installed the official app as well as EasyToken now, and I do get the "choose application" dialog -- but EasyToken isn't in the list.
I copied the URL into the "manual" entry, and it didn't un-grey the "Next" button.
The URL is in the form:
http (noise added to stop xda forum from rejecting post) ://127.0.0.1/securid/ctkip?scheme=https&url=hostname.company.com:443/ctkip/services/CtkipService

gehrehmee said:
The URL is in the form:
http (noise added to stop xda forum from rejecting post) ://127.0.0.1/securid/ctkip?scheme=https&url=hostname.company.com:443/ctkip/services/CtkipService
Click to expand...
Click to collapse
Unfortunately CTKIP is not currently supported. CTKIP URLs do not actually contain the token seed. Instead, they direct the client to handshake with a remote server to securely exchange information. I have not figured out how to implement this scheme yet.
Easy Token normally expects a URL that uses the "compressed token format" (ctf), such as:
Code:
http://127.0.0.1/securid/ctf?ctfData=219561515777421437245254320241301611451327661056547012064173126400766246671676001
The ctf string is entirely self-contained (it doesn't need to talk to a remote server).

Change Device ID
Would it be possible to let users change the device ID? The default one is calculated differently from the official RSA app, so I can't install the same token on both or migrate from one to the other without having a new token issued to me.

pfcrow said:
Would it be possible to let users change the device ID? The default one is calculated differently from the official RSA app, so I can't install the same token on both or migrate from one to the other without having a new token issued to me.
Click to expand...
Click to collapse
If the app is unable to successfully decrypt the token using the default device ID, it should prompt you to enter a different ID (see attached screenshot). You can copy the device ID from the official RSA app if your token is bound to that installation.
Are you getting an error instead?

cernekee said:
If the app is unable to successfully decrypt the token using the default device ID, it should prompt you to enter a different ID (see attached screenshot). You can copy the device ID from the official RSA app if your token is bound to that installation.
Are you getting an error instead?
Click to expand...
Click to collapse
That's awesome! Thanks. I'm also stuck on the CTKIP issue that others discussed above. I suspect I'm not going to have any luck getting the other app to cough up the token once I download it, though.

pfcrow said:
I'm also stuck on the CTKIP issue that others discussed above. I suspect I'm not going to have any luck getting the other app to cough up the token once I download it, though.
Click to expand...
Click to collapse
That's correct - it is stored in a different format, and obfuscated.
I wonder how much demand there would be for an Xposed Framework module that exports stored tokens from the official RSA app?

cernekee said:
That's correct - it is stored in a different format, and obfuscated.
I wonder how much demand there would be for an Xposed Framework module that exports stored tokens from the official RSA app?
Click to expand...
Click to collapse
A lot - my employer will only issue tokens in CTKIP format, and if I can't copy the RSA app's token out I'm stuck with the default app. And what's worse, I'm stuck with using it on just that one phone - this is the whole reason I found your app in the first place, because I have 2 phones and want to clone the token onto both.
If you figure out a way to read the token from the RSA app, I'd happily PayPal you $20 for the effort
Edit: Even better would be an app to extract the RSA token from a Titanium backup.

I am using this on Android and it works great. Today I tried to install this to chrome using ARC. It worked. I was able to import tokens and all seemed well except the tokens are generating the wrong numbers. They should match the android device but they do not. I verified the serial# and dates are the same but the digits after the same PIN numbers are entered are different. I realize ARC is new but figured i'd give it a go.

cernekee said:
That's correct - it is stored in a different format, and obfuscated.
I wonder how much demand there would be for an Xposed Framework module that exports stored tokens from the official RSA app?
Click to expand...
Click to collapse
Was this solved?
I'd love to get more info and give it a go!
It seems a fun challenge. :cyclops:

I gotta tell you - I love this app. I can easily move my token from phone to phone without getting a new token from my sysadmins. That is huge! I wish you a also had a Mac OS X app

Tasker/KLWP
This app is brilliant - so much better than RSA's!
But could you tell me is it possible to get a code from Easy Token into KLWP or Tasker? Using intents?
Cheers!

Great work, loving it !

The token in the official Android app is stored in a sqlite database. If your phone is rooted, it's easy to copy it out and dump the database. You can probably dump it out of any backup program. The problem is that the critical fields are obfuscated. They appear to be 256-bit numbers in hex, and I don't know how they translate into the fields used by stoken (the token program that powers the app we're discussing here).
A dump of the table shows:
Code:
CREATE TABLE tokens (
SERIALNUMBER text primary key not null,
NICKNAME text not null,
EXPIRATIONDATE text not null,
PINTYPE integer not null,
PRNPERIOD integer not null,
PRNLENGTH integer not null,
ROOTSEED blob not null,
OTPMODE integer not null,
DEVICEBINDINGDATA text not null,
ALGORITHM integer not null,
BIRTHDATE integer not null,
MAXTXCOUNT integer not null,
SIGNATURECOUNT integer not null,
LASTTXTIME integer not null,
TOKENHASH blob not null);
The ROOTSEED and TOKENHASH fields are both 64-character (256-bit) hex codes. I think everything else is either zero or reasonably obvious.
My two thoughts are to either make sense of all this data to create a converter, or to investigate the Windows token storage format (which might use the same fields) and see if the official token converter can extract it.

Is any results with CT-KIP? Or any workaround?

Related

SQL CE 3.5 - First App

I'm working on developing my first WM 6 App using SQL CE 3.5 . I'm sure there are other apps out there that do what mine does, but I'm just wanting the experience of developing it.
I'm working on a fairly simple app to track gas mileage and such. But, for some reason, whenever I debug it, the app can't seem to find the database file. I get an error saying: "The database file cannot be found. Check the path to the database. [ Data Source = .\GasTrackerDB.sdf ]"
I can browse with file explorer on the device and find the database in the same directory as the deployed application, so I'm not really sure where to go from here..
I'm doing everything through the IDE, so all of the code is generated for me to connect to the database.
Anybody experienced enough to help me troubleshoot this stupid problem?
i have been looking for an app that does the same thing as the one you are working on.
when it is finished please pm me. i wish i knew more programing, if i did i would help you.
Try
Code:
string database = string.Format(@"{0}\GasTrackerDB.sdf", GetApplicationPath());
public static string GetApplicationPath()
{
string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
return path;
}
I did figure it out after messing around with it. I think it has to do with the way VS2008 deploys the app on the emulator...
When I hard-code the path to the database file, it works. So, my app will just have to be installed on the local device and not the SD card
Don't hard-code the path! The method GetApplicationPath() returns the application path. This is also important when installing on OS with different language.
heliosdev said:
Don't hard-code the path! The method GetApplicationPath() returns the application path. This is also important when installing on OS with different language.
Click to expand...
Click to collapse
How is that possible when the Connection String was generated by the IDE? Here's what the .xsd says:
Code:
<Connection ConnectionStringObject="Data Source=\program files\gastracker\GasTrackerDB.sdf" IsAppSettingsProperty="false" Modifier="Assembly" Name="GasTrackerDBConnectionString" ParameterPrefix="@" Provider="Microsoft.SqlServerCe.Client.3.5" />
On application start create the connection string "Data Source = " + database (like post #3)
This connection string can then be passed wherever you need to connect to the database.
That's the problem.. the IDE created all the stuff for the connection string and I don't know enough about it to create everything needed manually.
How do you connect to the db? What are you calling for retrieving data from db? How do you insert data to the db? All these actions need an object which somehow knows the connectionstring. And this string can/must be changed.
Hmm.. That doesn't seem to be a valid function name. I'm using .NET CF 3.5 .I'll keep looking.
Well, I wrote my own function to get the execution path, but I still can't figure out how to modify the connection string at runtime.
This crap is ridiculous. I don't understand why it doesn't "just work" when I let the IDE do everything...
Well, I FINALLY made it work.. i ended up going through the xsd file and changing all the code that creates queries. I had to replace every instance of:
Code:
CType(Me._commandCollection(0), Global.System.Data.SqlServerCe.SqlCeCommand).Connection = New Global.System.Data.SqlServerCe.SqlCeConnection("Data Source=.\GasTrackerDB.sdf;")
With:
Code:
CType(Me._commandCollection(0), Global.System.Data.SqlServerCe.SqlCeCommand).Connection = New Global.System.Data.SqlServerCe.SqlCeConnection("Data Source=" & GetAppPath() & "\GasTrackerDB.sdf;")
That had to be done for every one of my queries created through the designer. Thankfully I only had 5!
Great! Keep in mind that changes in generated code can get lost when the ide is recreating the code. Just keep an eye on it when doing changes in this area!
heliosdev said:
Great! Keep in mind that changes in generated code can get lost when the ide is recreating the code. Just keep an eye on it when doing changes in this area!
Click to expand...
Click to collapse
Yeah, I already ran into that one If it gets to be too much of a pain, I'll see if I can create some sort of compile time script to do a find and replace.. But I haven't spent enough time going back and fixing it yet
go to
http://www.connectionstrings.com/
They have everything you need to build your connection string. From my experience, it's okay to let the IDE build everything EXCEPT the connection string....

[QUESTION] RSA SecurID or Similar

Has anyone found an RSA SecurID App or something similar to provide the same function under Android?
Good question. I look for one too but could not find an Android version yet. There is only 1 for iPhone .
The RSA SecurID Token for the Java ME Platform runs perfectly well on my HTC Desire (Android 2.1) phone.
(Sorry I am a new user so can't post the URL)
Got to RSA's web site.
Click Products on the menu
RSA SecureID
Product Family
Software Authenticators
Java Smartphones
You will need to convert your tokenseed to work with the app, but it is worth it.
woffys said:
The RSA SecurID Token for the Java ME Platform runs perfectly well on my HTC Desire (Android 2.1) phone.
(Sorry I am a new user so can't post the URL)
Got to RSA's web site.
Click Products on the menu
RSA SecureID
Product Family
Software Authenticators
Java Smartphones
You will need to convert your tokenseed to work with the app, but it is worth it.
Click to expand...
Click to collapse
Yup, confirmed. I have RSA running on my Hero (CM6), here's what I did.
Download J2ME app as per woffy's instructions above
Go to http://www.netmite.com/android/ and download the andme runner APK, and install
Go to http://www.netmite.com/android/srv/2.0/getapk.php and upload the JAD and JAR files from the RSA app you downloaded. An APK should be generated, load it onto your phone any way you want.
Get the token converted from the RSA website as well, and get your token file from the appropriate source. Then run tokenconverter.exe <filename>.sdtid -f. You should get a long numeric string.
Click import token in the RSA app, and enter the code from above
If all goes well, you should be able to enter your PIN and get a token.
Hope this helps someone, several of my coworkers and I have been waiting for this for months - we all got tired of carrying either fobs or our blackberries just to be able to remote in. One phone to rule them all!
what about the hardware securid
Is there a software for the hardware securid version?
magickarle said:
Is there a software for the hardware securid version?
Click to expand...
Click to collapse
This is what this thread is about.
But you need a special file to initialize the software, from the team of your company that manages the SecurID server and the hardware tokens.
snark_be said:
This is what this thread is about.
But you need a special file to initialize the software, from the team of your company that manages the SecurID server and the hardware tokens.
Click to expand...
Click to collapse
Ho. I though there were 2 different products.
What would be the "technical term" for this file.
I don't want to sound stupid when I'll explain them this.
Thanks
According to this page, you need:
AES (128-bit) token seeds
Click to expand...
Click to collapse
magickarle said:
Ho. I though there were 2 different products.
What would be the "technical term" for this file.
I don't want to sound stupid when I'll explain them this.
Thanks
Click to expand...
Click to collapse
Your security dept will need to have available soft tokens. Tell them to generate a Windows Mobile 128bit AES token file for you. You should receive a file with a .sdtid extension. Use that file with the token converter as described by whoiswes.
@wolfys: Nice find!
@whoiswes: Nice step by step writeup!
confirmed working on my DX...
edit:
You cannot use the sdtid file from an existing WM soft token btw. TokenConverter will blow up on a schema parsing error if there's a WM deviceID statement (generally the case when WM softtokens are assigned). Make sure the security dept. generates the WM token with a blank deviceID. Generally that means that they will have to unassign your existing soft token then re-assign it to you.
There is RSA SecurID beta app on the Market now http://www.appbrain.com/app/rsa-securid-software-token/com.rsa.securid

Link contact adress to Nokia Drive

I use my7rom on my Omnia 7.
Is there anyway to link a contacts adress to Nokia Drive instead of Maps (stock wp7 app). It would be much more practical if Nokia Drive opened a navigation session instead.
Anyone up for the challenge? A reg-tweak perhaps?
// Manneman
Skickat från Windows Phone 7.8
There's two parts here. The first is identifying the correct "filetype" or URI scheme that is used for navigation. That shouldn't be too hard; a little digging in HKCU should reveal it. We already know about ones like callto: and http: and I'm actually (slowly) working on an app to allow people to easily change them. The second part is finding the correct command to load that address or route in the Nokia Maps app. If the app supports pinning routes or destinations to Start, this is probably possible. If not, it may not be possible in the app. Most apps aren't designed to accept command-line parameters, so even if you make them the default handler for a given filetype or URI scheme, they ignore the value you send them and just start as though launched from Start.
GoodDayToDie said:
If the app supports pinning routes or destinations to Start, this is probably possible.
Click to expand...
Click to collapse
Nokia Drive supports pinning to start so it should be possible. Unfortunately I can't tell you exact command line parameters 'cause my Lumia 900 still "in jail"
Let me see if I have a copy of the Nokia Drive XAP handy. I'll need to decompile it to figure out the correct parameters for launching it with the intent of navigating to a specific location. Note also that this might not be possible directly - for example, the app might store a list of locations internally, and the tiles only provide an index into that list rather than providing the location directly - but that just requires another layer of indirection.
In that case, you create an app that gets registered as the navigation handler, and in response to a navigation request, it writes the requested location into the Nokia Drive app and then chain-launches Nokia Drive with the index of the newly written location. That's just an example of one way that this might go wrong, but overall, the odds are actually pretty good. Obviously, all of this will require, at a minimum, write access to the HKCR hive in the registry.
Ah, guys! You are so kind helping me out. I´m really certain alot of members in the WP7 section would love for this to work!
// Manneman
GoodDayToDie said:
I'll need to decompile it to figure out the correct parameters for launching it with the intent of navigating to a specific location
Click to expand...
Click to collapse
GoodDayToDie, you may try much simpler solution. Just create assembly (dll) to show startup parameters in message box, and replace main Nokia Drive dll (but pin some location first).
That's actually harder than it sounds; even if the app is sideloaded (which would mean I already have the DLL) my fake would have to mimic the internal structure of the real app to a degree (namespaces, class names, default actions, etc.). That's not hard, but decompiling .NET is pretty trivial too.
AFAIR, Nokia Drive is obfuscated (but I'm not 100% sure). Also, you don't need to duplicate all names and structures; just a stuff mentioned in WMAppManifest (I hope so). BTW, I forgot: I still have unlocked handset; if I'll found time, will try today later.
Update: tried but without of luck What I did:
- installed Nokia Drive first;
- downloaded map and pinned current location;
- created fake app with same app guid and namespace name ("Drive"), and performed app update (that operation completely override whole solution but NokiaDrive tile still pinned to the start screen);
- tried a few different page names (_default.xaml, QuickStartPage.xaml, DestinationPickerPage.xaml, FavoritesPage.xaml) with code
Code:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
MessageBox.Show("Hello from fake dll");
if (e.NavigationMode == System.Windows.Navigation.NavigationMode.New)
{
string[] keys = NavigationContext.QueryString.Keys.ToArray();
string[] values = NavigationContext.QueryString.Values.ToArray();
string param = "";
for (int i = 0; i < keys.Length; i++)
{
param += keys[i] + " -> " + values[i] + "\n";
}
MessageBox.Show("parameters: " + param);
}
}
But result always the same: app doesn't start from the pinned tile
Update 2: Finally, I did it
The trick is:
- do the same as I've described above (you should have pinned tile from ND);
- add following code to the start page:
Code:
public MainPage()
{
InitializeComponent();
var appTile = ShellTile.ActiveTiles.Last();
if (appTile != null)
{
//MessageBox.Show(appTile.NavigationUri.OriginalString);
EmailComposeTask emailTask = new EmailComposeTask();
emailTask.Subject = "NokiaDrive pinned parameters";
emailTask.Body = appTile.NavigationUri.OriginalString;
try
{
emailTask.Show();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK);
}
}
}
- run app as usual (not from tile);
We allset - all params are sent to our email (I'm too lazy to manually copy all stuff )
Here we are (start parameters; bold values are changed for privacy reason ):
/_default?destination.name=200 SomeName Street&destination.latitude=49.5255378801376&destination.longitude=-72.4296837244183&destination.address.street=SomeName Street&destination.address.houseno=200&destination.address.district=&destination.address.county=&destination.address.city=SomeCity&destination.address.state=&destination.address.country=USA&destination.address.postcode=05720&destination.hashCode=371767793destination.address.statecode=MA&pinnedFrom=Favorites
P.S. Just found: Navigon also has ability to pin address to the start tile So, if you find the way to modify map protocol (or how it calls), it will be a really nice hack! BTW, could you remind me: do we have ability to launch assembly by GUID (on the full-/policy-unlocked phones)? If "yes", it's possible to write a real nice "proxy" app to handle map requests
I don't know about launching assemblies directly, but it's certainly possible to launch apps by GUID. It doesn't even require anything more than dev-unlock in fact (although of course you can only launch apps that you could launch anyhow). So yes, a proxy app is totally possible. That's actually what I'm working on (started as a project to make a Kindle ebook file loader, that would pur .mobi/.prc file in the Kindle app's folder and then launch the app).
GoodDayToDie, could you please, take a look to the registry, for default map protocol handler and figure out how to change that stuff? I'm pretty busy these days (and probably will be extremely busy couple of next months) but we can cooperate and create this app...
I'll investigate, but you're not the only one busy. If you've noticed a lack of software from me recently, it's due to the nex job I got some months back; I love it, but it leaves me with a lot less time for phone hacking if I want to still have a life outside of that.
With that said, this actually ties into the work I'm already doing with things like filetype handling and default browser switching. I can send you my HKCRlib, at a minimum; it's a library that simplifies interacting with HKCR, including creating backups of important values when they change, and reverting the backups.
GoodDayToDie, truly, I'm not much interested (personally) in that hack 'cause I can't use it for my Lumia 900. So it's only for the community needs but because of lack of time, I believe, we may put it on hold.

How does WeChat store animated emojis (stickers)?

Hi,
I hope this is the right section for app-specific questions (if not, please move the thread)...
My wife recently got into that sticker/emoji-collecting-thing on WeChat (god knows why) and she would like to use the WeChat stickers on other messengers like Whatsapp (or have access to the image files in general). There are millions of tutorials how to make your own animated stickers for WeChat, but unfortunately there is zero information how to get them out of WeChat... Apparently everything is stored in the folder "Phone\tencent\MicroMsg\--some-md5-like-number--\emoji". Therein are subfolders like "com.tencent.xin.emoticon.NAME", I guess for each sticker creator, and the image files themselves have cryptic filenames like "fd0476f63c51690b88dd17d9be63af1c" without any extension. The good news is that PNGs and JPGs are saved "natively" - such files can be easily recognized by any image viewer via the header. However, animated stickers (typically discernible by the much larger file size) are apparently stored in a kind of proprietary format. It's not GIF or any image format I know of (or rather tried it with), it's also not a common compressed container, and the hex editor doesn't reveal anything useful, just densely packed gibberish...
Is there any kind of documentation on how WeChat stores animated images and how they can be converted back into something useful like GIF?
I was wondering this as well. I did the same digging as the OP, with one thing to add. I took a look at one of the said files – this one is 13Kb and about 1kb from the beginning there is a 648-byte xml rdf metadata tag. It shows that whatever this thing is, it was made with Photoshop. I took out the id's and hashes:
Code:
<rdf:Description rdf:about="" xmlns:xmpMM="http ://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http ://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:xmp="http ://ns.adobe.com/xap/1.0/" xmpMM:eek:riginalDocumentID="xmp.did:…" xmpMM:DocumentID="xmp.did:…" xmpMM:InstanceID="xmp.iid:…" xmp:CreatorTool="Adobe Photoshop CC 2015 (Windows)"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:…" stRef:documentID="adobe:docid:photoshop:…"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>
Looking for the same answer
It's been forever since this question was posted, but I still kinda want to know. I don't think anyone's figured out how. XD;;
Nope, I gave up and urged my wife to find a new hobby
Drats, the stickers are so adorable tho... iiOTL
The files are stored in the WXAM format (an in-house proprietary format). The most I found was this post detailing an exploit for WXGF (that's the name of the format), which includes POC code in Python (see zip at end of post) that encrypts a file to WXGF. In it, you can see the code calculating the encryption key - which, I imagine the way to decrypt them would be to do the opposite (obviously)
Python:
imei = '358035085174146'
key = hashlib.md5(imei).hexdigest()[0:16]
cipher = AES.new(key, AES.MODE_ECB)
result[0:1024] = cipher.encrypt(buffer[0:1024])
As for converting the unencrypted file - whether Android or Windows, it's contained in a dll or so file.
On Windows, the decompilation code can be found at
Code:
C:\Program Files (x86)\Tencent\WeChat\WXAMDecoder.dll
, while on Android it can be found at
Code:
libwechatcommon.so
Particularly on Android, the Java class located in
Code:
com.tencent.mm.plugin.gif.MMWXGFJNI
contains the java -> native implementation, with functions such as
Code:
nativePic2Wxam()
As for documenting the internal native code -> It's too much past my ability / time at the moment. Maybe this can be for someone for another day~ That being said, decryption isn't impossible as you saw above, related to IMEI and AES keys.
The particular function you were looking for was - sadly, using it would be a bit hard. But I imagine that you could take the so file, wire it up to an Android app with the same declarations here, and pass in the Wxam file in a byte[] array to get the result back -> You wouldn't have to know the internal code for that either, and since the type is byte[], we don't need to even reverse engineer the code to see what it supplied. Clearly it is a byte[] array of the files contents.
Code:
public static native byte[] nativeWxamToGif(byte[] bArr);
In fact, now that I think about it, I'd like to try it myself now and see what happens lol.
Edit: Yup, it works. I just decoded a few files. Working on decryption now. Sorry, I can't share it since I don't wanna get in trouble. But there's the information above ^^ If you can make Android apps and know enough, it's not hard
BBRecon said:
The files are stored in the WXAM format (an in-house proprietary format). The most I found was this post detailing an exploit for WXGF (that's the name of the format), which includes POC code in Python (see zip at end of post) that encrypts a file to WXGF. In it, you can see the code calculating the encryption key - which, I imagine the way to decrypt them would be to do the opposite (obviously)
Python:
imei = '358035085174146'
key = hashlib.md5(imei).hexdigest()[0:16]
cipher = AES.new(key, AES.MODE_ECB)
result[0:1024] = cipher.encrypt(buffer[0:1024])
As for converting the unencrypted file - whether Android or Windows, it's contained in a dll or so file.
On Windows, the decompilation code can be found at
Code:
C:\Program Files (x86)\Tencent\WeChat\WXAMDecoder.dll
, while on Android it can be found at
Code:
libwechatcommon.so
Particularly on Android, the Java class located in
Code:
com.tencent.mm.plugin.gif.MMWXGFJNI
contains the java -> native implementation, with functions such as
Code:
nativePic2Wxam()
As for documenting the internal native code -> It's too much past my ability / time at the moment. Maybe this can be for someone for another day~ That being said, decryption isn't impossible as you saw above, related to IMEI and AES keys.
The particular function you were looking for was - sadly, using it would be a bit hard. But I imagine that you could take the so file, wire it up to an Android app with the same declarations here, and pass in the Wxam file in a byte[] array to get the result back -> You wouldn't have to know the internal code for that either, and since the type is byte[], we don't need to even reverse engineer the code to see what it supplied. Clearly it is a byte[] array of the files contents.
Code:
public static native byte[] nativeWxamToGif(byte[] bArr);
In fact, now that I think about it, I'd like to try it myself now and see what happens lol.
Edit: Yup, it works. I just decoded a few files. Working on decryption now. Sorry, I can't share it since I don't wanna get in trouble. But there's the information above ^^ If you can make Android apps and know enough, it's not hard
Click to expand...
Click to collapse
I'm using nativeWxamToGif(), but I keep getting a return value of null. Do you know if it is still supposed to work? I tried the libwechatcommon.so in wechat versions 7 and 8 and still no luck.
My decryption code is almost the same as the encryption code. The only difference is that I strip off the trailing 0-pad and then reuse the imei-generated (using my own imei) key to decrypt.
Were you able to use nativePic2Wxam? The signature is too complex so it's too hard for me to guess what parameters to pass in.
Code:
private static native int nativePic2Wxam(String paramString1, String paramString2, int paramInt1, int paramInt2, int paramInt3, int paramInt4, int paramInt5);
Since I don't know how to use nativePic2Wxam, I'm just blindly trusting you that I should be able to decrypt one of the wxgf into wxam and then use nativeWxamToGif() to convert it to a gif. But I'm not sure why my gifs are always null.
I think I do have the libwechatcommon.so lib working because I am able to use other simple functions such as the following:
Code:
public static native int nativeRewindBuffer(long paramLong);
public static native int nativeUninit(long paramLong);
Does nativeWxamToGif() return null if the input byte array is invalid wxam or something?

Export Notes?

Many many notes using the Notes app on the Mate 7. Is there any way to export these notes so I can transfer them to PC/ another phone?
You can press "Share" for each note and share it via E-mail, or alternatively you can share it to "Google Keep" which is also an app for taking notes made by google. With google keep you can sync your note across all your devices.
Another way is to backup your notes with the "Backup" app which came with the phone's software, or the "HiSuit" program which is the official application from Huawei to backup files on your PC.
Feel free to ask any question if anything wasn't very clear.
Thanks for your response-
Too many notes to share individually and I think I would need to share individually to migrate to Google Keep...?
I believe the Backup and Hisuit program store in a format that is only useful for restoring to the phone or another Huawei phone; I need to transfer notes to pc/another non-Huawei phone.
Please clarify if I've missed something here. Hope someone has a solution...
Thanks-
Sam
SAbboushi said:
Too many notes to share individually and I think I would need to share individually to migrate to Google Keep...?
Click to expand...
Click to collapse
Unfortunately, yes you need to transfer each one individually.
SAbboushi said:
I believe the Backup and Hisuit program store in a format that is only useful for restoring to the phone or another Huawei phone; I need to transfer notes to pc/another non-Huawei phone.
Click to expand...
Click to collapse
Yea that's true, it only works with Huawei phones.
Huawei's notes app doesn't have many features to try, it only allows to "share" each note individually, Yes that will take time but once you switch into Google keep, Evernote, OneNote ..etc you can sync your notes across all your devices.
hi there,
I lost all my notes from my huawei p9 lite after i format my phone.
My questio is where can I find my old saved notes? I backed upmy phone before reseting it, and i copied all my files in my PC.
Thanks for your help.
If anyone else struggles with transfering notes from their phone to a different device, you could use the cloud option, back up the notes in phone settings (Cloud section), and then login to : cloud.huawei.com where you will be able to copy-paste all the notes to your computer. I assume this is easier for most people than copy-pasting on phone.
Hi,
I had similar situation - a stock Huawei phone with stock notes app and a user trying to migrate to Xiaomi... So it happened as follows:
Export Huawei notes from cloud, using browser access
Create "Standard Notes" account
Convert Huawei exported notes into "Standard Notes" backup format
Import "Standard Notes" backup
Here are details of operation:
Login into your Huawei cloud on some browser (preferably on computer)
Choose to download your data, click on notes
It will generate ZIP with JSONs of every note (use 7z to extract, as unzip on Linux fails with error 99)
Create a "Standard Notes" account at https://app.standardnotes.org (basic account is free, FOSS app is available on F-droid, nice interface, e2e encrypted)
Add one "My test note WOO-HOO!" to your new account
Export "Standard Notes" backup (using computer)
It will also make you download ZIP file, with a structure inside, however you only need top level "Standard Notes Backup and Import File.txt" file, which is, in fact, a JSON
You can make your own solution or just use my Ruby code (attached) to convert into a Standard Notes backup format, please adjust path at line #11 to match your needs.
Run ruby (it converted 2000+ notes in a few seconds for me), redirect output into a file, remove array markers in the very beginning and very end (first and last "[ ]" symbols)
Carefully edit "Standard Notes Backup and Import File.txt" file, insert the JSON block generated by Ruby code. In my case, my test note started at line 102 and finished at line 119, so I inserted my JSON starting with line 120 (do not forget add one comma in the end of line 119)
Run resulting TXT file through jq or any other JSON validation tool to make sure everything is fine.
Import into your Standard Notes
Sorry to leave some manual work to do, however this is just one time operation.
Cheers!
chockophone said:
Hi,
I had similar situation - a stock Huawei phone with stock notes app and a user trying to migrate to Xiaomi... So it happened as follows:
Export Huawei notes from cloud, using browser access
Create "Standard Notes" account
Convert Huawei exported notes into "Standard Notes" backup format
Import "Standard Notes" backup
Here are details of operation:
Login into your Huawei cloud on some browser (preferably on computer)
Choose to download your data, click on notes
It will generate ZIP with JSONs of every note (use 7z to extract, as unzip on Linux fails with error 99)
Create a "Standard Notes" account at https://app.standardnotes.org (basic account is free, FOSS app is available on F-droid, nice interface, e2e encrypted)
Add one "My test note WOO-HOO!" to your new account
Export "Standard Notes" backup (using computer)
It will also make you download ZIP file, with a structure inside, however you only need top level "Standard Notes Backup and Import File.txt" file, which is, in fact, a JSON
You can make your own solution or just use my Ruby code (attached) to convert into a Standard Notes backup format, please adjust path at line #11 to match your needs.
Run ruby (it converted 2000+ notes in a few seconds for me), redirect output into a file, remove array markers in the very beginning and very end (first and last "[ ]" symbols)
Carefully edit "Standard Notes Backup and Import File.txt" file, insert the JSON block generated by Ruby code. In my case, my test note started at line 102 and finished at line 119, so I inserted my JSON starting with line 120 (do not forget add one comma in the end of line 119)
Run resulting TXT file through jq or any other JSON validation tool to make sure everything is fine.
Import into your Standard Notes
Sorry to leave some manual work to do, however this is just one time operation.
Cheers!
Click to expand...
Click to collapse
hello i can't find the ruby code...
mcnick50 said:
hello i can't find the ruby code...
Click to expand...
Click to collapse
Sorry mate, looks like I can't attach it successfully. Let me try to paste into the body... Hopefully it won't get transformed into a emoticons
#!/usr/bin/ruby
#
require "pp"
require "json"
require "securerandom"
#json_in = File.read("../Notes-2021050323205147761/Notes/20210401133344621/json.js");
s_notes = []
Dir.glob('../Notes-2021050323205147761/Notes/*/json.js').each do |j|
json_in = File.read(j)
json_hash = JSON.parse(json_in[11..-1]);
uuid = SecureRandom.uuid
text = json_hash["content"]["title"].to_s
created_u = json_hash["content"]["created"].to_s[0..9].to_i
modified_u = json_hash["content"]["modified"].to_s[0..9].to_i
created = Time.at(created_u).strftime('%Y-%m-%dT%H:%M:%S.%LZ')
modified = Time.at(modified_u).strftime('%Y-%m-%dT%H:%M:%S.%LZ')
title_length = json_hash["content"]["title"].to_s.index("\n")
title = ""
if title_length > 30
title = json_hash["content"]["title"].to_s[0..30]
else
title = json_hash["content"]["title"].to_s[0..title_length-1]
end
s_note = {
:uuid => uuid,
:content_type => "Note",
:content => {
:text => text,
:title => title,
:references => [],
:appData => {
"org.standardnotes.sn" => {
:client_updated_at => modified
}
},
: preview_plain => "" # DELETE SPACE BETWEEN : and the "p"...
},
:created_at => created,
:updated_at => modified
}
s_notes.push s_note
end
puts s_notes.to_json
chockophone said:
Sorry mate, looks like I can't attach it successfully. Let me try to paste into the body... Hopefully it won't get transformed into a emoticons
#!/usr/bin/ruby
#
require "pp"
require "json"
require "securerandom"
#json_in = File.read("../Notes-2021050323205147761/Notes/20210401133344621/json.js");
s_notes = []
Dir.glob('../Notes-2021050323205147761/Notes/*/json.js').each do |j|
json_in = File.read(j)
json_hash = JSON.parse(json_in[11..-1]);
uuid = SecureRandom.uuid
text = json_hash["content"]["title"].to_s
created_u = json_hash["content"]["created"].to_s[0..9].to_i
modified_u = json_hash["content"]["modified"].to_s[0..9].to_i
created = Time.at(created_u).strftime('%Y-%m-%dT%H:%M:%S.%LZ')
modified = Time.at(modified_u).strftime('%Y-%m-%dT%H:%M:%S.%LZ')
title_length = json_hash["content"]["title"].to_s.index("\n")
title = ""
if title_length > 30
title = json_hash["content"]["title"].to_s[0..30]
else
title = json_hash["content"]["title"].to_s[0..title_length-1]
end
s_note = {
:uuid => uuid,
:content_type => "Note",
:content => {
:text => text,
:title => title,
:references => [],
:appData => {
"org.standardnotes.sn" => {
:client_updated_at => modified
}
},
: preview_plain => "" # DELETE SPACE BETWEEN : and the "p"... otherwise it becomes
},
:created_at => created,
:updated_at => modified
}
s_notes.push s_note
end
puts s_notes.to_json
Click to expand...
Click to collapse
Could you describe to me exactly how this ruby works, what it takes. i have 2000 notes and i can't convert as described you can't.
glehel said:
Could you describe to me exactly how this ruby works, what it takes. i have 2000 notes and i can't convert as described you can't.
Click to expand...
Click to collapse
You will need little experience with running things on command line (preferably Linux or Mac, but can also work on Windows). Basically, I already escribed all steps in the post above: export Huawei notes, export empty Standard Notes. Use ruby to transform Huawei notes into Standard Notes fragment, which you will have then manually copy-paste into empty SN backup form above.
chockophone said:
You will need little experience with running things on command line (preferably Linux or Mac, but can also work on Windows). Basically, I already escribed all steps in the post above: export Huawei notes, export empty Standard Notes. Use ruby to transform Huawei notes into Standard Notes fragment, which you will have then manually copy-paste into empty SN backup form above.
Click to expand...
Click to collapse
I tried running your code but I'm getting the following error
Traceback (most recent call last): 2: from Notes.rb:11:in <main>' 1: from Notes.rb:11:in each' Notes.rb:27:in block in <main>': undefined method >' for nil:NilClass (NoMethodError)
RajtheKing said:
I tried running your code but I'm getting the following error
Traceback (most recent call last): 2: from Notes.rb:11:in <main>' 1: from Notes.rb:11:in each' Notes.rb:27:in block in <main>': undefined method >' for nil:NilClass (NoMethodError)
Click to expand...
Click to collapse
I guess that in your case problem actually is on line 11. Please make sure you put correct file pattern there. Or maybe they changed format since then and there is no more title field present. In any case, if you run into issues, do not hesitate to PM me.

Categories

Resources