Results 1 to 6 of 6
  1. #1
    Dwar
    Dwar is offline
    Veteran Dwar's Avatar
    Join Date
    2010 Mar
    Posts
    2,222
    Thanks Thanks Given 
    211
    Thanks Thanks Received 
    2,230
    Thanked in
    292 Posts
    Rep Power
    10

    [Guide] Reversing SoulMaster NPK encryption algorithm

    Reversing SoulMaster NPK encryption algorithm
    It will be guide with explanation how to find encryption algorithm that used for unpacking .npk resource files of SoulMaster.

    You have already setup/tuned Ollydbg and run SoulMaster under debugger.

    Analyze main module “smc.exe”, call “find all referenced strings” and find strings with “.npk”. Choose first entry (it should be “acid_effect.npk”) and proceed to CPU.

    We get npk loading algorithm.
     0075DB81  |.  68 B8000000   push    0xB8
    => 0075DB86 |. C74424 1C C51>mov dword ptr [esp+0x1C], 0x18C5
    => 0075DB8E |. C74424 20 5A0>mov dword ptr [esp+0x20], 0xD5A
    => 0075DB96 |. C74424 24 940>mov dword ptr [esp+0x24], 0x594
    => 0075DB9E |. C74424 28 941>mov dword ptr [esp+0x28], 0x1294
    0075DBA6 |. E8 37322100 call 00970DE2
    0075DBAB |. 8BD8 mov ebx, eax
    0075DBAD |. 83C4 04 add esp, 0x4
    0075DBB0 |. 895C24 14 mov dword ptr [esp+0x14], ebx
    ...... (skipped)
    0075DBE9 |. 90 nop
    0075DBEA |. 8BC8 mov ecx, eax
    0075DBEC |. 90 nop
    0075DBED |. E8 EE711304 call 04894DE0
    0075DBF2 |. 8B1D C0539C00 mov ebx, dword ptr [0x9C53C0]
    => 0075DBF8 |. 68 70E8A300 push 00A3E870 ; ASCII "acid_effect.npk"
    0075DBFD |. 50 push eax
    0075DBFE |. 8D5424 30 lea edx, dword ptr [esp+0x30]
    0075DC02 |. 52 push edx
    0075DC03 |. C78424 B00000>mov dword ptr [esp+0xB0], 0xA
    0075DC0E |. FFD3 call ebx
    0075DC10 |. 83C4 0C add esp, 0xC
    0075DC13 |. 894424 14 mov dword ptr [esp+0x14], eax
    0075DC17 |. 8B4E 0C mov ecx, dword ptr [esi+0xC]
    0075DC1A |. 8B01 mov eax, dword ptr [ecx]
    0075DC1C |. 8B40 18 mov eax, dword ptr [eax+0x18]
    0075DC1F |. 8D5424 18 lea edx, dword ptr [esp+0x18]
    0075DC23 |. 52 push edx
    0075DC24 |. 8B5424 18 mov edx, dword ptr [esp+0x18]
    0075DC28 |. 52 push edx
    0075DC29 |. C68424 AC0000>mov byte ptr [esp+0xAC], 0xB
    => 0075DC31 |. FFD0 call eax ; Calling NPK loader
    0075DC33 |. 8D4C24 28 lea ecx, dword ptr [esp+0x28]
    0075DC37 |. C68424 A40000>mov byte ptr [esp+0xA4], 0xA
    0075DC3F |. 90 nop
    0075DC40 |. E8 5F82D277 call 78485EA4
    0075DC45 |. 8D4C24 48 lea ecx, dword ptr [esp+0x48]
    0075DC49 |. 89AC24 A40000>mov dword ptr [esp+0xA4], ebp
    0075DC50 |. 90 nop
    0075DC51 |. E8 4E82D277 call 78485EA4

    Pay attention to first 4 instructions:
    • mov dword ptr [esp+0x1C], 0x18C5
      mov dword ptr [esp+0x20], 0xD5A
      mov dword ptr [esp+0x24], 0x594
      mov dword ptr [esp+0x28], 0x1294

    You can scroll a little bit down and notice, that the same instructions with different values always appear before each .npk.
    Ok, we set BP on 0075DBF8 and run app. When the app stops on BP step over until several steps 0075DC31. It’s a call for NPK loader/unpacker.

    NPK loading algorithm
     04901770   .  6A FF         push    -0x1
    04901772 . 68 FA389C04 push 049C38FA
    04901777 . 64:A1 0000000>mov eax, dword ptr fs:[0]
    0490177D . 50 push eax
    0490177E . 83EC 44 sub esp, 0x44
    04901781 . A1 F80CB604 mov eax, dword ptr [0x4B60CF8]
    04901786 . 33C4 xor eax, esp
    ...... (skipped)
    0490183A . 50 push eax
    0490183B . 68 A854A604 push 04A654A8 ; ASCII "GxNPackage::Create - Fail to find file %s"
    04901840 . E8 4BDBF2FF call 0482F390
    04901845 . 83C4 08 add esp, 0x8
    04901848 . 85F6 test esi, esi
    0490184A . 0F84 2D010000 je 0490197D
    04901850 . 56 push esi
    04901851 . E9 21010000 jmp 04901977
    04901856 > 8B4C24 18 mov ecx, dword ptr [esp+0x18]
    0490185A . 51 push ecx
    0490185B . 8BCB mov ecx, ebx
    0490185D . FF15 50739C04 call dword ptr [0x49C7350]
    04901863 . 50 push eax
    => 04901864 . E8 E7FF0100 call 04921850 ; loading NPK, NPK checker, decryption
    04901869 . 83C4 08 add esp, 0x8
    0490186C . 8945 64 mov dword ptr [ebp+0x64], eax
    0490186F . 85C0 test eax, eax
    04901871 . 75 3B jnz short 049018AE


    Loading NPK, NPK checker, decryption
     04921850  /$  81EC 30020000 sub     esp, 0x230
    04921856 |. A1 F80CB604 mov eax, dword ptr [0x4B60CF8]
    0492185B |. 33C4 xor eax, esp
    0492185D |. 898424 2C0200>mov dword ptr [esp+0x22C], eax
    04921864 |. 53 push ebx
    04921865 |. 8B9C24 3C0200>mov ebx, dword ptr [esp+0x23C]
    0492186C |. 55 push ebp
    0492186D |. 56 push esi
    0492186E |. 57 push edi
    0492186F |. 8BBC24 440200>mov edi, dword ptr [esp+0x244]
    04921876 |. 6A 4C push 0x4C ; /size = 4C (76.)
    04921878 |. 895C24 20 mov dword ptr [esp+0x20], ebx ; |
    0492187C |. C74424 14 000>mov dword ptr [esp+0x14], 0x0 ; |
    04921884 |. FF15 E4739C04 call dword ptr [0x49C73E4] ; malloc
    ...... (skipped)
    049218E1 |. E8 2A0B0000 call 04922410
    049218E6 |. 83C4 1C add esp, 0x1C
    049218E9 |. 83F8 01 cmp eax, 0x1
    049218EC |. 0F85 6E030000 jnz 04921C60

    ; reading first 4 bytes from file and checking the file header
    049218F2 |. 6A 04 push 0x4
    049218F4 |$ 68 ACF0A704 push 04A7F0AC ; |s2 = "NPK!"
    049218F9 |. 55 push ebp ; |s1
    049218FA |. FF15 94749C04 call dword ptr [0x49C7494] ; strncmp
    04921900 |. 83C4 0C add esp, 0xC
    04921903 |. 85C0 test eax, eax
    04921905 |. 74 19 je short 04921920
    04921907 |. 6A 04 push 0x4 ; /maxlen = 4
    04921909 |. 68 A4F0A704 push 04A7F0A4 ; |s2 = "NPAK"
    0492190E |. 55 push ebp ; |s1
    0492190F |. FF15 94749C04 call dword ptr [0x49C7494] ; strncmp
    04921915 |. 83C4 0C add esp, 0xC
    04921918 |. 85C0 test eax, eax
    0492191A |. 0F85 40030000 jnz 04921C60
    04921920 |> 8B45 04 mov eax, dword ptr [ebp+0x4]
    04921923 |. 83F8 15 cmp eax, 0x15
    04921926 |. 7D 0A jge short 04921932
    04921928 |. 68 01FFFFFF push -0xFF
    0492192D |. E9 26030000 jmp 04921C58
    04921932 |> 85DB test ebx, ebx
    04921934 |. 75 07 jnz short 0492193D
    04921936 |. 6A DF push -0x21
    04921938 |. E9 1B030000 jmp 04921C58
    0492193D |> 83F8 17 cmp eax, 0x17

    ; adding ciphers to the stack
    04921940 |. 8B0B mov ecx, dword ptr [ebx]
    04921942 |. 894D 18 mov dword ptr [ebp+0x18], ecx
    04921945 |. 8B53 04 mov edx, dword ptr [ebx+0x4]
    04921948 |. 8955 1C mov dword ptr [ebp+0x1C], edx
    0492194B |. 8B4B 08 mov ecx, dword ptr [ebx+0x8]
    0492194E |. 894D 20 mov dword ptr [ebp+0x20], ecx
    04921951 |. 8B53 0C mov edx, dword ptr [ebx+0xC]
    04921954 |. 8955 24 mov dword ptr [ebp+0x24], edx
    04921957 |. 7C 2B jl short 04921984
    ...... (skipped)
    049219EB |. 6A 01 push 0x1
    049219ED |. 51 push ecx
    049219EE |. 53 push ebx
    049219EF |. 50 push eax
    049219F0 |. 8B4424 34 mov eax, dword ptr [esp+0x34]
    049219F4 |. 52 push edx
    049219F5 |. 50 push eax
    => 049219F6 |. E8 F50A0000 call 049224F0

    After that, app calculates the position of encrypted data in .npk and copy it to the buffer
    Step into the: 049219F6 |. E8 F50A0000 call 049224F0
    Inside, after another “step into”, we will stopped on
     04922860  /$  8B4424 08     mov     eax, dword ptr [esp+0x8]
    04922864 |. 8BC8 mov ecx, eax
    04922866 |. 83E1 07 and ecx, 0x7
    04922869 |. 56 push esi
    0492286A |. 8B7424 08 mov esi, dword ptr [esp+0x8]
    0492286E |. 2BC1 sub eax, ecx
    04922870 |. 57 push edi
    04922871 |. 8D3C30 lea edi, dword ptr [eax+esi]
    04922874 |. 3BF7 cmp esi, edi
    04922876 |. 73 1A jnb short 04922892
    04922878 |. 53 push ebx
    04922879 |. 8B5C24 18 mov ebx, dword ptr [esp+0x18]
    0492287D |. 8D49 00 lea ecx, dword ptr [ecx]
    => 04922880 |> 53 /push ebx
    => 04922881 |. 56 |push esi
    => 04922882 |. E8 39FFFFFF |call 049227C0
    => 04922887 |. 83C6 08 |add esi, 0x8
    => 0492288A |. 83C4 08 |add esp, 0x8
    => 0492288D |. 3BF7 |cmp esi, edi
    => 0492288F |.^ 72 EF jb short 04922880
    04922891 |. 5B pop ebx
    04922892 |> 5F pop edi
    04922893 |. 5E pop esi
    04922894 . C3 retn

    Here the cycle that passes to the decryption algorithm two dwords from the buffer.
    In EDI stored the latest dword from the buffer (in my case for “acid_effect.npk“ it equal to EDI 06DA16D0 ASCII ".glua"). Ok, and this “call 049227C0” point to decryptor.

    Now, C++ decryption code.
    Function DecryptMemory – decryption of given memory block
    Parameters:
    Buffer – Pointer to a region with encrypted data.
    BufSize – Size of the Buffer.
    DecryptTable – Pointer to ciphers (4 DWORD's)
     void __stdcall __declspec(naked) DecryptMemory(void *Buffer, size_t BufSize, void *DecryptTable)
    {
    __asm
    {
    l04942860: MOV EAX, [ESP+0x8]
    l04942864: MOV ECX, EAX
    l04942866: AND ECX, 0x7
    l04942869: PUSH ESI
    l0494286A: MOV ESI, [ESP+0x8]
    l0494286E: SUB EAX, ECX
    l04942870: PUSH EDI
    l04942871: LEA EDI, [EAX+ESI]
    l04942874: CMP ESI, EDI
    l04942876: JNB l04942892
    l04942878: PUSH EBX
    l04942879: MOV EBX, [ESP+0x18]
    l0494287D: LEA ECX, [ECX]
    l04942880: PUSH EBX
    l04942881: PUSH ESI
    l04942882: CALL l049427C0
    l04942887: ADD ESI, 0x8
    l0494288A: ADD ESP, 0x8
    l0494288D: CMP ESI, EDI
    l0494288F: JB l04942880
    l04942891: POP EBX
    l04942892: POP EDI
    l04942893: POP ESI
    l04942894: RETN

    l049427C0: SUB ESP, 0x10
    l049427C3: MOV EAX, [ESP+0x14]
    l049427C7: MOV ECX, [EAX]
    l049427C9: MOV EAX, [EAX+0x4]
    l049427CC: PUSH EBX
    l049427CD: PUSH ESI
    l049427CE: PUSH EDI
    l049427CF: MOV EDI, [ESP+0x24]
    l049427D3: MOV EBX, [EDI+0x8]
    l049427D6: MOV [ESP+0x10], EBX
    l049427DA: MOV EBX, [EDI+0xC]
    l049427DD: MOV [ESP+0xC], EBX
    l049427E1: MOV EBX, [EDI+0x4]
    l049427E4: MOV EDI, [EDI]
    l049427E6: MOV ESI, 0x20
    l049427EB: MOV EDX, 0xC6EF3720
    l049427F0: MOV [ESP+0x18], EBX
    l049427F4: MOV [ESP+0x14], EDI
    l049427F8: JMP l04942800
    l049427FA: LEA EBX, [EBX]
    l04942800: MOV EDI, ECX
    l04942802: SHR EDI, 0x5
    l04942805: ADD EDI, [ESP+0xC]
    l04942809: MOV EBX, ECX
    l0494280B: SHL EBX, 0x4
    l0494280E: ADD EBX, [ESP+0x10]
    l04942812: DEC ESI
    l04942813: XOR EDI, EBX
    l04942815: LEA EBX, [EDX+ECX]
    l04942818: XOR EDI, EBX
    l0494281A: SUB EAX, EDI
    l0494281C: MOV EDI, EAX
    l0494281E: SHL EDI, 0x4
    l04942821: ADD EDI, [ESP+0x14]
    l04942825: MOV EBX, EAX
    l04942827: SHR EBX, 0x5
    l0494282A: ADD EBX, [ESP+0x18]
    l0494282E: XOR EDI, EBX
    l04942830: LEA EBX, [EDX+EAX]
    l04942833: XOR EDI, EBX
    l04942835: SUB ECX, EDI
    l04942837: ADD EDX, 0x61C88647
    l0494283D: TEST ESI, ESI
    l0494283F: JA l04942800
    l04942841: MOV EDX, [ESP+0x20]
    l04942845: POP EDI
    l04942846: POP ESI
    l04942847: MOV [EDX], ECX
    l04942849: MOV [EDX+0x4], EAX
    l0494284C: POP EBX
    l0494284D: ADD ESP, 0x10
    l04942850: RETN
    }
    }


    Another one for Delphi
     procedure DecryptMemory(Buffer: Pointer; BufSize: Cardinal; DecryptTable: Pointer); stdcall;
    begin
    asm
    mov esp, ebp
    pop ebp

    @l04942860: MOV EAX, [ESP+$8]
    @l04942864: MOV ECX, EAX
    @l04942866: AND ECX, $7
    @l04942869: PUSH ESI
    @l0494286A: MOV ESI, [ESP+$8]
    @l0494286E: SUB EAX, ECX
    @l04942870: PUSH EDI
    @l04942871: LEA EDI, [EAX+ESI]
    @l04942874: CMP ESI, EDI
    @l04942876: JNB @l04942892
    @l04942878: PUSH EBX
    @l04942879: MOV EBX, [ESP+$18]
    @l0494287D: LEA ECX, [ECX]
    @l04942880: PUSH EBX
    @l04942881: PUSH ESI
    @l04942882: CALL @l049427C0
    @l04942887: ADD ESI, $8
    @l0494288A: ADD ESP, $8
    @l0494288D: CMP ESI, EDI
    @l0494288F: JB @l04942880
    @l04942891: POP EBX
    @l04942892: POP EDI
    @l04942893: POP ESI
    @l04942894: RETN

    @l049427C0: SUB ESP, $10
    @l049427C3: MOV EAX, [ESP+$14]
    @l049427C7: MOV ECX, [EAX]
    @l049427C9: MOV EAX, [EAX+$4]
    @l049427CC: PUSH EBX
    @l049427CD: PUSH ESI
    @l049427CE: PUSH EDI
    @l049427CF: MOV EDI, [ESP+$24]
    @l049427D3: MOV EBX, [EDI+$8]
    @l049427D6: MOV [ESP+$10], EBX
    @l049427DA: MOV EBX, [EDI+$C]
    @l049427DD: MOV [ESP+$C], EBX
    @l049427E1: MOV EBX, [EDI+$4]
    @l049427E4: MOV EDI, [EDI]
    @l049427E6: MOV ESI, $20
    @l049427EB: MOV EDX, $C6EF3720
    @l049427F0: MOV [ESP+$18], EBX
    @l049427F4: MOV [ESP+$14], EDI
    @l049427F8: JMP @l04942800
    @l049427FA: LEA EBX, [EBX]
    @l04942800: MOV EDI, ECX
    @l04942802: SHR EDI, $5
    @l04942805: ADD EDI, [ESP+$C]
    @l04942809: MOV EBX, ECX
    @l0494280B: SHL EBX, $4
    @l0494280E: ADD EBX, [ESP+$10]
    @l04942812: DEC ESI
    @l04942813: XOR EDI, EBX
    @l04942815: LEA EBX, [EDX+ECX]
    @l04942818: XOR EDI, EBX
    @l0494281A: SUB EAX, EDI
    @l0494281C: MOV EDI, EAX
    @l0494281E: SHL EDI, $4
    @l04942821: ADD EDI, [ESP+$14]
    @l04942825: MOV EBX, EAX
    @l04942827: SHR EBX, $5
    @l0494282A: ADD EBX, [ESP+$18]
    @l0494282E: XOR EDI, EBX
    @l04942830: LEA EBX, [EDX+EAX]
    @l04942833: XOR EDI, EBX
    @l04942835: SUB ECX, EDI
    @l04942837: ADD EDX, $61C88647
    @l0494283D: TEST ESI, ESI
    @l0494283F: JA @l04942800
    @l04942841: MOV EDX, [ESP+$20]
    @l04942845: POP EDI
    @l04942846: POP ESI
    @l04942847: MOV [EDX], ECX
    @l04942849: MOV [EDX+$4], EAX
    @l0494284C: POP EBX
    @l0494284D: ADD ESP, $10
    @l04942850: RETN
    end;
    end;


    ”Decryption keys”


    NPK structure was described here
    Regards to Genz, who helps with reversing.
    © Dwar & Genz
    Feel free using our knowledge and guides, but please,
    keep linkbacks to the original article
    Please, post your questions on forum, not by PM or mail

    I spend my time, so please pay a little bit of your time to keep world in equilibrium

  2. #2
    klumpur
    klumpur is offline
    Guest
    Join Date
    2010 Aug
    Posts
    3
    Thanks Thanks Given 
    0
    Thanks Thanks Received 
    0
    Thanked in
    0 Posts
    Rep Power
    0

    Re: [Guide] Reversing SoulMaster NPK encryption algorithm

    Hey.. Thanks alot.. Btw, what encryption software do I need for .npk files with those keys..?

  3. #3
    Dwar
    Dwar is offline
    Veteran Dwar's Avatar
    Join Date
    2010 Mar
    Posts
    2,222
    Thanks Thanks Given 
    211
    Thanks Thanks Received 
    2,230
    Thanked in
    292 Posts
    Rep Power
    10

    Re: [Guide] Reversing SoulMaster NPK encryption algorithm

    klumpur
    encryption software ... the best one is "brain+Delphi/C++", I mean that there are no standalone "encryption software" etc., you must make your own
    Please, post your questions on forum, not by PM or mail

    I spend my time, so please pay a little bit of your time to keep world in equilibrium

  4. #4
    Kraze
    Kraze is offline
    New member
    Join Date
    2010 Aug
    Posts
    20
    Thanks Thanks Given 
    4
    Thanks Thanks Received 
    1
    Thanked in
    1 Post
    Rep Power
    0

    Re: [Guide] Reversing SoulMaster NPK encryption algorithm

    Thanks for posting this! =]
    Im now on my way to looking on how to create a repacker.

  5. #5
    falc0n
    falc0n is offline
    Member-in-training
    Join Date
    2010 Aug
    Posts
    64
    Thanks Thanks Given 
    0
    Thanks Thanks Received 
    0
    Thanked in
    0 Posts
    Rep Power
    0

    Re: [Guide] Reversing SoulMaster NPK encryption algorithm

    Quote Originally Posted by Kraze
    Thanks for posting this! =]
    Im now on my way to looking on how to create a repacker.

    You don't need one.

    Btw I'm not trying to sound ungrateful, but the file's aren't fully unpacked. Some dungeon and instance loading scripts or related data isn't fully unpacked, so when you enter a dungeon it crashes XD

  6. #6
    Dwar
    Dwar is offline
    Veteran Dwar's Avatar
    Join Date
    2010 Mar
    Posts
    2,222
    Thanks Thanks Given 
    211
    Thanks Thanks Received 
    2,230
    Thanked in
    292 Posts
    Rep Power
    10

    Re: [Guide] Reversing SoulMaster NPK encryption algorithm

    isn't fully unpacked
    What exactly?
    Please, post your questions on forum, not by PM or mail

    I spend my time, so please pay a little bit of your time to keep world in equilibrium

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •