PDA

View Full Version : Decrypting npgm.erl


nForce
1st July 2006, 16:20
I decided to reverse engineer the encryption algorithm responsible for encrypting npgm.erl.

It was a little bit more difficult but you will see the algorithm is still very similar to what was used for npgg.erl and npgl.erl. Unlike the previous encryption system, a strange timestamp is stored where the remainder of a specific operations is XORd with 85 (55h). This remainder is the index to a key table which I have extracted. By obtaining the remainder once again we can extract the correct key from the key table and feed it into the algorithm we are familiar with, the same one used for decrypting npgg/npgl. Proof of concept code is provided bellow.

Please remember, the key table may differ depending on the game as well there are some other values that might change depending on the game.

/************************************************** **********************************
* Project: ERL (Type2) Decryptor *
* *
* Copyright (C) 2006 by nForce *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
************************************************** **********************************/

#include <iostream>
#include <fstream>

using namespace std;

int main ( int nArguments, const char * szArguments [] )
{
static const unsigned long nKeyTable [] =
{
0x14C4D0D4, 0x2F4F636C,
0x1BCBD3D8, 0x3888B0B8,
0xB83888B0, 0x70314171,
0x080B0B03, 0x29C9E1E8,
0x0E8E828C, 0x34340430
};

if ( nArguments > 1 )
{
std::string sOutput ( szArguments [ 1 ] );
ifstream ifsTargetFile ( sOutput.c_str (), ios::binary );

if ( ifsTargetFile.is_open () )
{
sOutput.append ( ".dec" );
ofstream ofsOutputFile ( ( sOutput.c_str () ) );

if ( ofsOutputFile.is_open () )
{
unsigned long nTimeStamp;
ifsTargetFile.read ( ( ( char * ) ( & nTimeStamp ) ), 4 );

unsigned long nKeyIndex = ( ( ( nTimeStamp >> 16 ) & 0xff ) ^ 0x55 );
if ( nKeyIndex >= 10 )
{
cout << "Error: Key index is out of range!" << endl;
return 1;
}

unsigned long nCryptoKey = nKeyTable [ nKeyIndex ];

while ( ifsTargetFile.good () )
{
nCryptoKey = ( nCryptoKey * 3 + 1 );

unsigned char nEncryptedByte;
ifsTargetFile.get ( ( * ( char * ) ( & nEncryptedByte ) ) );

unsigned char nCryptoByte = ( unsigned char ) ( nCryptoKey & 0xff );
nCryptoByte = nCryptoByte + 0x58;
nEncryptedByte = nCryptoByte ^ nEncryptedByte;

ofsOutputFile.put ( ( * ( char * ) ( & nEncryptedByte ) ) );
}

ofsOutputFile.close ();
}
else
{
cout << "Unable to open " << sOutput.c_str () << " for output!" << endl;
}

ifsTargetFile.close ();
}
else
{
cout << "Unable to open " << sOutput.c_str () << " for input!" << endl;
}
}
else
{
cout << "Syntax Error!" << endl
<< "Syntax: " << szArguments [ 0 ] << " <Erl File>" << endl;
}

return 0;
}

temp2
2nd July 2006, 02:46
I decided to reverse engineer the encryption algorithm responsible for encrypting npgm.erl.

This remainder is the index to a key table which I have extracted.

Please remember, the key table may differ depending on the game as well there are some other values that might change depending on the game.


Great work. Nope its the same.

.text:0040681A cmp eax, 0FFFFFFFFh
.text:0040681D mov [ebp+var_7C], 14C4D0D4h
.text:00406824 mov [ebp+var_78], 2F4F636Ch
.text:0040682B mov [ebp+var_74], 1BCBD3D8h
.text:00406832 mov [ebp+var_70], 3888B0B8h
.text:00406839 mov [ebp+var_6C], 0B83888B0h
.text:00406840 mov [ebp+var_68], 70314171h
.text:00406847 mov [ebp+var_64], 80B0B03h
.text:0040684E mov [ebp+var_60], 29C9E1E8h
.text:00406855 mov [ebp+var_5C], 0E8E828Ch
.text:0040685C mov [ebp+var_58], 34340430h
.text:00406863 jnz loc_406AC1


