QQXT (ueni.ueni)

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
Viserion
Posts: 63
Joined: Fri Sep 12, 2014 11:02 pm

QQXT (ueni.ueni)

Post by Viserion »

Hello guys,

ueni.ueni is a file encrypted with *.txt, *.lua and *.xml files (maybe in this version have other files or not).

Download: https://mega.co.nz/#!O4hl2T5Q!Fn5s2Pzxz ... c3kIZPMGBw

Someone can help me?

Thanks,
Good morning.
Viserion
Posts: 63
Joined: Fri Sep 12, 2014 11:02 pm

Re: QQXT (ueni.ueni)

Post by Viserion »

Here a link with PackUI: https://mega.co.nz/#!S84DSCQL!bcVBa2wnY ... IhBDqAPBzA

PS: This PackUI only works in old version.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: QQXT (ueni.ueni)

Post by aluigi »

Maybe they changed the key.
I used a simple encryption aes "\x07\xd4\x55\xc4\x0a\x1c\x31\xd9\xc7\x2b\xfe\x4a\x35\x4d\x5a\x58\xf8\xae\xa7\x73\x22\x5e\x6e\x0d\xaf\x14\x64\xc6\x90\x11\x69\xfe" and it failed.
Ekey
Posts: 1383
Joined: Sat Aug 09, 2014 2:34 pm

Re: QQXT (ueni.ueni)

Post by Ekey »

Viserion
Posts: 63
Joined: Fri Sep 12, 2014 11:02 pm

Re: QQXT (ueni.ueni)

Post by Viserion »

Sorry to disturb. But someone got any news?

In the client code, this function calls the ueni.ueni

Code: Select all

#define GET_SPLITNAME(STR, LEN)   buf = (byte*)malloc(LEN+1);MEMSET(buf, 0, LEN+1);MEMCPY( buf, decipher.first(), LEN );STR=(char*)buf;decipher.erase(0, LEN + 1);free(buf);
void QGameEngine::parseUISource()
{
   GUARD(QGameEngine::parseUISource);
   
   QArray<byte> decipher;
   if (!QSystem::loadBinFile("UENI.ueni", decipher))
   {
      WARNF("Failed to load ui pack file \"%s\" !", "UENI.ueni");
      return;
   }

   Rijndael_Imp* encryption = new Rijndael_Imp();
   
   unsigned char key_buff[] = KEY_UI;
   encryption->setkey(key_buff, 32);
   
   encryption->decode(decipher.first(), decipher.size(), 1, 1);
   //QString    packUIContent = (char*)decipher.first();

   // parse file
   byte splitSign = '$';
   byte* buf;
   while (decipher.size())
   {
      QString fname;
      QArray<byte> fcontent;
      QString fileLeng;
      
      // find fname
      int id = decipher.find( splitSign );
      if (id == -1)
      {
         break;
      }
      else if( id == 0 )
      {
         decipher.erase(0);
         id = decipher.find( splitSign );
      }
      GET_SPLITNAME(fname, id);
      LOGF(fname);
      // delete fname and split

      //If it is compiled LUA file, change the name
      bool flag = true;
      if( fname.mid(fname.len() - 2, fname.len())==".l" )
      {
         flag = false;
      
         fname = fname.mid(0, fname.len()-2) + ".lua";
      }
      //Find the length of the separator
      id = decipher.find(splitSign);
      GET_SPLITNAME(fileLeng, id);
      //Find the length of the contents of the corresponding
      int leng = CStr::atoi(fileLeng);
      fcontent.resize(leng+1);
      fcontent[leng] = 0;
      MEMCPY( fcontent.first(), decipher.first(), leng );

      if( !flag )
         LOGF((char*)fcontent.first());
      decipher.erase(0, leng);

      QGUIFileData fileData;
      fileData.name = fname;
      fileData.content = fcontent;
      fileData.c_size = leng;
      QSystem::saveBinFile( fileData.name, fileData.content ); //GG
      QGUIFrame::uiFiles.push(fileData);

   }

   UNGUARD;
}


loadBinFile

Code: Select all

bool QSystem::loadBinFile( const char* filename, QArray<byte>& file )
{
   GUARD(QSystem::loadBinFile);
   QArchive* reader = createReader( filename );
   if( !reader )
      return false;
   int len =  reader->size();
   file.resize(len);
   if( len )
      reader->serialize( (byte*)(&(file[0])), len );
   DELETE reader;
   return true;
   UNGUARD;
}


createReader

Code: Select all

