News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

BASE64 Distance between EDI from Start To Finish

Started by AgentSmithers, May 30, 2009, 05:55:26 AM

Previous topic - Next topic

AgentSmithers

;************************************************* *********
;Function function: to Base64 encoding
;Parameters:
;Source = incoming string
;Destination = return code
;********************************************************** ;************************************************* *********
Base64Encode proc uses ebx edi esi source:DWORD, destination:DWORD
LOCAL sourcelen:DWORD
invoke lstrlen, source
mov sourcelen, eax

mov esi, source
mov edi, destination
@@base64loop:
xor eax, eax
.if sourcelen == 1
    lodsb ;source ptr + 1
    mov ecx, 2 ;bytes to output = 2
    mov edx, 03D3Dh ;padding = 2 byte
    dec sourcelen ;length - 1
.elseif sourcelen == 2
    lodsw ;source ptr + 2
    mov ecx, 3 ;bytes to output = 3
    mov edx, 03Dh ;padding = 1 byte
    sub sourcelen, 2 ;length - 2
.else
    lodsd
    mov ecx, 4 ;bytes to output = 4
    xor edx, edx ;padding = 0 byte
    dec esi ;source ptr + 3 (+4-1)
    sub sourcelen, 3 ;length - 3
.endif

xchg al,ah ;flip eax completely
rol eax, 16 ;can this be done faster
xchg al,ah

@@:
push eax
and eax, 0FC000000h ;get the last 6 high bits
rol eax, 6 ;rotate them into al
mov al, byte ptr [offset base64_alphabet + eax] ;get encode character
stosb ;write to destination
pop eax
shl eax, 6 ;shift left 6 bits
dec ecx
jnz @B ;loop

cmp sourcelen, 0
jnz @@base64loop ;main loop

mov eax, edx ;add padding and null terminate
stosd

;xor eax, eax
;loop4ever:
;mov esi, destination
;cmp byte ptr [esi], 0
;inc eax
;jne loop4ever
;add eax, 48

;invoke WriteConsoleA, STDHandle, eax, 2, ebx, 0 ;Uses 2Byte Tchar's

;invoke WriteConsoleA, STDHandle, addr CRLF, 2, ebx, 0 ;Uses 2Byte Tchar's

ret
Base64Encode endp


Now My Attempts are their as follows and failed...

would a simple soultion would be to push the offset of destination onto the stack and once done pop it and do a sub new, old to get a value = length of the encoded output?


dedndave

i take it you are trying to pre-calculate the length  :dazzled:

        mov     eax,InputLength
        mov     edx,eax
        shr     edx,1
        shr     edx,1
        sub     eax,edx     ;eax = OutputLength

is that what you mean ?

EDITED - try that

AgentSmithers

Well I don't think its exactly, I'm going to go deeper into detail. At the end of the function it returns will a address in "Destination" filled with the values of the Base64 Encrypted string version of the "Source"
with the lest amount of clock cycles I want to fetch the side of the Encryption string.

Question though:

How does bit shifting EDX play a role in comparing space between an address?

dedndave

shr edx,1 divides edx by 2 - notice, it throws away some low-order bits - in this case, that is ok
shr on a register is a very fast instruction
eax holds the input size (until the sub instruction)
in edx, we caclulate how many bytes are saved by mod 64 compression
the last instruction (sub) ...
(input length) - (bytes saved) = (output length)

you can calculate afterwards like you said, also

mov esi, offset InputData
mov edi, offset OutputData
push edi
.
.
.
pop esi
sub edi,esi

now, edi holds the OutputData bytes and esi points to the first output byte

AgentSmithers

Quote from: dedndave on May 30, 2009, 12:36:55 PM
shr edx,1 divides edx by 2 - notice, it throws away some low-order bits - in this case, that is ok
shr on a register is a very fast instruction
eax holds the input size (until the sub instruction)
in edx, we caclulate how many bytes are saved by mod 64 compression
the last instruction (sub) ...
(input length) - (bytes saved) = (output length)

you can calculate afterwards like you said, also

mov esi, offset InputData
mov edi, offset OutputData
push edi
.
.
.
pop esi
sub edi,esi

now, edi holds the OutputData bytes and esi points to the first output byte


Ahhh right I know Shift Right is the same as /2. now this code makes sence to compare the distance between the two offsets and getting the difference in bytes
mov esi, offset InputData
mov edi, offset OutputData
push edi
.
.
.
pop esi
sub edi,esi


But I cant relate this code
shr edx,1 divides edx by 2 - notice, it throws away some low-order bits - in this case, that is ok
shr on a register is a very fast instruction
eax holds the input size (until the sub instruction)
in edx, we calculate how many bytes are saved by mod 64 compression
the last instruction (sub) ...
(input length) - (bytes saved) = (output length)


to the Base64 I posted above, Is InputLength meant to be = Source?
now another question I feel im missing something here, When Base64Encode hits RET the EDI = The starting byte of the Encoded value due to stosb, Would it be better/Possible to pull of offset off of stosb after the final loop and sub it from their?

After STOSB are leftover values stored in EDX i must not be aware of and thats why you are SHR'ing that specific register?

dedndave

it converts data into base64
for InputLength, you tell it how many input bytes you have
for Source, you tell it the address of the first input byte
for Destination, you tell it the address of the first output byte

AgentSmithers

Ok, I really like the help so I thankyou, But If Im getting this correct it seems like your telling me how to operate the function? not calculate the length of the encoded data?

invoke lstrlen, source - is used to get the inputlength from my understanding

Im going to read over again..

dedndave

well - without reading the code, i figured you were trying to compress some data
i have used similar techniques before, myself
i thought you wanted to get data that could be represented with 6 bits tightly packed into 8
(i.e. 4 input bytes into 3 output bytes)
the little shr, shr, subtract code pre-calculates that output length

AgentSmithers

OH! no no no no I was like wtf does Shr have anything to do with it lol.

Yeah I have a string being passed in and out comes a Encoded version of the string.

now I was to get the StrLen of the Encoded string so I can send it through a command that requires a stringlen to be passed to it, Lets say Winsock send as a Example, it requires how many bytes to send as part of the Param.

AgentSmithers

NVM I got it, Base64 is always 4to3 4to2 and 4to1 char.

So if you have a 7 letter string being encoded its going to take up 12 chars once encoded!


Cheers

-Agent
=)

FORTRANS

Quote from: AgentSmithers on June 04, 2009, 05:25:20 AM
NVM I got it, Base64 is always 4to3 4to2 and 4to1 char.

So if you have a 7 letter string being encoded its going to take up 12 chars once encoded!

Hello,

   While that is true for UUEncode, and maybe XXEncode (I would have to
check), you can encode 3 into 4, 2 into 3 and 1 into 2 as the last bytes in
the input stream.  So a 7 letter string can be either 12 or 10 characters when
encoded depending on the standard being followed.

Steve N.

AgentSmithers

Um not sure if we are on the same Topic but Base64's standard pads with a '=' byte until the 4 byte sequence is met.

FORTRANS

Hello,

   Encoding in base-64 is an algorithm with differing implementations.
If the one you use requires padding, then do so.  And you are then
correct on the character count.  But the algorithm does not require
padding.

Regards,

Steve N.