Skip to content

Instantly share code, notes, and snippets.

@jeedee
Created May 10, 2010 14:10
Show Gist options
  • Save jeedee/396075 to your computer and use it in GitHub Desktop.
Save jeedee/396075 to your computer and use it in GitHub Desktop.
Nexus packet decryptor/encryptor function by VIPERZOO.
(new version using 32bit xoring for faster operation)
IMPORTANT IMPORTANT! - If you are using dynamically generated buffers to hold your packet data for encryption/unencryption, the size of the buffer MUST be AT LEAST the smallest multiple of 4 above the size of your packet plus 1. For example, say you have a packet that is in total 25 bytes large (that is including the AA and size header), you must put it in a buffer that is a MINIMUM of 29 bytes large (28 is smallest multiple of 4 over 25, add 1 = 29) to avoid buffer access page faults. Also, remember the true size of the packet (or just check it from the header) when working with the data after so you don't pull any extra garbage data from having to pad the buffer with extra bytes.
Included is the DLL and the source code for the nexus packet decryption/encryption routine.
Usage of it is very simple, include the library file in your project and set up a definition of the "crypt_packet" function, it takes a single DWORD as an argument.
Also you can just use the standard LoadLibrary/GetProcAddress method to execute the function "crypt_packet".
crypt_packet PROTO pPacketBuff:DWORD
The single argument to crypt_packet is a pointer to a buffer containing a COMPLETE nexus packet (either encrypted or decrypted, it will change its status to the other once it completes.) The only error checking it does is to check the first byte of the buffer to be AA. If that first byte is not AA, it returns with a value of 1 (indication an error.) Otherwise the function will work normally, returning a value of 0 upon completion.
Usage:
BufferVariable def "AA 00 05 02 ..." (this is just an example packet, pretend the packet is encrypted)
PointerToBufferVariable DOUBLE WORD
Load PointerToBufferVariable with a pointer to BufferVariable however your programming language of choice does it.
if crypt_packet(PointerToBufferVariable) == 1 then
there was an error!;
else
no error, and now BufferVariable contains an unencrypted packet
endif
www.activateskynet.com/nexusbb
;--------------------------------------------------------------------------------
;Nexus packet decryption and encryption algorithm by VIPERZOO.
;--------------------------------------------------------------------------------
.486
.model flat,stdcall
option casemap:none
.data
align 4
encKey db 'NexonInc.NexonInc.NexonInc.NexonInc.',0
align 4
xorkey dd 0
.code
align 4
DllEntry proc hInstDLL:DWORD, reason:DWORD, reserved1:DWORD
mov eax,1 ;our entry, just return true
ret
DllEntry Endp
align 4
crypt_packet PROC pPacketBuff:DWORD
push esi ;preserve regs windows standard preserves
push edi
mov eax,pPacketBuff
mov dl,[eax]
cmp dl,0AAh ;check for starting AA, return 1 if not
jz @F
pop edi
pop esi
mov eax,1
ret
@@:
inc eax
xor ecx,ecx ;get packet size, fix endian form
mov cx,[eax]
rol cx,8
add eax,3
mov bl,[eax] ;get first encryption key, extend throughout ebx for 32-bit xor
mov bh,bl
shl ebx,16
mov bl,[eax]
mov bh,bl
inc eax
sub ecx,2
mov esi,eax ;use esi as our buffer pointer, eax for data
xor edx,edx
lea edi,encKey
xor eax,eax
mov xorkey,edx
push eax ;eax will also play a role as our "9-byte" tracker through
@@: ;stack swapping
mov eax,[esi] ;also, all conditionals inside the main loop are majority
xor eax,ebx ;fall through loops to save many cycles. Sacrificing readability
xor eax,edx ;for speed.
push edx
mov edx,[edi] ;do all 3 xors within one loop, yay for cycle saving
xor eax,edx
mov [esi],eax
pop edx
add edi,4
sub ecx,4 ;fix our pointers and byte left counter
add esi,4
mov al,[edi]
cmp al,0 ;check to see if our NexonInc. encryption key needs to be looped
je @_01 ;to the start (look for 0 terminator)
@_011:
pop eax
inc eax
cmp eax,2 ;check to see if we've done 8 bytes on current key
je @_02
@_022:
cmp ecx,0 ;check to see if we've done at least all the bytes in packet
jle @_03
push eax
jmp @B ;loop again since we aren't done
@_01:
lea edi,encKey ;yes, our NexonInc. key needs to be looped again
jmp @_011
@_02:
mov al,[esi] ;we've done 8 bytes, fix 9th byte and prepare for next 8
xor al,bl
xor al,dl
mov dl,[edi]
xor al,dl
mov [esi],al
mov edx,xorkey
inc esi
inc edi
dec ecx
inc dl
inc dh
rol edx,16
inc dl
inc dh
mov xorkey,edx
cmp edx,ebx
je @_04 ;check to see if our new key is same as packet key, if so we don't
@_044: ;want to double xor it, so we make sure we xor with nothing
mov al,[edi]
cmp al,0
je @_05 ;check for end of NexonInc. key since we modified the pntr since last
@_055: ;check
xor eax,eax
jmp @_022 ;set counter back to 0 and get back in business
@_04:
xor edx,edx ;fix our key so we don't double xor
jmp @_044
@_05:
lea edi,encKey ;second fix NexonInc. pntr outer loop
jmp @_055
@_03:
pop edi ;exit the loop since we are done, return 0 for success
pop esi
mov eax,0
ret
crypt_packet endp
End DllEntry
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment