• XSS.stack #1 – первый литературный журнал от юзеров форума

нужен сорец decode из base64 на с++

karabas-barabas

(L1) cache
Пользователь
Регистрация
18.07.2006
Сообщения
650
Реакции
5
Нужен сорец декодирования данных из base64 на с++, желательно без использования хедеров типа stdio.h, string и namespace std , у кого есть буду благодарен

p.s. покопайтесь в своих тайничках :rolleyes:
 
Код:
const char Base64Table[64] =
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int __stdcall decode_b64(const unsigned char *buftodec, int bufsize,
  unsigned char *decbuf)
  {
  // выделяем память под временный буфер
  unsigned char *buftemp = new unsigned char [bufsize];
  memset(buftemp, '\0', bufsize);
  memcpy(buftemp, buftodec, bufsize);
  int i = 0;
  int cpos[5];
  unsigned char binbyte[4];
  while (i < bufsize)
    {
      if(buftemp[i] == '=')
        cpos[0] = 0;
      else
        cpos[0] = strchr(Base64Table, buftemp[i]) - Base64Table;
      if(buftemp[i + 1] == '=')
        cpos[1] = 0;
      else
        cpos[1] = strchr(Base64Table, buftemp[i + 1]) - Base64Table;
      if(buftemp[i + 2] == '=')
        cpos[2] = 0;
      else
        cpos[2] = strchr(Base64Table, buftemp[i + 2]) - Base64Table;
      if(buftemp[i + 3] == '=')
        cpos[3] = 0;
      else
        cpos[3] = strchr(Base64Table,buftemp[i + 3]) - Base64Table;
      binbyte[0] = ((cpos[0] << 2) | (cpos[1] >> 4));
      binbyte[1] = ((cpos[1] << 4) | (cpos[2] >> 2));
      binbyte[2] = (((cpos[2] & 0x03 )<< 6) | (cpos[3] & 0x3f));
      decbuf[i - (i / 4)] = binbyte[0];
      decbuf[i - (i / 4) + 1] = binbyte[1];
      decbuf[i - (i / 4) + 2] = binbyte[2];
      i += 4;
    }
    delete buftemp;
    return strlen(decbuf);
  }

такой подойдёт?
 
Код:
return strlen(decbuf)
подходит только для строк , а если мне нужно расшифровать .exe закодированный в base64 то вернет только 3 (MZh)...
еще есть какие-то варианты ?
 
Код:
 proc Base64Encode lpSrc,lpDst,dwstrlen
   push      esi edi edx ebx
       
   mov      esi,[lpSrc]
   mov      edi,[lpDst]
   mov      ebx,dword [dwstrlen]
   call      b64.encode
       
   pop      ebx edx edi esi
   ret      
  endp   
       
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; base64 encoder without dictionary by RT Fishel
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       
  b64:      
    .newline:  
   call      b64.store_crlf
       
    .encode:      ; ebp = length, esi -> src buffer, edi -> dst buffer
   push      (76 shr 2) + 1
   pop      edx
       
    .outer:    
   dec      edx
   je      b64.newline
   lodsd      
   dec      esi
   inc      ebx
   bswap      eax
   mov      ecx,4
       
    .inner:    
   rol      eax,6
   and      al,3Fh
   cmp      al,3Eh
   jb      b64.testchar
   shl      al,2
   sub      al,((3Eh shl 2)+'A'-'+') and 0FFh
       
    .testchar: 
   sub      al,4
   cmp      al,'0'
   jnl      b64.store
   add      al,'A'+4
   cmp      al,'Z'
   jbe      b64.store
   add      al,'a'-'Z'-1
       
    .store:    
   stosb      
   dec      ebx
   loopne     b64.inner
   jne      b64.outer
   mov      al,'='
   rep      stosb
   xor      al,al
   stosb      
   ret      
       
    .store_crlf: 
   mov      ax,0a0dh
   stosw      
       
   ret  