QArchive* QSystem::createReader( const char* filename, bool useCache, bool noFail )
{
   GUARD(QSystem::createReader);
   DWORD  Access    = GENERIC_READ;
   DWORD  WinFlags  = FILE_SHARE_READ;
   DWORD  Create    = OPEN_EXISTING;
   HANDLE Handle    = CreateFile( filename, Access, WinFlags, NULL, Create, FILE_ATTRIBUTE_NORMAL, NULL );
   if( Handle==INVALID_HANDLE_VALUE )
   {
      if( noFail )
         ERRF( "Failed to read file: %s", filename );
      return NULL;
   }
   curLoadFile = filename;
   return NEW QArchiveWinReader( Handle, GetFileSize(Handle,NULL), useCache );
   UNGUARD;
}



Code: Select all

/******************************************************************************
      FILE SYSTEM WRAPPER.
******************************************************************************/
// TODO: Implement cached file archive!!!!!!
/**
 * @class QArchiveWinReader
 *
 * @brief Windows file reader.
 */
#define FILE_BUF_SIZE      65536

//WZ
class QArchiveWinReader : public QArchive
{
public:
    QArchiveWinReader( HANDLE handle, int size, bool buf = 1 )
        :QArchive(true),
        _handle(handle),
        _size(size)
    {
        GUARD(QArchiveWinReader);
        ASSERT( handle );

        //If use buffered file, allocate memory for the buffer.
        if(buf)
        {
            _buf = (byte*)ALLOC(FILE_BUF_SIZE);
            _bufDataPtr =  _buf;
        }
        else
        {
            _buf = _bufDataPtr = NULL;
        }

        _bufFreeSize = 0;

        UNGUARD;
    }
    virtual ~QArchiveWinReader()
    {
        GUARD(~QArchiveWinReader);
        if( _buf ) FREE(_buf);
        if( _handle )
            CloseHandle( _handle );
        _handle = NULL;
        UNGUARD;
    }

    //
    // QArchive interface implementations.
    //
    void serialize( byte* readBuf, int len )
    {
        GUARD(QArchiveWinReader::serialize);
        ASSERT( _pos + len <= _size );
        if( len == 0 ) return;

        //Use buffer to optimize read.
        if(_buf)
        {
            if(len < _bufFreeSize)
            {
                MEMCPY(readBuf, _bufDataPtr,len);
                _bufFreeSize -= len;
                _bufDataPtr += len;
                _pos += len;
            }
            else
            {
                MEMCPY(readBuf, _bufDataPtr,_bufFreeSize);
                //Direct read data to readBuf.
                DWORD realRead;
                ReadFile( _handle, readBuf + _bufFreeSize, (DWORD)(len - _bufFreeSize), &realRead, NULL );
                if(realRead != len - _bufFreeSize)
            {
               ERRF("Error or invalid operation happened when try to read file %s", QSystem::getCurLoadFile());
                    ERRF("EOS error is : %s", QSystem::getSysError());
                }
                else
                {
                    _pos += _bufFreeSize + realRead;
                }
                //Fill the file buffer with data.
                ReadFile( _handle, _buf, FILE_BUF_SIZE, (DWORD*)&_bufFreeSize, NULL );
                _bufDataPtr = _buf;
            }
        }
        else
        {
            //None buffer reading.
            DWORD realRead;
            ReadFile(_handle, readBuf, len, &realRead, NULL);
            if(realRead != len)
         {
            ERRF("Error or invalid operation happened when try to read file %s", QSystem::getCurLoadFile());
            ERRF("EOS error is : %s", QSystem::getSysError());
            }

            _pos += len;
        }

        UNGUARD;
    }
    int size(){   return _size;}
    int tell()   { return _pos; }
    void seek( int newPos )
    {
        GUARD(QArchiveWinReader::seek);
        ASSERT(newPos>=0);
        ASSERT(newPos<=_size);

        //Move file pointer.
        if(SetFilePointer(_handle, newPos, 0, FILE_BEGIN) == 0xffffffff)
        {
            ERRF("Seek failed,OS error is %s", QSystem::getSysError());
        }
        else
        {
            //If succeed to set new file pointer.
            if(_buf)
            {
                //Read data form new position.
                ReadFile( _handle, _buf, FILE_BUF_SIZE, (DWORD*)&_bufFreeSize, NULL );
                if((DWORD)_bufFreeSize != FILE_BUF_SIZE && newPos + _bufFreeSize != _size)
            {
               ERRF("Error or invalid operation happened when try to read file %s", QSystem::getCurLoadFile());
               ERRF("EOS error is : %s", QSystem::getSysError());
                    ASSERT((DWORD)_bufFreeSize != FILE_BUF_SIZE);
                }
                _bufDataPtr = _buf;
            }

            _pos = newPos;
        }

        UNGUARD;
    }

protected:
    HANDLE      _handle;   // Handle of the file.

    byte*      _buf;      // precache buffer.
    byte*      _bufDataPtr;
    int         _bufFreeSize;

    int         _size;      // File size.
};