Neopets Mobile

From Computers Wiki
Jump to navigationJump to search

Neopets Mobile does not refer to the 2021 interface of the website, but the 2006 flip phone application that has long been discontinued.

Archival

https://www.jellyneo.net/?go=mobile

https://pinkpt.com//neodex/index.php?title=Neopets_Mobile

https://drive.google.com/file/d/1Cj8hqk4VI-O408kgMnKpffPmI-kxKmWR/view

Attempts to reverse engineer the long-defunct API

TODO (The jars are all minified, but perhaps I can extract the API URLs from them and document what the application expects to get back)

The META-INF/MANIFEST.MF for the Nokia 6280 version specifies a Java version of 1.4.2_04.

The decompiler used is quiltflower: https://github.com/QuiltMC/quiltflower and the javax.microedition classes were copied from https://github.com/mcpat/java-microedition-libraries

Nokia 6280 V02.30.00 (en) Singtel

m.java contains two calls:

The session check appears to return one of the following values, with anything else as a failure code of -1:

Response Treated as ID
SUBSCRIBED 1
UNSUBSCRIBED 2
REVOKED 3
SECURITY 5

Nokia 6111

m.java contains one call:

Both

In b.java for the 6280 version and m.java for the 6111 version, there is code for the following POST request (taken from the 6280 version):

   private static final void a(HttpConnection var0, p var1, boolean var2) throws IOException {
      var0.setRequestMethod("POST");
      var0.setRequestProperty("content-type", "application/x-www-form-urlencoded");
      var0.setRequestProperty("connection", "close");
      if (a != null) {
         var0.setRequestProperty("x-up-calling-line-id", a);
      }

      DataOutputStream var3 = var0.openDataOutputStream();
      if (var2) {
         a(var3, "session=" + b);
         a(var3, "&");
      }

      a(var3, "client=NEOPETS/2.8");
      a(var3, "&");
      a(var3, "game=" + c);
      if (a > 0) {
         a(var3, "&");
         a(var3, "center=" + a);
      }

      if (d != null) {
         a(var3, "&");
         a(var3, "language=" + d);
      }

      a(var3, "\n");
      var3.writeShort(var1.a);
      var3.writeInt(8 * var1.a());
      var1.a(var3);
      var3.writeShort(255);
      var3.close();
   }
   private static final h a(HttpConnection var0) throws IOException, o {
      int var1;
      if ((var1 = var0.getResponseCode()) != 200) {
         throw new o(var1, var0.getResponseMessage());
      } else {
         String var2;
         if ((var2 = var0.getType()) != null && var2.equals("application/x-www-form-urlencoded")) {
            DataInputStream var3;
            String var4;
            String var5;
            if ((var5 = a(var4 = a(var3 = var0.openDataInputStream()), "session")) != null) {
               b(var5);
            }

            String var6;
            if ((var6 = a(var4, "url")) != null) {
               e = var6;
            }

            int var7;
            if ((var7 = var3.read()) == true) {
               return new h(-1, new byte[0]);
            } else {
               int var8 = var7 << 8 | var3.readByte() & 255;
               byte[] var10 = new byte[(var3.readInt() + 7) / 8];
               var3.readFully(var10);
               if (var3.read() != -1) {
                  throw new o(500, "Too much data in response");
               } else {
                  var3.close();
                  if (var8 != 32768 && var8 != 32868) {
                     return new h(var8, var10);
                  } else {
                     throw new o(500, new String(var10, 1, var10.length - 1));
                  }
               }
            }
         } else {
            throw new o(500, "Invalid response Content-Type: " + var2);
         }
      }
   }

Getting sample network requests

  1. Install Kahvibreak
  2. Edit /path/to/Kahvibreak/Software/win32/KLaunch.bat
  3. Change echo NetworkNotAvailable=true>>property.txt to echo NetworkNotAvailable=false>>property.txt
  4. Edit /etc/hosts
  5. Add 127.0.0.1 npprod-singtel.in-fusio.com
  6. Add 127.0.0.1 npprod.in-fusio.com
  7. Run something on port 80 that listens to /data-np/
  8. Launch Neopets Mobile from Kahvibreak
  9. Try to login

Logging in

With username "aaaaaa" and password "bbbbbb", in Python 3 bytes notation:

b'client=NEOPETS/2.8&game=11061&center=61&language=en\n\xa0\x01\x00\x00\x01\xa0\x00\x12\x00\x00\x00\x00\x00@\x00\x00\x00@\x00\x10\x00\x18\x00 \x00\x0eISO-8859-1;2.8\x00\x06aaaaaa\x00\x06bbbbbb\x00\x00\x00\xff'

Signing up

With username "adadad", password "gjgjgj", male green Kacheek, name "cccccc", birthday 1999-12-31, health 6, strength weak, defense very poor, movement slow, height 36 cms, weight 26 lbs, in Python 3 bytes notation:

b'client=NEOPETS/2.8&game=11061&center=61&language=en\n\xa0\x07\x00\x00\x04\xd0\x00:\x00\x00\x00\x00\x00@\x00\x00\x00@\x00\x10\x00\x18\x00 \x00(\x004\x00:\x00>\x00B\x00J\x00S\x00Z\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00$\x00\x00\x00\x1a\x00\x0eISO-8859-1;2.8\x00\x06adadad\x00\x06gjgjgj\x00\x06cccccc\x00\n1999-12-31\x00\x04Male\x00\x02en\x00\x02EN\x00\x06adadad\x00\x07Kacheek\x00\x05GREEN\x00\x04Male\x00\xff'

Reverse engineering the format

I've been renaming symbols in the decompiled source code to slowly figure out what the application is looking for as a response.

The response seems to use the same data structure as the request: a form-encoded set of key-value pairs, then a newline, then some sort of binary data structure.

Shorts seem to be big-endian. Strings seem to be delayed until the end of the structure.