Асм вставку заюзай...либо можно и всего этого создать либу для С++
format MS COFF
 
так и знал что на асме напишешь)))
но мне от асма не легче, а только хуже :cry2:
к тому же у тебя Base64Encode, а мну нужно decode и потом dwstrlen говорит само за себя что этот алгоритм для строк , а мне нужно расшифровывать и двоичные данные с \x00 символом.
 
пришлось поднатужиться самому , в итоге родил класс для работы с base64
Код:
void* memstr (void *  hay, size_t  n, const char * needle)
{
	unsigned char *haystack = (unsigned char *)hay;
	size_t l = strlen(needle);
	while (n >= l) {
  if (0 == memcmp(haystack, needle, l))
  	return (void *)haystack;
  haystack++;
  n--;
	}
	return (void *)0;
}
static unsigned char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* This assumes that an unsigned char is exactly 8 bits. Not portable code! :-) */
static unsigned char index_64[128] = {
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,   62, 0xff, 0xff, 0xff,   63,
	52,   53,   54,   55,   56,   57,   58,   59,   60,   61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff,    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,
	15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
	41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51, 0xff, 0xff, 0xff, 0xff, 0xff
};
#define char64(c)  ((c > 127) ? 0xff : index_64[(c)])

class MyBASE64 
{
public:
	MyBASE64(PBYTE in_buff, int sz_buff);
	MyBASE64(char* f_name);
    ~MyBASE64();
	PBYTE base64EncodeInBuff();
	bool base64EncodeInFile(char* filename);
	PBYTE base64DecodeInBuff();
	bool base64DecodeInFile(char* filename);

