Monday, January 30, 2017

Using SWProxy for summoners war

First you need to install git (or the gui github desktop). Then you can clone the code from Then you can clone the repository in the GUI or from the command line:

git clone

Now you have to have python 2.7 and pip installed (best to leave default directory of c:\python27). Pip should be installed automatically as of 2.7.9 and higher, but I did it a while ago and had to install it manually.

You need to be able to run python and pip from the command line. You can run "python --version" and "pip --version" to see if they are in your path, otherwise you need to add "C:\python27" and "C:\python27\scripts" to your path.

Next you need to install Microsoft Visual C++ Compiler for Python 2.7. This is required for one of the encryption packages you'll install next with pip because it compiles some C++ code. After installing that you can install the pip packages required with this:

pip install pycrypto dpkt yapsy

To use the proxy your computer has to be attached to the same access point as your phone (unless you setup the routing yourself, but then you don't need to be reading this :)). Check your computer's ip address by running "ipconfig". You should see a wifi adapter with an address like

   IPv4 Address. . . . . . . . . . . :
   Subnet Mask . . . . . . . . . . . :
   Default Gateway . . . . . . . . . :

Now you're ready to run the proxy. Go to the folder with the code in it and run "python". It should start and tell you the ip address and port it is running on:

# SWParser v0.100 - Summoners War Proxy #
        Written by:

                Youness Alaoui
                Leonardo Stern

                Generate Visit Friend
                Demo Plugin
                SWARFARM Export Plugin
                Generate Runes
                Print Unit Collection
                Barion Rune Efficiency Plugin

Licensed under LGPLv3 and available at:

Failed to load GUI dependencies. Switching to CLI mode
Running Proxy server at on port 8080

Now on your phone make sure you're connected to the same wifi access point as your computer and change the settings of the access point to use the proxy (or whatever your ip address is) and port 8080. Then kill your game and restart it or log out and back in. The login packet has all your account data and will produce several files, these are mine:

-rw-r--r-- 1 Jason 197609 2581564 Jan 29 17:35 6202709.json
-rw-r--r-- 1 Jason 197609     714 Jan 29 17:35 6202709-info.csv
-rw-r--r-- 1 Jason 197609   35236 Jan 29 17:35 6202709-monsters.csv
-rw-r--r-- 1 Jason 197609  852821 Jan 29 17:35 6202709-optimizer.json
-rw-r--r-- 1 Jason 197609   91540 Jan 29 17:35 6202709-runes.csv
-rw-r--r-- 1 Jason 197609  696553 Jan 29 17:35 6202709-swarfarm.json

When you visit another player you will get lists for them too but they have much less data:

-rw-r--r-- 1 Jason 197609  942112 Jan 29 17:36 visit-2403436.json
-rw-r--r-- 1 Jason 197609   47097 Jan 29 17:36 visit-2403436-monsters.csv
-rw-r--r-- 1 Jason 197609  931956 Jan 29 17:36 visit-2913465.json
-rw-r--r-- 1 Jason 197609   45451 Jan 29 17:36 visit-2913465-monsters.csv
-rw-r--r-- 1 Jason 197609 1741862 Jan 29 17:35 visit-3563695.json
-rw-r--r-- 1 Jason 197609   88550 Jan 29 17:35 visit-3563695-monsters.csv

Tuesday, September 8, 2015

C# Bouncy Castle File Decryption

I had a hard time finding a good sample of decrypting a PGP-encrypted file in C# so I decided to write this post.

Bouncy Castle works with streams for the most part.  So first you need to open the file as a stream, then get a special decoder stream using PgpUtilities:

// Comment
using (FileStream fsEncryptedFile = File.Open(ENCRYPTED_FILENAME, FileMode.Open)) {
 using (Stream decoderStream = PgpUtilities.GetDecoderStream(fsEncryptedFile))
Next we have to create a PgpObjectFactory using that stream which will provide us with PgpObjects. We're looking for a PgpEncryptedDataList so we might have to skip the first object which could be a marker:
PgpObjectFactory factory = new PgpObjectFactory(decoderStream);
PgpObject obj = factory.NextPgpObject();
if (!(obj is PgpEncryptedDataList))
 obj = factory.NextPgpObject(); // first object might be a PGP marker packet
PgpEncryptedDataList edl = obj as PgpEncryptedDataList;
With our PgpEncryptedDataList we find PgpPublicKeyEncryptedData, and find the key. Here we open a secret keyring file and find the key based on the KeyId in the data and decrypt it using a passphrase:
PgpEncryptedDataList edl = obj as PgpEncryptedDataList;
foreach (PgpPublicKeyEncryptedData data in edl.GetEncryptedDataObjects())
    PgpPrivateKey privateKey = null;
    using (FileStream fsKeyring = File.Open(KEYRING_FILENAME, FileMode.Open))
     PgpSecretKeyRingBundle bundle = new PgpSecretKeyRingBundle(fsKeyring );
     PgpSecretKey secretKey = bundle.GetSecretKey(data.KeyId);
     privateKey = secretKey.ExtractPrivateKey(PASSPHRASE.ToCharArray());
Next we use GetDataStream on our PgpPublicKeyEncryptedData and pass it our private key and create a PgpObjectFactory that will give us our data. If the object is compressed, we uncompress it:
PgpObjectFactory plainFactory = new PgpObjectFactory(data.GetDataStream(privateKey));
PgpObject message = plainFactory.NextPgpObject();
if (message is PgpCompressedData) {
 message = new PgpObjectFactory(((PgpCompressedData)message).GetDataStream()).NextPgpObject();
Hopefully that will give us a PgpLiteralData which is what we need to get a stream containing the plain, unencrypted data and write that to a new file:
if (message is PgpLiteralData) {
 PgpLiteralData ld = (PgpLiteralData)message;
 using (FileStream outStream = File.Create(OUTPUT_FILENAME)) {
  Stream inStream = ld.GetInputStream();
  byte [] buffer = new byte[0x100000];
  int count = inStream.Read(buffer, 0, buffer.Length);
  while (count > 0) {
   outStream.Write(buffer, 0, count);
   count = inStream.Read(buffer, 0, buffer.Length);
} else {
 Console.WriteLine("ERROR: Unknown type of message in PGP file: {0}", message.GetType().FullName);

Thursday, August 11, 2011

Near Miss Pedantry

"Near miss" is a correct term to describe something that comes close to hitting something else.  I hate it when people say that "near miss" would really be a collision.  The most common meaning of near means close, usually in space.  If I am shooting at a target and I got close to it but didn't quite hit it, that would both be a miss and it would be near the target, therefore it would be a "near miss".  If I had missed way off to the side, it would be a "far miss".  You could say "The miss was near the target", so why can't you call it a "near miss"?

If you have a low ceiling you might say "The ceiling is near".  You could say it was a "near ceiling".  It would be a stretch to interpret this as meaning "It is almost a ceiling, but not quite."

Why do so many pedants skip to the fifth definition when complaining about this term?

Tuesday, July 19, 2011

Intellisense for Google Closure Library in VS 2010 (MVC)

Visual Studio examines your javascript to provide intellisense, and lets you add references to other javascript files to pull info from.  To get closure classes to show up I created a plovr config and did a grep of the whole closure library to find goog.provide calls and converted them to goog.require calls.  Then I did a build to include all the code for closure, resulting in Test.7z (534kb).  It contains the following files:

  • Test\test-config.js: plovr config file, uncomment the module you want to build and run through plovr
  • Test\test.js: goog.require for entire closure library
  • Test\test2.js: missing requires for gears, crypt, test, and some others I'll never use
  • Test\test3.js: also missing goog.ui.editor
  • Test\closure_complete.js: built from test.js, 4.1mb
  • Test\closure_mostly.js: built from test2.js, 2.6mb
  • Test\closure_noeditor.js: built from test3.js, 2.4mb
The easiest way to use them would be to unpack in your Content directory and add this line to the top of your javascript files (has to be the first thing):
/// <reference path="~/Content/Test/closure_mostly.js">

Note: you don't have to add the files to your project, but it uses the same url pathing as if they were part of your web site.

You could also just build your project in WHITESPACE mode and use the generated file.  If you use SIMPLE mode, the closure compiler will shorten your parameter names.  If you use ADVANCED mode the closure compiler would shorten all the names and wouldn't even include code you didn't use.

Monday, July 4, 2011

Building PLOVR on Windows

I wanted to add options to plovr, specifically the ability to output a property map to use for interacting with my server using JSON.

First I installed Mercurial which is needed to get the plovr source code.  I installed it to I:\Programs\Mercurial and added that to my path.

Next I got the plovr source code:
I:\plovr\SRC>hg clone plovr

I saw it had a build.xml file so I downloaded apache ant and unzipped it to I:\Programs\apache-ant-1.8.2, adding I:\Programs\apache-ant-1.8.2\bin to my path also.

Building produced an error that bash wasn't found, so I downloaded MSYS (MinGW not needed) and installed it to I:\Programs\msys\1.0.

Then I just started an msys shell and did:
$ cd /i/plovr/src/plovr
$ ant

And voila - /i/plovr/SRC/plovr/build/plovr.jar (i:\plovr\SRC\plovr\build\plovr.jar) is now there!

Friday, June 17, 2011

MiniProfiler with PetaPoco

Integrating PetaPoco with Mvc Mini Profiler can be done by changing a few lines in PetaPoco.cs to wrap the connection with a MvcMiniProfiler.Data.ProfiledDbConnection and by changing a line that gets a command using the factory to use the connection. I've written a simple DbProviderFactory that acts as a proxy to the SQL Server factory so you don't have to make any changes to PetaPoco. You register it by adding a element under the root configuration element in your web.config to register the factory and change your connect strings to use the new provider:

      <add name="MiniProfiler Data Provider"
           description="SqlServer wrapper for MiniProfiler"
           type="WebSupport.Code.MiniProfilerSqlProviderFactory, WebSupport"
    <add name="Test" providerName="MiniProfilerSql" connectionString="xxxx" />

Notice in the type attribute that my class is in the WebSupport.Code namespace, the value after the comma shows that it is in the WebSupport assembly I have referenced in my MVC project. If you want to stop using MiniProfiler you can just change your connect strings back to using System.Data.SqlClient as the provider.

Here's the code, you should be able to change it for other providers by changing the provider name in the constructor:

public class MiniProfilerSqlProviderFactory : DbProviderFactory
        public static MiniProfilerSqlProviderFactory Instance = new MiniProfilerSqlProviderFactory();

        DbProviderFactory _factory;

        public override bool CanCreateDataSourceEnumerator
                return _factory.CanCreateDataSourceEnumerator;

        public override DbCommand CreateCommand()
            return _factory.CreateCommand();

        public override DbCommandBuilder CreateCommandBuilder()
            return _factory.CreateCommandBuilder();

        public override DbConnection CreateConnection()
            DbConnection cnn = _factory.CreateConnection();
            return MvcMiniProfiler.Data.ProfiledDbConnection.Get(cnn);

        public override DbConnectionStringBuilder CreateConnectionStringBuilder()
            return _factory.CreateConnectionStringBuilder();

        public override DbDataAdapter CreateDataAdapter()
            return _factory.CreateDataAdapter();

        public override DbDataSourceEnumerator CreateDataSourceEnumerator()
            return _factory.CreateDataSourceEnumerator();

        public override DbParameter CreateParameter()
            return _factory.CreateParameter();

        public override CodeAccessPermission CreatePermission(PermissionState state)
            return _factory.CreatePermission(state);

        public MiniProfilerSqlProviderFactory()
            _factory = DbProviderFactories.GetFactory("System.Data.SqlClient");