Speccy - наш выбор!

Speccy - наш выбор! (http://zx-pk.ru/index.php)
-   Программирование (http://zx-pk.ru/forumdisplay.php?f=14)
-   -   Помогите HRUST21.CPP превратить в DLL (http://zx-pk.ru/showthread.php?t=10276)

newart 27th May 2009 00:09

Помогите HRUST21.CPP превратить в DLL
 
Для дальнейшего развития zxpress.ru необходима DLL'ка до недавнего времени выручал Ander (одээлелев MSPACK, LZS, HRUST1, HRUM), но сейчас он похоже очень и на долго занят. :(

На форуме ведь есть С програмерры?
Переделки в общем то минимальные, тем более есть пример и полный пакет файлов из уже готовых распаковщиков (под Visual C++).

выглядет оно так (плагин к FAR'у)

Скрытый текст



#include <windows.h>
#include "..\\dtr.hpp"

BYTE *hr_d_output;
BYTE *hr_d_input;
BYTE hr_d_tagbyte;/*буфер для битов.*/
BYTE __index = 7;

BYTE hr_d_getbit(void)
{
BYTE bit[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };

__index = (__index + 1) % 8;
if(__index == 0) hr_d_tagbyte = *hr_d_input++;

return (hr_d_tagbyte & bit[__index]) == 0 ? 0 : 1;
}

WORD hr_d_getlen(void)
{
WORD tmp, result = 1;
do
{
tmp = (hr_d_getbit() << 1) + hr_d_getbit();
result += tmp;
} while(tmp == 0x03 && result != 0x10);

return(result);
}

WORD hr_d_getdist(void)
{
WORD result;volatile WORD tmp;

if(hr_d_getbit())
{
result = 0xff00 + *hr_d_input++;
}
else
{
result = 0xffff;
tmp = (hr_d_getbit() << 1) + hr_d_getbit() + 0xffff-3;

for(; tmp; tmp++) result = (result << 1) + hr_d_getbit() - 1;
if(result == 0xffff - 30) result = *hr_d_input++;
result = (result << 8) + *hr_d_input++;
}
return (result);
}

void dehrust(BYTE* source, BYTE* destination)
{
__index = 7;
WORD len;
short offs;

hr_d_input = source + 6;
hr_d_output = destination;

*hr_d_output++ = *hr_d_input++;

while(true)
{
if(!hr_d_getbit())
{
len = hr_d_getlen();
offs = 0xffff;

if(len == 4)
{
if(hr_d_getbit())
{
len = *hr_d_input++;

if(len == 0)
break;
else
if(len < 16) len = (len << 8) + *hr_d_input++;

offs = hr_d_getdist();

for(; len; len--) *hr_d_output = *(hr_d_output++ + offs);
}
else
{
len = 0;
for(int i = 4; i; i--) len = (len << 1) + hr_d_getbit();
len += 6;
len <<= 1;
for(; len; len--) *hr_d_output++ = *hr_d_input++;
}
}
else
{
if(len > 4) len--;
if(len == 1)
{
for(int i = 3; i; i--) offs = (offs << 1) + hr_d_getbit();
}
else
{
if(len == 2)
offs = 0xff00 + *hr_d_input++;
else
offs = hr_d_getdist();
}
for(; len; len--) *hr_d_output = *(hr_d_output++ + offs);
}
}
else
{
*hr_d_output++ = *hr_d_input++;
}
}

for(int i = 0; i < 6; i++) *hr_d_output++ = source[i];
}

bool WINAPI extract(HoHdr *hdr, const BYTE *source, DWORD sourceSize, BYTE *unpackBuffer, DWORD *noUnpackedBytes, DWORD)
{
*noUnpackedBytes = *(WORD*)(source + 4);

if(source[3] & 0x80)
CopyMemory(unpackBuffer, source + 8, *noUnpackedBytes);
else
{
dehrust((BYTE*)source + 8, unpackBuffer);

#define ACE_notSUPPORT
#ifdef ACE_SUPPORT
// ACE detector
int i;
WORD len = hdr->length;
bool ace = true;
DWORD extraLen = sourceSize - len;
if(extraLen >= 14) extraLen = 14;
for(i = 0; i < extraLen; ++i)
if(source[i] != source[len+i])
{
ace = false;
break;
}

WORD maxLen = 128;
WORD lineLen = 0;
for(i = 0; i < *noUnpackedBytes && ace ; ++i)
{
if(unpackBuffer[i] == 0)
{
// sprites?
if((*noUnpackedBytes-i-1)%9*32 != 0)
{
ace = false;
break;
}
*noUnpackedBytes = i; // let's crop sprites
break;
}
else
{
if(lineLen > maxLen)
{
ace = false;
break;
}
++lineLen;
if(unpackBuffer[i] == 0x0d) lineLen = 0;
}
}
if(ace)
{
for(i = 0; i < *noUnpackedBytes; ++i)
if((unpackBuffer[i] > 0 && unpackBuffer[i] < 9) || (unpackBuffer[i] > 13 && unpackBuffer[i] < 21)) unpackBuffer[i] = ' ';
}
// END of ACE detector
#endif
}

return true;
}

bool WINAPI detect(DetectorResult &result, const char*, const HoHdr*, const BYTE *data, int file_size)
{
if(data[0] != 'h' || data[1] != 'r' || data[2] != '2') return false;

WORD size = *(WORD*)(data + 4);
WORD packed_size = *(WORD*)(data + 6);

if(packed_size > size || packed_size > file_size) return false;

result.action = do_extract;
lstrcpy(result.title, "[hrust 2.1]");

return true;
}


[свернуть]


На самом деле есть еще PCD, TRUSH, CC, DSQ, ESV, но большинство интересных статей запаковано именно HRUST21.

rasmer 27th May 2009 00:11

А на спеке распаковать никак? Или скомпилить плугин к фаре?

Vitamin 27th May 2009 01:00

Почему dll? Как планируется использовать? Может лучше CLI-приложение?

newart 27th May 2009 09:02

1 Attachment(s)
Quote:

Originally Posted by Vitamin (Post 201683)
Почему dll? Как планируется использовать? Может лучше CLI-приложение?

Потому что так удобно. Что такое CLI не знаю.

Сейчас глянул, все 4 распаковщика уже обьеденены в одну DLL.

Либа используется для поиска и распаковки архивов.
Есть три функции: detect, depack и freemem

HRUST1 что было и что получилось:

Скрытый текст



было:

HTML Code:




#include <windows.h>
#include "..\\dtr.hpp"

class BBStream
{
private:
        BYTE* base;
        BYTE* p;
        int  idx;
        int  len;
        bool  eof;
        WORD  bits;
public:
        BBStream(BYTE* from, int blockSize)
        {
                base = p = from;

                len = blockSize;
                idx = 0;
                eof = false;

                bits  = getByte();
                bits += 256*getByte();
        }

        BYTE getByte(void)
        {
                if(p - base == len) { eof = true; return 0; }
                return *p++;
        }

        BYTE getBit()
        {
                WORD mask[]  = { 0x8000, 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };

                BYTE bit = (bits & mask[idx]) ? 1 : 0;
                if(idx == 15)
                {
                        bits  = getByte();
                        bits += 256*getByte();
                }

                idx = (idx + 1) % 16;
                return bit;
        }

        BYTE getBits(int n)
        {
                BYTE r = 0;
                do { r = 2*r + getBit(); } while(--n);
                return r;
        }

        bool error(void) { return eof; }
};

bool WINAPI extract(HoHdr *hdr, const BYTE *source, DWORD, BYTE *unpackBuffer, DWORD *noUnpackedBytes, DWORD)
{
        BYTE *from = (BYTE*)source;
        BYTE *to  = unpackBuffer;

        if(source[0] != 'H' || source[1] != 'R')
                from += 0x103;

        BBStream s(from + 12, from[4] + 256*from[5]);

        *to++ = s.getByte();

        BYTE noBits = 2;
        BYTE mask[] = { 0, 0, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0 };

        while(!s.error())
        {
                while(s.getBit()) *to++ = s.getByte();

                WORD len = 0;
                BYTE bb  = 0;
                do
                {
                        bb = s.getBits(2);
                        len += bb;
                } while(bb == 0x03 && len != 0x0f);

                short offset = 0;

                if(len == 0)
                {
                        offset = 0xfff8 + s.getBits(3);
                        *to++ = to[offset];
                        continue;
                }

                if(len == 1)
                {
                        BYTE code = s.getBits(2);

                        if(code == 2)
                        {
                                BYTE b = s.getByte();
                                if(b >= 0xe0)
                                {
                                        b <<= 1; ++b; // rlca
                                        b ^= 2;      // xor c

                                        if(b == 0xff) { ++noBits; continue; }

                                        offset = 0xff00 + b - 0x0f;

                                        *to++ = to[offset];
                                        *to++ = s.getByte();
                                        *to++ = to[offset];
                                        continue;
                                }
                                offset = 0xff00 + b;
                        }

                        if(code == 0 || code == 1)
                        {
                                offset = s.getByte();
                                offset += 256*(code ? 0xfe : 0xfd);
                        }
                        if(code == 3) offset = 0xffe0 + s.getBits(5);

                        for(BYTE i = 0; i < 2; ++i)
                                *to++ = to[offset];
                        continue;
                }

                if(len == 3)
                {
                        if(s.getBit())
                        {
                                offset = 0xfff0 + s.getBits(4);
                                *to++ = to[offset];
                                *to++ = s.getByte();
                                *to++ = to[offset];
                                continue;
                        }

                        if(s.getBit())
                        {
                                BYTE noBytes = 6 + s.getBits(4);
                                for(BYTE i = 0; i < 2*noBytes; ++i)
                                        *to++ = s.getByte();
                                continue;
                        }

                        len = s.getBits(7);
                        if(len == 0x0f) break; // EOF
                        if(len <  0x0f) len = 256*len + s.getByte();
                }

                if(len == 2) ++len;

                BYTE code = s.getBits(2);

                if(code == 1)
                {
                        BYTE b = s.getByte();

                        if(b >
= 0xe0)
                        {
                                if(len > 3) return false;

                                b <<= 1; ++b; // rlca
                                b ^= 3;      // xor c

                                offset = 0xff00 + b - 0x0f;

                                *to++ = to[offset];
                                *to++ = s.getByte();
                                *to++ = to[offset];
                                continue;
                        }
                        offset = 0xff00 + b;
                }

                if(code == 0) offset = 0xfe00 + s.getByte();
                if(code == 2) offset = 0xffe0 + s.getBits(5);
                if(code == 3)
                {
                        offset  = 256*(mask[noBits] + s.getBits(noBits));
                        offset += s.getByte();
                }

                for(WORD i = 0; i < len; ++i)
                        *to++ = to[offset];
        }

        for(int i = 0; i < 6; ++i)
                *to++ = from[6+i];

        *noUnpackedBytes = to-unpackBuffer;

        return true;
}

bool WINAPI detect(DetectorResult &result, const char*, const HoHdr*, const BYTE *data, int file_size)
{
        WORD size;
        WORD packed_size;

        while(true)
        {
                if(data[0] == 'H' && data[1] == 'R')
                {
                        size        = *(WORD*)(data + 2);
                        packed_size = *(WORD*)(data + 4);

                        // check for HRiP
                        if(data[2] == 'i' && (data[2+5] == 0 || data[2+5] == 1))
                                return false;

                        break;
                }

                if(data[0x103] == 'H' && data[0x104] == 'R')
                {
                        size        = *(WORD*)(data + 0x105);
                        packed_size = *(WORD*)(data + 0x107);

                        break;
                }

                return false;
        }

        if(packed_size >
size || packed_size > file_size)
                return false;

        result.action = do_extract;
        lstrcpy(result.title, "[hrust 1.x]");

        return true;
}

стало:

HTML Code:

#include "stdafx.h"
#include "hrust1.h"
#include <vector>

class BBStream
{
private:
        BYTE* base;
        BYTE* p;
        int  idx;
        int  len;
        bool  eof;
        WORD  bits;
public:
        BBStream(BYTE* from, int blockSize)
        {
                base = p = from;

                len = blockSize;
                idx = 0;
                eof = false;

                bits  = getByte();
                bits += 256*getByte();
        }

        BYTE getByte(void)
        {
                if(p - base == len) { eof = true; return 0; }
                return *p++;
        }

        BYTE getBit()
        {
                WORD mask[]  = { 0x8000, 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };

                BYTE bit = (bits & mask[idx]) ? 1 : 0;
                if(idx == 15)
                {
                        bits  = getByte();
                        bits += 256*getByte();
                }

                idx = (idx + 1) % 16;
                return bit;
        }

        BYTE getBits(int n)
        {
                BYTE r = 0;
                do { r = 2*r + getBit(); } while(--n);
                return r;
        }

        bool error(void) { return eof; }
};

extern "C" HRUST1_API void *hrust1_extract(const BYTE *source, DWORD *noUnpackedBytes)
{
        WORD packed_size;
        BYTE *from = (BYTE*)source;
        BYTE *unpackBuffer = 0;
        *noUnpackedBytes = 0;
        std::vector<BYTE> out;

        try
        {
                if(source[0] != 'H' || source[1] != 'R')
                        from += 0x103;

                BBStream s(from + 12, from[4] + 256*from[5]);

                out.push_back(s.getByte());

                BYTE noBits = 2;
                BYTE mask[] = { 0, 0, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0 };

                while(!s.error())
                {
                        while(s.getBit())
                        {
                                out.push_back(s.getByte());
                        }

                        WORD len = 0;
                        BYTE bb  = 0;
                        do
                        {
                                bb = s.getBits(2);
                                len += bb;
                        } while(bb == 0x03 && len != 0x0f);

                        short offset = 0;

                        if(len == 0)
                        {
                                offset = 0xfff8 + s.getBits(3);
                                out.push_back(out.at(out.size() + offset));
                                continue;
                        }

                        if(len == 1)
                        {
                                BYTE code = s.getBits(2);

                                if(code == 2)
                                {
                                        BYTE b = s.getByte();
                                        if(b >= 0xe0)
                                        {
                                                b <<= 1; ++b; // rlca
                                                b ^= 2;      // xor c

                                                if(b == 0xff) { ++noBits; continue; }

                                                offset = 0xff00 + b - 0x0f;

                                                out.push_back(out.at(out.size() + offset));
                                                out.push_back(s.getByte());
                                                out.push_back(out.at(out.size() + offset));
                                                continue;
                                        }
                                        offset = 0xff00 + b;
                                }

                                if(code == 0 || code == 1)
                                {
                                        offset = s.getByte();
                                        offset += 256*(code ? 0xfe : 0xfd);
                                }
                                if(code == 3) offset = 0xffe0 + s.getBits(5);

                                for(BYTE i = 0; i < 2; ++i)
                                        out.push_back(out.at(out.size() + offset));
                                continue;
                        }

                        if(len == 3)
                        {
                                if(s.getBit())
                                {
                                        offset = 0xfff0 + s.getBits(4);
                                        out.push_back(out.at(out.size() + offset));
                                        out.push_back(s.getByte());
                                        out.push_back(out.at(out.size() + offset));
                                        continue;
                                }

                                if(s.getBit())
                                {
                                        BYTE noBytes = 6 + s.getBits(4);
                                        for(BYTE i = 0; i < 2*noBytes; ++i)
                                                out.push_back(s.getByte());
                                        continue;
                                }

                                len = s.getBits(7);
                                if(len == 0x0f) break; // EOF
                                if(len <  0x0f) len = 256*len + s.getByte();
                        }

                        if(len == 2) ++len;

                        BYTE code = s.getBits(2);

                        if(code == 1)
                        {
                                BYTE b = s.getByte();

                                if(b >
= 0xe0)
                                {
                                        if(len > 3) return false;

                                        b <<= 1; ++b; // rlca
                                        b ^= 3;      // xor c

                                        offset = 0xff00 + b - 0x0f;

                                        out.push_back(out.at(out.size() + offset));
                                        out.push_back(s.getByte());
                                        out.push_back(out.at(out.size() + offset));
                                        continue;
                                }
                                offset = 0xff00 + b;
                        }

                        if(code == 0) offset = 0xfe00 + s.getByte();
                        if(code == 2) offset = 0xffe0 + s.getBits(5);
                        if(code == 3)
                        {
                                offset  = 256*(mask[noBits] + s.getBits(noBits));
                                offset += s.getByte();
                        }

                        for(WORD i = 0; i < len; ++i)
                                out.push_back(out.at(out.size() + offset));
                }

                for(int i = 0; i < 6; ++i)
                        out.push_back(from[6+i]);
        }
        catch(...)
        {
                return 0;
        }

        *noUnpackedBytes = out.size();
        unpackBuffer = (BYTE *)malloc(*noUnpackedBytes);
        std::vector<BYTE>
::pointer ptr = &out [0];
        memcpy(unpackBuffer, ptr, *noUnpackedBytes);
        return unpackBuffer;
}

extern "C" HRUST1_API int hrust1_detect(const BYTE *data)
{
        WORD size;
        WORD packed_size;

        while(true)
        {
                if(data[0] == 'H' && data[1] == 'R')
                {
                        size        = *(WORD*)(data + 2);
                        packed_size = *(WORD*)(data + 4);

                        // check for HRiP
                        if(data[2] == 'i' && (data[2+5] == 0 || data[2+5] == 1))
                                return 0;

                        break;
                }

                return 0;
        }

        if(packed_size > size)
                return 0;

        return size;
}

[свернуть]


Архив проекта (чуток старый, тут нет Hrum'а)

Vitamin 27th May 2009 09:16

Quote:

Originally Posted by newart (Post 201705)
Потому что так удобно. Что такое CLI не знаю.

Command-Line interface.

Из какой программы используется либа? Где исходники оригинальной (с 4 депакерами) либы?

newart 27th May 2009 09:25

Quote:

Originally Posted by Vitamin (Post 201706)
Из какой программы используется либа?

Из рипалки , которую пишу на PureBasic.

Добавлено через 2 минуты
DLL в любом случае мне кажется более универсальным вариантом.
Написать обертку для комндной строки дело одной минуты (если кому надо будет).

Firestarter 27th May 2009 16:07

http://wincmd.ru/plugring/inhrust.html

Плагин к TotalCommander, позволяющий распаковывать HRIP-архивы и файлы упакованные спектрумовскими компрессорами Hrust 1 и Hrust 2.

Щас полетят помидоры что он не для FAR

Shadow Maker 27th May 2009 16:09

Ему ж не это надо, он предлагает на базе плагина от фара слепить ему длл-ку для его рипалки.

Firestarter 27th May 2009 16:18

Quote:

Originally Posted by Shadow Maker (Post 201750)
Ему ж не это надо, он предлагает на базе плагина от фара слепить ему длл-ку для его рипалки.

Началось...

newart 27th May 2009 16:23

1 Attachment(s)
Quote:

Originally Posted by Shadow Maker (Post 201750)
Ему ж не это надо, он предлагает на базе плагина от фара слепить ему длл-ку для его рипалки.

Ну и не только для нее.
Ничто не мешает далее использовать эту DLL в Тотале или любом другом софте.

Вот сорцы от XLOOK'а (не знаю можно ли их вот так публиковать? если нет, удалю)


All times are GMT +4. The time now is 21:01.

Powered by vBulletin® Version 3.8.3
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.