	DWORD enclength, declength;
private:
	DWORD GetEncodeLength();
	DWORD GetDecodeLength();
	DWORD GetSizeFile();
	PBYTE CreateBufferFromFile(char* filename);
	PBYTE inbuf;
	int szbuff;
	char* fname;
	int szfile;


};
MyBASE64::~MyBASE64()
{
	MessageBoxA(0,"Good bay","bay",0);
}
MyBASE64::MyBASE64(PBYTE in_buff, int sz_buff)
{
	inbuf = in_buff; szbuff = sz_buff;
	enclength = GetEncodeLength();
	declength = GetDecodeLength();
};
PBYTE MyBASE64::CreateBufferFromFile(char* filename)
{
	HANDLE hf = CreateFile(filename,GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	if (hf == INVALID_HANDLE_VALUE) return 0;
	//int hf_size = GetFileSize(hf,0);
	PBYTE buff = new BYTE[szfile];
	DWORD rdn;
	ReadFile(hf,buff,szfile,&rdn,0);
	//*buff_size = hf_size;
	CloseHandle(hf);
	return buff;
}
MyBASE64::MyBASE64(char* f_name)
{
	fname = f_name; szfile = GetSizeFile();
	szbuff = szfile;
	inbuf = this->CreateBufferFromFile(f_name);
	enclength = GetEncodeLength();
	declength = GetDecodeLength();
	

};
bool MyBASE64::base64EncodeInFile(char *filename)
{

	PBYTE tempbuff = 0;
	tempbuff = base64EncodeInBuff();
	DWORD wrtn = 0;HANDLE hFile = 0;
	hFile = CreateFile(filename,GENERIC_READ|GENERIC_WRITE,0,0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,0);
	if ((hFile < (HANDLE)1)||!tempbuff) 
	{CloseHandle(hFile); delete tempbuff; return 0;}
	WriteFile(hFile,tempbuff, enclength, &wrtn,0);
	CloseHandle(hFile);
	delete tempbuff;
	return 1;

}
bool MyBASE64::base64DecodeInFile(char* filename)
{
	PBYTE tempbuff = 0;
	tempbuff = base64DecodeInBuff();
	DWORD wrtn = 0;HANDLE hFile = 0;
	hFile = CreateFile(filename,GENERIC_READ|GENERIC_WRITE,0,0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,0);
	if ((hFile < (HANDLE)1)||!tempbuff) 
	{CloseHandle(hFile); delete tempbuff; return 0;}
	WriteFile(hFile,tempbuff, declength, &wrtn,0);
	CloseHandle(hFile);
	delete tempbuff;
	return 1;
}
DWORD MyBASE64::GetSizeFile()
{
	DWORD siz = 0;HANDLE hFile = 0;
	hFile = CreateFile(fname,GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
	if (hFile > 0) siz = GetFileSize(hFile,0);
	CloseHandle(hFile);
	return siz;
}
DWORD MyBASE64::GetEncodeLength()
{
	DWORD res = 0;
	res = szbuff%3;
	if (res) res = (szbuff + (3-res))/3 *4;
	else res = szbuff/3*4;
	enclength = res;
	return res;
}

DWORD MyBASE64::GetDecodeLength()
{

	DWORD res =0;
	if (memstr((void*)inbuf,szbuff, "=="))
	{
  res = szbuff/4*3-2;
	}
	else if (memchr((const void*)inbuf, szbuff, '='))
	{
  res = szbuff/4*3-1;
	}
	else { res = szbuff/4*3; }
	declength = res;
	return res;
}
PBYTE MyBASE64::base64EncodeInBuff()
{
	int	i = 0, j = 0;
	int	pad;
	PBYTE output = new BYTE[enclength];
	//assert(output_length >= (input_length * 4 / 3));

	while (i < szbuff) {
  pad = 3 - (szbuff - i);
  if (pad == 2) {
  	output[j  ] = basis_64[inbuf[i]>>2];
  	output[j+1] = basis_64[(inbuf[i] & 0x03) << 4];
  	output[j+2] = '=';
  	output[j+3] = '=';
  } else if (pad == 1) {
  	output[j  ] = basis_64[inbuf[i]>>2];
  	output[j+1] = basis_64[((inbuf[i] & 0x03) << 4) | ((inbuf[i+1] & 0xf0) >> 4)];
  	output[j+2] = basis_64[(inbuf[i+1] & 0x0f) << 2];
  	output[j+3] = '=';
  } else{
  	output[j  ] = basis_64[inbuf[i]>>2];
  	output[j+1] = basis_64[((inbuf[i] & 0x03) << 4) | ((inbuf[i+1] & 0xf0) >> 4)];
  	output[j+2] = basis_64[((inbuf[i+1] & 0x0f) << 2) | ((inbuf[i+2] & 0xc0) >> 6)];
  	output[j+3] = basis_64[inbuf[i+2] & 0x3f];
  }
  i += 3;
  j += 4;
	}
	return output;
}
PBYTE MyBASE64::base64DecodeInBuff()
{
	int  i = 0, j = 0, pad;
	unsigned char	c[4];
	PBYTE output = new BYTE[declength+1];
	//  assert(output_length >= (input_length * 3 / 4));
	//  assert((input_length % 4) == 0);
	while ((i + 3) < szbuff) {
  pad  = 0;
  c[0] = char64(inbuf[i  ]); pad += (c[0] == 0xff);
  c[1] = char64(inbuf[i+1]); pad += (c[1] == 0xff);
  c[2] = char64(inbuf[i+2]); pad += (c[2] == 0xff);
  c[3] = char64(inbuf[i+3]); pad += (c[3] == 0xff);
  if (pad == 2) {
  	output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
  	output[j]   = (c[1] & 0x0f) << 4;
  } else if (pad == 1) {
  	output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
  	output[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2);
  	output[j]   = (c[2] & 0x03) << 6;
  } else {
  	output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
  	output[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2);
  	output[j++] = ((c[2] & 0x03) << 6) | (c[3] & 0x3f);
  }
  i += 4;
	}
	return output;
}
 
тоесть выражаясь нормальным языком на чистом С а не С++ =)
Немного не в ту степь батенька и вообще твой ответ провокационный с перспективой выяснения у кого пиписка длиннее у С или C++ или Delphi not dead.
Подразумевалось в С++ без CRT/RTL - что в конечном счете сказывается на размере троя
 
> while (i < bufsize) {
всё оно вам расшифрует, результат будет лежать в decbuf, которую можно будет сдампить в файл простым WriteFile(hFile,decbuf,out_bufsize,&written,0)
Код:
const char B64Tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int decode_b64(const unsigned char *buftodec, int bufsize, unsigned char *decbuf) {
   int i = 0,cpos[5],decmax;
   unsigned char binbyte[4],t, *buftemp =  (unsigned char*) alloc(bufsize);
   memset(buftemp, 0, bufsize);
   memcpy(buftemp, buftodec, bufsize);
   while (i < bufsize){
     for(t=0;t<=3;t++) cpos[t] = (buftemp[i + t] == '=')?0:strchr(B64Tbl, buftemp[i + t]) - B64Tbl;
     binbyte[0] = ((cpos[0] << 2) | (cpos[1] >> 4));
     binbyte[1] = ((cpos[1] << 4) | (cpos[2] >> 2));
     binbyte[2] = (((cpos[2] & 0x03 )<< 6) | (cpos[3] & 0x3f));
     for(t=0;t<3;t++) {
       int tmp=i - (i / 4) + t;
       if(tmp>decmax)decmax=tmp;
       decbuf[tmp] = binbyte[t];
     }
     i += 4;
   }
   free(buftemp);
   return decmax;
}

с примерным применением
Код:
  int binsz=FileRR("tmp.in",bin,50 kb);
  int boutsz=decode_b64(bin,binsz,bout);
  FileWW("tmp.out",bout,boutsz);
словом, "ну ты понел"
 
все уже реализовано, уменьшил хайд в моем посте.
Единственный минус, что собрал я в класс. Все-таки для меня теплее процедурное программирование. Позже выложу этот класс разбитый на процедуры
 
да, плюсы - это не дело.

вот лави тут тебе и С и С++, и при желании можно asm код рипнуть
Код:
//------------------------------------------------------------------------------
void* memstr (void *  hay, size_t  n, const char * needle)
{
	unsigned char *haystack = (unsigned char *)hay;
	size_t l = strlen(needle);
	while (n >= l) {
  if (0 == memcmp(haystack, needle, l))
  	return (void *)haystack;
  haystack++;
  n--;
	}
	return (void *)0;
}
void * memchr_ (
        const void * buf,
        int chr,
        size_t cnt
        )
{
	while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) {
  buf = (unsigned char *)buf + 1;
  cnt--;
	}

	return(cnt ? (void *)buf : NULL);
}
static unsigned char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* This assumes that an unsigned char is exactly 8 bits. Not portable code! :-) */
static unsigned char index_64[128] = {
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,   62, 0xff, 0xff, 0xff,   63,
	52,   53,   54,   55,   56,   57,   58,   59,   60,   61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff,    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,
	15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
	41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51, 0xff, 0xff, 0xff, 0xff, 0xff
};
#define char64(c)  ((c > 127) ? 0xff : index_64[(c)])

