|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
发信人: FrankCH (终有绿叶衬), 信区: Java
标 题: Re: 这段代码是什么意思啊?
发信站: BBS 水木清华站 (Wed Jul 3 17:38:34 2002)
【 在 FrankCH (终有绿叶衬) 的大作中提到: 】
: 嘿嘿,这块石头好眼熟啊。。
嘿嘿。。
我贴一段东西大家看看吧。想玩java decode的都该看看的
- $Revision: 1.1 $
- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- Cracking Zelix KlassMaster's String Encryption
- (and how to get hiscores in Java games)
- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- by Morten Poulsen
- [email]m0rtenp@ofir.dk[/email]
- [url]http://www.zelix.com/klassmaster/featuresStringEncryption.html[/url]
- "However, note that Zelix KlassMaster's String Encryption isn't and
- cannot be fundamentally irreversible."
- Introduction
- ~~~~~~~~~~~~
- To make decompilation of Java applets and making changes to the code more
- difficult, and to hide secret information (eg. how to calculate hashes for
- hiscores) people obfuscate their java bytecode. Some of the ways to do so is
- to scramble the line number tables, replace all names of classes, methods an
- d
- variables with nonsense, and the one we will look at, string encryption.
- You will need a few tools to help you do the job:
- - Java decompiler (Jad)
- - editor (vim)
- - common sense (brain)
- some knowlage about JVMs will be nice, but I tell you everything you need to
- know here. If you want to make your own cracks, you need that knowlage.
- Some tools are nice to have when cracking the hiscore tables of Java games:
- - TCP sniffer (tcpdump)
- - "Java enabled" browser (Mozilla)
- - C compiler (gcc)
- - all the GNU tools (eg. grep)
- - webserver with PHP ;-)
- What's going on?
- ~~~~~~~~~~~~~~~~
- Forst of all we need to find a game to crack. The games on Coca~Cola's
- (nordic) website looks like great candidates. Start the TCP sniffer (tcpdump
- -w file), and launch the game. Play the game and write down your score. Stop
- the TCP sniffer, and open the file (vi file). Search for your score in the
- binary masses. You shuld find a line a'la:
- GET /magazine/servlet/SetHighscoreServlet?score=6324&game=0&cookie=yourname&
- md5=c404cd019e1a214487cd4c841
- So all we need to know is how to generate the md5 hash, then we will be able
- to make our own hiscores, hopefully.
- Decompiling and Thinking
- ~~~~~~~~~~~~~~~~~~~~~~~~
- Download the .jar archive containing the game (hint: view source, <applet
- >
- tag, archive=...), unpack it and decompile each class. Now try to find the
- place in the code where the result is send back to the server (fgrep -rn "UR
- L"
- *). b/a/a.java line 122 (decompiled with jad) looks like a god place to star
- t.
- It reads:
- URL url = new URL(c, b("L9\001 qMdK|)\016rZ!\f\007cfg8\ndMa-\007DK|)
- \016rZ1,\001x\\kb") + Integer.toString(i) + b("DpOc:_") + d + b("DtA
- a4\013r\023") + e + b("DzJ;b") + a.a.a.a.a.a(i, Integer.parseInt(d), e))
- ;
- The URL looks a lot like what we seek:
- "long text"+i+"text"+d+"text"+e+"text"+result_of_calculation(i,d,e)
- the problems are now "are these strings the ones we seek?" (just for the fun
- of it - lets find out) and "what does a.a.a.a.a.a() do?".
- Open the file (vi b/a/a.java) and seek to line 122. We can see that the
- method used to decrypt the string is b(). Seek to b() (line 224). It looks
- like this:
- 224: private static String b(String s)
- 225: {
- 226: char ac[];
- 227: int i;
- 228: int j;
- 229: ac = s.toCharArray();
- 230: i = ac.length;
- 231: j = 0;
- 232: goto _L1
- 233: _L9:
- 234: ac;
- 235: j;
- 236: JVM INSTR dup2 ;
- 237: JVM INSTR caload ;
- 238: j % 5;
- 239: JVM INSTR tableswitch 0 3: default 76
- 240: // 0 52
- 241: // 1 58
- 242: // 2 64
- 243: // 3 70;
- 244: goto _L2 _L3 _L4 _L5 _L6
- 245: _L3:
- 246: 0x62;
- 247: goto _L7
- 248: _L4:
- 249: 23;
- 250: goto _L7
- 251: _L5:
- 252: 46;
- 253: goto _L7
- 254: _L6:
- 255: 14;
- 256: goto _L7
- 257: _L2:
- 258: 95;
- 259: _L7:
- 260: JVM INSTR ixor ;
- 261: (char);
- 262: JVM INSTR castore ;
- 263: j++;
- 264: _L1:
- 265: if(j < i) goto _L9; else goto _L8
- 266: _L8:
- 267: return new String(ac);
- 268: }
- Java's Virtual Machine is a stack based machine. That is, there is only o
- ne
- register, the instruction pointer, the rest of what registers are normaly us
- ed
- for is done on the stack. Example: c=a+b is done PUSH a, PUSH b, ADD (which
- pop the operands off the stack, and push the result back), POP c.
- If we look closer at the code, we can see that the lines 232,233,264,265,
- 266 are just a while-loop, looping through the chars in the string. Line 238
- pushes the result of j (the index into the string) modulus 5 on the stack.
- Lines 239-259 looks like a switch/case, pushing a nubmer onto the stack, bas
- ed
- on j%5. Line 260 pops two operands off the stack - a char from the encrypted
- string, and the mysterious number, and pushes back the result of an XOR. Ah!
- The mysterious numbers are the key of a simple XOR encryption! Written in C
- it
- would look like:
- for (j=0; j<strlen(str); j++) {
- str[j] ^= key[j%5];
- }
- that's it. Just a plain 40-bit XOR. Let's make a short program to decrypt a
- string. I am lazy so everything is hard-coded.
- decode1.c:
- ----------------------------------------------------------------------------
- --
- #include <stdlib.h>
- #define KEYSIZE 5
- int main(void) {
- unsigned char buf[] = "L9\001 qMdK|)\016rZ!\f\007cfg8\ndMa-\007DK|)\016r
- Z1,\001x\\kb";
- unsigned char key1[] = { 0x62, 23, 46, 14, 95 };
- unsigned char c;
- int i;
- for (i=0; i<strlen(buf); i++) {
- c = buf[i] ^ key1[i%KEYSIZE];
- printf("%c", c);
- }
- printf("\n");
- return EXIT_SUCCESS;
- }
- ----------------------------------------------------------------------------
- --
- weeee, running it (gcc decode1.c && ./a.out) returns:
- ../../servlet/SetHighscoreServlet?score=
- so this was all that had to be done! A few lines of C, and the strings can b
- e
- decrypted.
- The Hash Function
- ~~~~~~~~~~~~~~~~~
- The hash in the HTTP-request looks a lot like an MD5, and the name in the
- URL is "md5", so my guess is: It's an md5 of the score, the game id, the
- username and some secret string. But why does the method take three paramete
- rs
- (long,int,String)? That's not normal for MD5 functions. Open the file (vi
- a/a/a/a/a.java) and seek to the version of a() taking the three parameters
- (line 83). Ah! It calls the real MD5 method with a string:
- (l + i) + s + "some secret string"
- where l is the score, i is the gameid and s is the username. But the secret
- string is encrypted. Actualy it is encrypted two times (see, it calls both c
- ()
- and b()), but that shuld be no problem at all.
- Seek to method c() (line 140). Ha! It's just like the other one, only the
- key is changed. Let's have a look at methos b() (line 89). Haha, the same
- thing here. So all we need to do to get the secret string is to change a few
- lines in the decode program so it can handle two keys.
- decode2.c:
- ----------------------------------------------------------------------------
- --
- #include <stdlib.h>
- #define KEYSIZE 5
- #define BUFSIZE 25 /* needed, 'cause buf has a null byte */
- int main(void) {
- unsigned char buf[] = "mS?\032<lD/\0137aS&\003<e_,\013*}D.\000>";
- unsigned char key1[] = { 0x71, 103, 47, 41, 9 };
- unsigned char key2[] = { 120, 81, 100, 71, 80 };
- unsigned char c;
- int i;
- for (i=0; i<BUFSIZE; i++) {
- c = buf[i] ^ key1[i%KEYSIZE] ^ key2[i%KEYSIZE];
- printf("%c", c);
- }
- printf("\n");
- return EXIT_SUCCESS;
- }
- ----------------------------------------------------------------------------
- --
- running the program gives us the result "detteerdenhemmeligestreng" which is
- danish for "thisisthesecretstring". ROFL.
- Exploiting the Hiscore
- ~~~~~~~~~~~~~~~~~~~~~~
- WARNING! Don't try this at home, you will just get into trouble ;-)
- I am lazy, so I wrote a little PHP script to generate the URL's to request
- from the server to set hiscores (eg. just copy/paste into browser). Try it t
- o
- see if the hash is the same as the one you got playing the game (no, my hash
- here is fake, use your own).
- hash.php:
- ----------------------------------------------------------------------------
- --
- <html>
- <head>
- <title>Coca~Cola hiscore generator</title>
- </head>
- <body>
- <?php
- if ($cookie) print("http://www.coca-cola.fi/magazine/servlet/SetHighsc
- oreServlet?score=$score&game=$game&cookie=$cookie&md5=".md5($score.$cookie.'
- detteerdenhemmeligestreng')."<br>\n");
- print("<form>\n");
- print("<input type="text" name="score" value="" . (int)$score . "
- " size="10"><br>\n");
- print("<input type="text" name="game" value="" . (int)$game . ""
- size="2"><br>\n");
- print("<input type="text" name="cookie" value="$cookie" size="3
- 0"<br>\n");
- print("<input type="submit" value="go go go">\n");
- print("</form>");
- ?>
- </body>
- </html>
- ----------------------------------------------------------------------------
- --
复制代码 |
|