SRL Archive - Help and Support

runescape client


Bobzilla69

2011-11-11 08:13:00

Hi,

Has the current client been decompiled? i dont have a clue about it thats why i am asking, so sorry if its a stupid question.

i am after a decompiled version so i can study it a bit, if anyone can help me i would be very happy

Thanks

YoHoJo

2011-11-11 08:21:55

From: Bobzilla69
Hi,

Has the current client been decompiled? i dont have a clue about it thats why i am asking, so sorry if its a stupid question.

i am after a decompiled version so i can study it a bit, if anyone can help me i would be very happy

Thanks


I think the bot nuke killed all reflection/decompiling etc. and I don't think it will be fixed or coming back any time soon. Pretty sure that's the case.

Flight

2011-11-11 08:26:25

I'd recommend Mopar's forums. They seem to be leading the way in client hacking.

Bobzilla69

2011-11-11 08:30:56

Ok i did think that was the case but i thought i would ask anyways.

has anyone for a copy of the last client? might still prove somewhat helpful

YoHoJo

2011-11-11 08:35:42

Ah yes, +1 for going to Mopar they are big on that stuff/information, they are a gold mine of info about client/client hacking/information.

ollie

2011-11-17 22:42:19

the client is encrypted and obfuscated.

you need to decrypt it first then run it through popcorn's deober with a new control field finder.

From: evangelina

I noticed that iagex implemented a new loader system in rs. The jar file is grabbed from the server. The jar contains the loader and an encrypted 'inner.pack.gz' file which contains the rs classes. To decrypt the file you need the '0' parameter value and the '-1' parameter value. The first one is the 'key' used to decypher the file and the second is the ivParameterSpec.

So if you want to get the rs classes you need to get those 2 parameters including the gamepack which coresponds with those parameters. Don't use another gamepack.jar file from them with the 2 parameters from another rs instance as it won't work.

Main.java:
package com.rubodev;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;

/**
* Created by IntelliJ IDEA.
* User: Vincent
* Date: 15/11/11
* Time: 19:45
* To change this template use File | Settings | File Templates.
*/
public class Main {
public static void main(String[] args) throws IOException {
HashMap<String,byte[]> classes = Utils.decryptPack("parameter '0' value","parameter '-1' value");
JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File("dumpedJar.jar")));
for(String key : classes.keySet()){
byte[] bytes = classes.get(key);
System.out.println(key+" -> "+bytes.length+" bytes" );
jos.putNextEntry(new JarEntry(key.replaceAll("\\.", "/") + ".class"));
jos.write(bytes);
jos.closeEntry();

}
jos.close();
}
}

Utils.java:
package com.rubodev;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.*;
import java.util.HashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
import java.util.zip.GZIPInputStream;

/**
* Created by IntelliJ IDEA.
* User: Vincent
* Date: 15/11/11
* Time: 19:46
* To change this template use File | Settings | File Templates.
*/
public class Utils {
static byte[] decrypt(String arg0) throws Exception {
int j1 = 0;
int i;
int j;
int k;
int l;
byte[] abyte0;
char c1;
int i1;
char c2;
try {
i = arg0.length();
if (0 == i)
return new byte[0];
} catch (RuntimeException runtimeexception) {
throw new Exception("");
}
label0:
{
label1:
{
label2:
{
label3:
{
label4:
{
j = -4 & i + 3;
k = 3 * (j / 4);
if (~i >= ~(-2 + j))
break label1;
c1 = arg0.charAt(j - 2);
if ('\0' <= c1 && c1 < p.length) {
l = p[c1];
if (j1 == 0)
break label4;
}
l = -1;
}
if (~l == 0)
break label1;
if (i <= j - 1)
break label2;
c2 = arg0.charAt(-1 + j);
if (~c2 <= -1 && ~p.length < ~c2) {
i1 = p[c2];
if (j1 == 0)
break label3;
}
i1 = -1;
}
if (0 != ~i1 && j1 == 0)
break label0;
}
k--;
if (j1 == 0)
break label0;
}
k -= 2;
}
abyte0 = new byte[k];
decrypt2(abyte0, 0, arg0, (byte) -75);
return abyte0;
}

static int decrypt2(byte[] arg0, int arg1, String arg2, byte arg3) throws Exception {
int var17 = 0;

try {
int var4 = arg1;
int var5 = arg2.length();
int var6 = 0;

int var10000;
while (true) {
if (var5 > var6) {
char var8 = arg2.charAt(var6);
var10000 = var8;
if (var17 != 0) {
break;
}

int var7;
label128:
{
if (var8 >= 0 && ~p.length < ~var8) {
var7 = p[var8];
if (var17 == 0) {
break label128;
}
}

var7 = -1;
}

int var10;
label140:
{
if (var5 <= 1 + var6) {
var10 = -1;
if (var17 == 0) {
break label140;
}
}

int var11;
label117:
{
char var12 = arg2.charAt(var6 + 1);
if (0 <= var12 && var12 < p.length) {
var11 = p[var12];
if (var17 == 0) {
break label117;
}
}

var11 = -1;
}

var10 = var11;
}

int var19;
label141:
{
if (~(2 + var6) <= ~var5) {
var19 = -1;
if (var17 == 0) {
break label141;
}
}

int var13;
label106:
{
char var14 = arg2.charAt(2 + var6);
if (0 <= var14 && p.length > var14) {
var13 = p[var14];
if (var17 == 0) {
break label106;
}
}

var13 = -1;
}

var19 = var13;
}

int var20;
label142:
{
if (3 + var6 >= var5) {
var20 = -1;
if (var17 == 0) {
break label142;
}
}

int var15;
label95:
{
char var16 = arg2.charAt(3 + var6);
if (0 <= var16 && ~var16 > ~p.length) {
var15 = p[var16];
if (var17 == 0) {
break label95;
}
}

var15 = -1;
}

var20 = var15;
}

arg0[arg1++] = (byte) (var7 << 2 | var10 >>> 4);
if (var19 != -1 || var17 != 0) {
arg0[arg1++] = (byte) (var19 >>> 2 | 240 & var10 << 4);
if (~var20 != 0) {
arg0[arg1++] = (byte) (var20 | var19 << 6 & 192);
var6 += 4;
if (var17 == 0) {
continue;
}
}
}
}

var10000 = arg3;
break;
}

return var10000 > -45 ? 45 : arg1 + -var4;
} catch (RuntimeException var18) {
throw new Exception("");

}
}

public static HashMap<String, byte[]> decryptPack(String variable1, String variable2) {
int dummy = 0;
HashMap<String, byte[]> classes = new HashMap<String, byte[]>();
try {
byte[] key = decrypt(variable1);
byte[] ivParameterSpec = decrypt(variable2);
Cipher cipherObject;
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

try {
cipherObject = Cipher.getInstance("AES/CBC/PKCS5Padding");
(cipherObject).init(2, secretKeySpec, new IvParameterSpec(ivParameterSpec));
} catch (NoSuchPaddingException var34) {
throw new RuntimeException(var34);
} catch (NoSuchAlgorithmException var35) {
throw new RuntimeException(var35);
} catch (InvalidKeyException var36) {
throw new RuntimeException(var36);
} catch (InvalidAlgorithmParameterException var37) {
throw new RuntimeException(var37);
}

InputStream packStream = new FileInputStream(new File("inner.pack.gz"));
if (packStream == null) {

System.exit(1);
}

byte[] buffer = new byte[5242880];
int offset = 0;

int bytesread;
try {
int bytesRead = packStream.read(buffer, offset, 5242880 - offset);

while (-1 != bytesRead) {
offset += bytesRead;
bytesRead = packStream.read(buffer, offset, -offset + 5242880);
bytesread = dummy;

if (bytesread != 0 || dummy != 0) {
break;
}
}
} catch (IOException var44) {
var44.printStackTrace();
}

byte[] dest = new byte[offset];
System.arraycopy(buffer, 0, dest, 0, offset);
byte[] decryptedData = null;

try {
decryptedData = cipherObject.doFinal(dest);
} catch (BadPaddingException var32) {
var32.printStackTrace();
} catch (IllegalBlockSizeException var33) {
var33.printStackTrace();
}
Pack200.Unpacker unpacker = Pack200.newUnpacker();
ByteArrayOutputStream bos = new ByteArrayOutputStream(5242880);

try {
JarOutputStream jos = new JarOutputStream(bos);
GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(decryptedData));
unpacker.unpack(gzip, jos);
jos.close();
} catch (IOException var31) {
var31.printStackTrace();
}


label191:
{
try {
JarInputStream jarInputStream = new JarInputStream(new ByteArrayInputStream(bos.toByteArray()));

JarEntry entry;
while ((entry = jarInputStream.getNextJarEntry()) != null) {
String entryName = entry.getName();
offset = 0;
bytesread = jarInputStream.read(buffer, offset, 5242880 + -offset);
if (dummy != 0) {
break label191;
}

int bytesRead1 = bytesread;

label143:
{
while (true) {
if (0 != ~bytesRead1) {
offset += bytesRead1;
bytesRead1 = jarInputStream.read(buffer, offset, -offset + 5242880);
bytesread = dummy;

if (bytesread != 0) {
break;
}

if (dummy == 0) {
continue;
}
}

if (!entryName.endsWith(".class")) {
break label143;
}

entryName = entryName.replace('/', '.');
break;
}

byte[] desBytes = new byte[offset];
System.arraycopy(buffer, 0, desBytes, 0, offset);
classes.put(entryName.substring(0, entryName.length() + -6), desBytes);
}

if (dummy != 0) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}


}

} catch (Exception e) {
e.printStackTrace();
}
return classes;
}

static int[] p;
private static char[] m;

static {
label0:
{
p = new int[128];
int i1 = 0;
while (~i1 > ~p.length) {
p[i1] = -1;
i1++;
}
break label0;

}
label1:
{
int j1 = 65;
while (-91 <= ~j1) {
p[j1] = -65 + j1;
j1++;
}
break label1;
}
label2:
{
int k1 = 97;
while (122 >= k1) {
p[k1] = k1 + -71;
k1++;
}
break label2;
}
label3:
{
int l1 = 48;
while (-58 <= ~l1) {
p[l1] = (-48 + l1) - -52;
l1++;
}
break label3;
}
label4:
{
p[43] = 62;
int ai[] = p;
ai[42] = 62;
p[47] = 63;
int ai1[] = p;
ai1[45] = 63;
m = new char[64];
int i2 = 0;
while (26 > i2) {
m[i2] = (char) (65 + i2);
i2++;
}
break label4;
}
label5:
{
int j2 = 26;
while (~j2 > -53) {
m[j2] = (char) (-26 + (97 - -j2));
j2++;
}
break label5;
}
label6:
{
int k2 = 52;
while (k2 < 62) {
m[k2] = (char) (-52 + k2 + 48);
k2++;
}
break label6;
}
m[63] = '/';
m[62] = '+';
}


static {
label0:
{
p = new int[128];
int i1 = 0;
while (~i1 > ~p.length) {
p[i1] = -1;
i1++;
}
break label0;
}
label1:
{
int j1 = 65;
while (-91 <= ~j1) {
p[j1] = -65 + j1;
j1++;
}
break label1;
}
label2:
{
int k1 = 97;
while (122 >= k1) {
p[k1] = k1 + -71;
k1++;
}
break label2;
}
label3:
{
int l1 = 48;
while (-58 <= ~l1) {
p[l1] = (-48 + l1) - -52;
l1++;
}
break label3;
}
label4:
{
p[43] = 62;
int ai[] = p;
ai[42] = 62;
p[47] = 63;
int ai1[] = p;
ai1[45] = 63;
m = new char[64];
int i2 = 0;
while (26 > i2) {
m[i2] = (char) (65 + i2);
i2++;
}
break label4;
}
label5:
{
int j2 = 26;
while (~j2 > -53) {
m[j2] = (char) (-26 + (97 - -j2));
j2++;
}
break label5;
}
label6:
{
int k2 = 52;
while (k2 < 62) {
m[k2] = (char) (-52 + k2 + 48);
k2++;
}
break label6;
}
m[63] = '/';
m[62] = '+';
}
}

I'll be improving the code soon and making it more general