DWORD Base64EncodeLength(int buf_size)
{
	DWORD res = 0;
	res = buf_size%3;
	if (res) res = (buf_size + (3-res))/3 *4;
	else res = buf_size/3*4;
	return res;
}
void Base64EncodeInBuff(char* inbuf, int buf_size, char* output, int len_outbuf)
{
	int	i = 0, j = 0;
	int	pad;
	while (i < buf_size) {
  pad = 3 - (buf_size - i);
  if (pad == 2) {
  	output[j  ] = basis_64[inbuf[i]>>2];
  	output[j+1] = basis_64[(inbuf[i] & 0x03) << 4];
  	output[j+2] = '=';
  	output[j+3] = '=';
  } else if (pad == 1) {
  	output[j  ] = basis_64[inbuf[i]>>2];
  	output[j+1] = basis_64[((inbuf[i] & 0x03) << 4) | ((inbuf[i+1] & 0xf0) >> 4)];
  	output[j+2] = basis_64[(inbuf[i+1] & 0x0f) << 2];
  	output[j+3] = '=';
  } else{
  	output[j  ] = basis_64[inbuf[i]>>2];
  	output[j+1] = basis_64[((inbuf[i] & 0x03) << 4) | ((inbuf[i+1] & 0xf0) >> 4)];
  	output[j+2] = basis_64[((inbuf[i+1] & 0x0f) << 2) | ((inbuf[i+2] & 0xc0) >> 6)];
  	output[j+3] = basis_64[inbuf[i+2] & 0x3f];
  }
  i += 3;
  j += 4;
	}
}

