WPN / WinMX File Hashing - Technical Description




The file-hashing system utilised by WinMX is a proprietary system relying more for security on obscurity than any serious technical blocks to reversal, the hashing algorithm itself is one designed for speed, using something more heavyweight on a low end PC running windows 98 would demonstrate the reasoning behind this choice of method.

This technical guide I hope will demonstrate the process of hashing a file and using the result within the protocol.
Lets begin by looking at firstly how a file hash is constructed from a file.

This diagram represents the basic chunk (16 bits) and process algorithm, you will notice the steps value is nearly always 5 (unless there are less than 5 steps remaining! ) and the hash subroutine is a simple bit shift and XOR (a logical operation) the values in each step.



The weakness of this system is that as it uses a step system instead of including all the files digits its possible to manufacture a file that will look like the original but the first 4 sections of each step could be completely different and the hash could still be made to look identical, this then is a trade-off between hash processing time and the time required to get the user and their library active in as short a time as possible and should be accepted as so.
A possible upgrade to the current system would be to of course use a more secure hashing algorithm, this its a possibility that's become more promising as processor speeds increase and library generation times become less daunting,  but this brings with it problems such as current client compatibility and maybe even require a bit of reading up on import /export of cryptographic code regulations if something very secure was used.

Here is the basic code as taken from the Mxsock.dll implementation found here


const BOOL GetFileHash(LPCTSTR lpszFileName, DWORD *pHash, DWORD *pFileLen)
{
   FILE *in;
   DWORD len;
   DWORD blockskip;
   if((in = fopen(lpszFileName, "rb")) == NULL) return FALSE;
   BYTE buf[0x20000];
   fseek(in, 0 , SEEK_END);
   *pFileLen = ftell(in);
   fseek(in, 0, SEEK_SET);
   blockskip = *pFileLen / 0x20000 / 10;
   if(blockskip < 5) blockskip = 5;
   pHash[0] = pHash[1] = pHash[2] = pHash[3] = 0;
   len = fread(buf, 1, 0x20000, in);
   while(1)
   {
        MXHashSub(buf, len, (BYTE *)pHash);
        if(len < 0x20000) break;
        fseek(in, 0x20000 * (blockskip - 1), SEEK_CUR);
        len = fread(buf, 1, 0x20000, in);
   }
   fclose(in);
   return TRUE;
}



This is the actual bit swapping subroutine in code form.

inline void MXHashSub(BYTE *pBuf, const DWORD dwLen, BYTE *pHash)
{
   BYTE b, n;
   BYTE *bp;
   if(dwLen <= 16) return;
   b = 0xC9;
   n = 0;
   bp = pBuf;
   while(bp < pBuf + dwLen - 16)
   {
        pHash[0] += bp[0];
        pHash[1] += bp[1];
        pHash[2] += bp[2];
        pHash[3] += bp[3];
        pHash[4] += bp[4];
        pHash[5] += bp[5];
        pHash[6] += bp[6];
        pHash[7] += bp[7];
        pHash[8] += bp[8];
        pHash[9] += bp[9];
        pHash[10] += bp[10];
        pHash[11] += bp[11];
        pHash[12] += bp[12];
        pHash[13] += bp[13];
        pHash[14] += bp[14];
        pHash[15] += bp[15];
        pHash[0] ^= b;
        pHash[1] ^= pHash[0];
        pHash[2] ^= pHash[1];
        pHash[3] ^= pHash[2];
        pHash[4] ^= pHash[3];
        pHash[5] ^= pHash[4];
        pHash[6] ^= pHash[5];
        pHash[7] ^= pHash[6];
        pHash[8] ^= pHash[7];
        pHash[9] ^= pHash[8];
        pHash[10] ^= pHash[9];
        pHash[11] ^= pHash[10];
        pHash[12] ^= pHash[11];
        pHash[13] ^= pHash[12];
        pHash[14] ^= pHash[13];
        pHash[15] ^= pHash[14];
        b = n + pHash[15];
        b = (b << 1) + ( b >> 7);
        bp += 0x10;
        n++;
   }
}


Note : The hash that is placed in the search box is not identical to the one a WPN client sends across the network, this then is an operation undertaken in the client itself and has nothing to do with the protocol.

This diagram shows the process of conversion.




My thanks go to Nushi@http://2sen.dip.jp/2sene/ for the use of his code in this guide.

I hope you have enjoyed this guide and discovered something new about the client thats been powering file sharers since 2000/2001.

©2005-2017 WinMXWorld.com. All rights reserved. Page last updated Mon Dec 15 2008