========== Log Started at 2006/06/16 23:01:10:213 ==========
23:01:10:213 --- GameMon.des version 664 : Wed Feb 15 10:33:10 2006 ---
23:01:10:213 cmd: 12124634816 3428 1 492 488 Lineage2us 1e4 1d4 0
23:01:10:213 argc: 9, argv: 121634234816 3428 1 492 488 Lineage2us
...
23:01:11:822 -- ParseIni done
23:01:11:822 CS2: PrtcLibVer 1.45
23:01:11:822 -- InitNPGM
23:01:11:822 Admin Privilege
23:01:14:431 reggms: 2
23:01:14:431 npscan: D:\Games\Lineage II\system\GameGuard\npscan.des
23:01:14:447 Try to turn on npscan
23:01:14:462 Virobot Turn ON
23:01:14:462 GGSM_MUTEX: bc
23:01:14:462 NPGG_SHAREDMEM: 1
23:01:14:462 ReadSMThread(c4) ID: 8760
23:01:14:462 -- InitGameHook
23:01:14:462 gamemon: D:\Games\Lineage II\system\GameGuard\GameMon.des
23:01:14:494 HOOKSDLL: D:\Games\Lineage II\system\GameGuard\npggNT.des
23:01:14:634 MDOI: ntdll.dll
23:01:14:634 MDOI: kernel32.dll
23:01:15:134 MDOI: user32.dll
23:01:15:400 MDOI: advapi32.dll
23:01:15:525 MDO: 0 0 0 0
23:01:15:525 CloneFile: D:\Games\Lineage II\system\L2.exe
23:01:15:525 SmssPID: 224, \systemroot\system32\smss.exe
23:01:15:540 CsrssPID: 252, \??\c:\sys\system32\csrss.exe
23:01:15:540 LsassPID: 320, c:\sys\system32\lsass.exe
23:01:15:540 ClonePID: 3428, D:\games\lineage ii\system\l2.exe
23:01:15:540 NPGG_MUTEX: 18
23:01:15:556 LdrGetDllHandle: 77f85b c
23:01:15:556 NtQuerySystemInformation: 77f889dc
23:01:15:556 NtResumeThread: 77f88bbc
23:01:15:556 Admin Account
23:01:15:556 VirtualProtectEx: 55 8b EC FF 75 18 8D 45 10 FF
23:01:15:556 DebugActiveProcess: 55 8b EC 81 EC 90 0 00 00 53
23:01:15:556 GameModule start: 10900000, limit: 1097D000
23:01:15:712 N/A, 8, N/A (error4)
23:01:15:712 NATIVE SYSTEM PROCESS, smss.exe, ski
23:01:15:712 GameHook: Hooking 252='csrss.exe' ..
23:01:15:775 : InitNPGG, GamePID: 3428, GameWnd: 0, 0, MonPID: 9908, CurrPID: 252
23:01:15:790 LAC IGG Success
23:01:15:822 GameHook: Hooking 248='winlogon.exe' ..
23:01:15:869 : InitNPGG, GamePID: 3428, GameWnd: 0, 0, MonPID: 9908, Curr ID: 248
...

sstevenn6t9
3rd July 2006, 03:08
Uhh Im looking for how to bypass nProtect / nGuard .. is that the same thing?

temp2
3rd July 2006, 07:14
if ( nEncryptedByte == 0x8 )
{
ofsOutputFile << endl;
}
else


Certainly for me this test can be omitted.

Neiltwo2
4th July 2006, 10:10
it looks so hard xD

nForce
4th July 2006, 12:18
Certainly for me this test can be omitted.

Yes actually that can be removed, it was a mistake on my part. I updated the code above and reuploaded the binaries. Thanks for pointing it out.

SunBeam
7th August 2006, 09:33
Wouldn't it be possible to read that log as it gets processed by GameMon ? I am attempting to test your application for MapleStory and it errors me with "Error: Key index is out of range!"

nForce
8th August 2006, 00:13
If possible post the npgm.erl that cannot be decrypted, and the version of GameGuard Maple Story currently uses.

Exidis
8th August 2006, 00:21
Rev 817 is latest on maple story.

SunBeam
10th August 2006, 01:07
Updated to 818, but it shouldn't matter. Thanks for taking a look...

nForce
11th August 2006, 05:53
Indeed it looks like they might, unless I'm mistaken, have changed their encryption algorithm. Or perhaps they have just changed their key table. Regardless this might have been in response to this release. For this reason it would seem somewhat pointless to continue releasing reversals of their algorithms if they are this quick to patch them.

moaraj
6th October 2006, 01:39
i know this sounds stupid but why dont u just restar while it is sending

HackerzNeo
6th October 2006, 15:29
i know this sounds stupid but why dont u just restar while it is sending

then u cant play maple

idea1:

Sunbeam is this possible?

u block out the log sending using Zone Alarm?

i386
10th October 2006, 02:27
This thread intrigues me. Has there been any follow-up work done? I think with the recent updates your algorithm might be obsolete, maybe it's just me. My *.erl files are being translated into some chinese language-set garble.

edit: yeah yeah, search button, sorry. found the new threads. my bad. ;]

x0r
25th December 2006, 22:14
which extension is the keyfile? <Key File> ?

bornarascal
15th January 2007, 09:13
i 386 ur right i tryed using my own perl made decrypter eh not so reliable but i get some asci text and then some chinese set garbage to

pursuit11
20th January 2007, 18:34
If possible, would you mind checking to see if u can manage these erls from flyff?
GG rev 942

Thank You if you are able to try this.