DWORD Base64DecodeLength(char* inbuff)
{
	DWORD res =0; DWORD szbuff = lstrlen(inbuff);
	if (memstr((void*)inbuff,szbuff, "=="))
	{
  res = szbuff/4*3-2;
	}
	else if (memstr((void*)inbuff, szbuff, "="))
	{
  res = szbuff/4*3-1;
	}
	else { res = szbuff/4*3; }
	return res;
}
void Base64DecodeInBuff(char* inbuff, int len_inbuff, char* outbuff, int len_outbuff)
{
	int  i = 0, j = 0, pad;
	unsigned char	c[4];
	while ((i + 3) < len_inbuff) {
  pad  = 0;
  c[0] = char64(inbuff[i  ]); pad += (c[0] == 0xff);
  c[1] = char64(inbuff[i+1]); pad += (c[1] == 0xff);
  c[2] = char64(inbuff[i+2]); pad += (c[2] == 0xff);
  c[3] = char64(inbuff[i+3]); pad += (c[3] == 0xff);
  if (pad == 2) {
  	outbuff[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
  	outbuff[j]   = (c[1] & 0x0f) << 4;
  } else if (pad == 1) {
  	outbuff[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
  	outbuff[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2);
  	outbuff[j]   = (c[2] & 0x03) << 6;
  } else {
  	outbuff[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
  	outbuff[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2);
  	outbuff[j++] = ((c[2] & 0x03) << 6) | (c[3] & 0x3f);
  }
  i += 4;
	}
	
}
//----------------------------------------------------------------------------
 
Гы-гы, решил тоже свои 5 копеек нуба закинуть :)
Тоже такая когда-то трабла была, при этом я на свалке http://www.google.com/codesearch искал че-нить подходящее
Честно - пришел в ужаснах от этих академиков рожающих такой код, страшно даже смотреть на код не то, что там юзать
На васме есть исходники разных там "хеш и кеш"(в одном архиве), так вот я взял оттуда Base64Decode.asm и Base64Encode.asm
Ссылку правда уже не помню
Но вот для примера
Base64Encode.asm
Код:
.686
.model flat, stdcall
option casemap :none

.data 
align 4
b64chars label byte
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

.code

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

; returns b64 string len
Base64Encode proc pInputData:DWORD,dwDataLen:DWORD,pOutputStr:DWORD
	push ebp
	push esi
	push edi
	push ebx
	mov esi,[esp+1*4][4*4];pInputData
	mov ebp,[esp+2*4][4*4];dwDataLen
	mov edi,[esp+3*4][4*4];pOutputStr
	.repeat
  test ebp,ebp
  jz @F; exact divide 3?
	; EEEEEEFF CCDDDDDD BBBBCCCC AAAAAABB
  mov al,[esi+0]
  mov dl,[esi+1]
  mov bl,[esi+2]
  mov ah,al
  mov dh,dl
  mov bh,bl
  and ah,00000011b
  and dh,00001111b
  and bh,00111111b
  shr al,2
  shr dl,4
  shr bl,6
  shl ah,4
  shl dh,2
  or ah,dl
  or bl,dh
  movzx edx,al
  movzx ecx,ah
  mov al,[edx+b64chars]
  mov ah,[ecx+b64chars]
  movzx edx,bl
  movzx ecx,bh
  mov bl,[edx+b64chars]
  mov bh,[ecx+b64chars]
  and eax,0FFFFh
  shl ebx,16
  add esi,3
  or eax,ebx
  stosd
  sub ebp,3
	.until SIGN?
    add edi,ebp
    .repeat
  mov byte ptr [edi],'='
     inc edi
  inc ebp
    .until ZERO?
@@:	mov eax,edi
	pop ebx
	mov [eax],bp
	pop edi
	pop esi
	sub eax,[esp+3*4][1*4];pOutputStr
	pop ebp
	ret 3*4
Base64Encode endp

OPTION PROLOGUE:PROLOGUEDEF 
OPTION EPILOGUE:EPILOGUEDEF
end

Base64Decode.asm
Код:
.686
.model flat, stdcall
option casemap :none

.data 
align 4
b64table label byte
db 0,42 dup (-1)
db 62; +; [02Bh]
db 3 dup(-1)
db 63; /; [02Fh]
db 52,53,54,55,56,57,58,59,60,61; 0..9;30-39
db 3 dup(-1)
db 0; =; [03Dh]
db 3 dup(-1)
db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25; A..Z
db 6 dup(-1)
db 26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51; a..z
db 133 dup (-1)

.code

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
Base64Decode proc pInputStr:DWORD,pOutputData:DWORD
	push ebp
	push esi
	push edi
	push ebx
	mov edi,[esp+1*4][4*4];pInputStr
	xor eax,eax
	mov esi,edi
	.repeat; strlen 
  mov al,[edi]
  add edi,4
  test al,al
	.until zero?
	lea ebp,[edi-4]
	mov eax,'='
	sub ebp,esi; 4parts
	jz @F
	cmp al,[esi+ebp-1]; padd?
	sete dl
	.if zero?;equal?
  mov [esi+ebp-1],ah
	.endif
	cmp al,[esi+ebp-2]
	sete al
	.if zero?;equal?
  mov [esi+ebp-2],ah
	.endif
	add al,dl
	mov edi,[esp+2*4][4*4];pOutputData
	shr ebp,2
	lea edx,[ebp*2+ebp]
	sub edx,eax
	push edx; result = length
	.repeat
	; CCDDDDDD BBBBCCCC AAAAAABB
  mov ecx,[esi]
  movzx edx,cl
  movzx ebx,ch
  mov al,[edx+b64table]; ..AAAAAA
  mov ah,[ebx+b64table]; ..BBBBBB
  shr ecx,16
  add esi,4
  movzx edx,cl
  movzx ecx,ch
  mov bl,[edx+b64table]; ..CCCCCC
  mov bh,[ecx+b64table]; ..DDDDDD
  mov dl,ah
  mov dh,bl
  shl al,2;AAAAAA..
  shr bl,2;....CCCC
  shl dh,6;CC......
  shl ah,4;BBBB....
  shr dl,4;......BB
  or bh,dh
  or al,dl
  or ah,bl
  mov [edi+0],al
  mov [edi+2],bh
  mov [edi+1],ah
  dec ebp
  lea edi,[edi+3]
	.until zero?
	pop eax
@@:	pop ebx
	pop edi
	pop esi
	pop ebp
	ret 2*4
Base64Decode endp

OPTION PROLOGUE:PROLOGUEDEF 
OPTION EPILOGUE:EPILOGUEDEF
end

Добавил их(*.asm) в сишный проект(кстати лучше юзать C++ и это без вариантов) и определил как
Код:
extern "C" DWORD Base64Encode(char *pInputData, DWORD dwDataLen, char *pOutputStr);
extern "C" void Base64Decode(char *pInputStr, char *pOutputData);

И потом юзаю так(для примера)
Код:
char b64[100];
char buf[100];
DWORD len = Base64Encode("test", 4, b64);
Base64Decode(b64, buf);
Вроде на *.exe траблов никогда и не было, но тут даже самое главное - быстро и без пЫли..
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх