Важная информация

User Tag List

Страница 1 из 2 12 ПоследняяПоследняя
Показано с 1 по 10 из 11

Тема: Помогите HRUST21.CPP превратить в DLL

  1. #1
    Guru Аватар для newart
    Регистрация
    19.01.2005
    Адрес
    Санкт-Петербург
    Сообщений
    10,947
    Благодарностей: 1520
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    Red face Помогите 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.

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2
    Guru Аватар для rasmer
    Регистрация
    20.01.2005
    Адрес
    Саранск
    Сообщений
    2,172
    Благодарностей: 140
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    А на спеке распаковать никак? Или скомпилить плугин к фаре?
    Мои интры: [Kukarachess][Super boot rmx][tRUSHE MOSAIc][BLAZE]
    Мои игры: [Overload][Removal]

    Список игр для ZX-Spectrum: [2015] [2014]

  4. #3
    Vitamin C++ Аватар для Vitamin
    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,031
    Благодарностей: 1426
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

  5. #4
    Guru Аватар для newart
    Регистрация
    19.01.2005
    Адрес
    Санкт-Петербург
    Сообщений
    10,947
    Благодарностей: 1520
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Vitamin Посмотреть сообщение
    Почему dll? Как планируется использовать? Может лучше CLI-приложение?
    Потому что так удобно. Что такое CLI не знаю.

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

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

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

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



    было:

    Код HTML:
    
    
    #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:
    #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'а)
    Вложения Вложения
    Последний раз редактировалось newart; 27.05.2009 в 06:22.

  6. #5
    Vitamin C++ Аватар для Vitamin
    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,031
    Благодарностей: 1426
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от newart Посмотреть сообщение
    Потому что так удобно. Что такое CLI не знаю.
    Command-Line interface.

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

  7. #6
    Guru Аватар для newart
    Регистрация
    19.01.2005
    Адрес
    Санкт-Петербург
    Сообщений
    10,947
    Благодарностей: 1520
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Vitamin Посмотреть сообщение
    Из какой программы используется либа?
    Из рипалки , которую пишу на PureBasic.

    Добавлено через 2 минуты
    DLL в любом случае мне кажется более универсальным вариантом.
    Написать обертку для комндной строки дело одной минуты (если кому надо будет).
    Последний раз редактировалось newart; 27.05.2009 в 06:27. Причина: Добавлено сообщение

  8. #7
    Activist
    Регистрация
    15.01.2005
    Адрес
    TYU-MEN
    Сообщений
    214
    Благодарностей: 46
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

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

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

  9. #8
    --- Аватар для Shadow Maker
    Регистрация
    01.03.2005
    Адрес
    Саранск
    Сообщений
    5,213
    Благодарностей: 869
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Ему ж не это надо, он предлагает на базе плагина от фара слепить ему длл-ку для его рипалки.
    Свирепый агрессивно-депрессивный мордовец!
    Не уверен - не напрягай!

    Не сдавайся. Дыши?

    Мордовия - Республика звука

  10. #9
    Activist
    Регистрация
    15.01.2005
    Адрес
    TYU-MEN
    Сообщений
    214
    Благодарностей: 46
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Shadow Maker Посмотреть сообщение
    Ему ж не это надо, он предлагает на базе плагина от фара слепить ему длл-ку для его рипалки.
    Началось...

  11. #10
    Guru Аватар для newart
    Регистрация
    19.01.2005
    Адрес
    Санкт-Петербург
    Сообщений
    10,947
    Благодарностей: 1520
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Shadow Maker Посмотреть сообщение
    Ему ж не это надо, он предлагает на базе плагина от фара слепить ему длл-ку для его рипалки.
    Ну и не только для нее.
    Ничто не мешает далее использовать эту DLL в Тотале или любом другом софте.

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

Страница 1 из 2 12 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Ответов: 68
    Последнее: 10.11.2011, 13:46

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •