View and vote on the article here: Adding a function to win32 SNEAK :: translation table (xlat)
Adding a function to win32 SNEAK :: translation table (xlat)| Category | | | Summary | | The theory behind XLAT (or "translation") encoding is to replace each byte of an original text with the bytes from a character table whose positions correspond to the original byte value. |
| | Body | Prerequisites
To program win32 Sneak, you need the MASM assembler package and the WinASM studio IDE.
You can find the latest MASM version at:
http://www.masm32.com/masmdl.htm
And WinASM Studio at:
http://www.winasm.net
Basic structure of the win32 Sneak project
As stated in the readme file, the project contains the following files:
sneak.inc - which contains all the variables, string definitions and functions prototypes needed by the program;
rsrc.rc - the resource file for the user interface;
sneak.asm - the main source file containing only the windows creation and the messages handling function;
functions.asm - which contains all non-encryption / non-encoding functions (error handling functions, combobox handling functions, etc.);
hashing.asm - contains the hashing functions (only md5 for the moment);
encoding_decoding.asm - for base64 and leet encode/decode (XLAT will be placed here);
byte_operations.asm - for byte operations like conversion and rotation.
The XLAT / un-XLAT feature
The result we wish to achieve here is that the combobox should add another option for encoding and decoding functions. When it is selected, a window should pop up with a text box to insert a list of printable ASCII characters and two buttons to run the XLAT / un-XLAT functions. Finally, the popup is closed and the result displayed in the main window.
Adding the combobox option
First we need to define the strings "XLAT" in sneak.inc
You can add it anywhere in the .data section.
Since xlat is a reserved word, you cannot use it as a variable, so we work around it like so:
xxlat byte "XLAT",0
The next step is to add the string inside the combo box.
Open functions.asm and expand the FillCombo procedure.
Add the following line after the md5 options:
invoke SendMessage,hCombo,CB_ADDSTRING,0,offset xxlat
Now expand the HandleCombo procedure and add the following condition:
.elseif Index == 25 ;xlat
;call XlatEncodeDecode
Since the function doesn't exist yet, we want to comment it out for now.
The XLAT procedure
First, let's add the procedure definition at the end of all the existing prototypes in sneak.inc
XlatEncodeDecode PROTO
we can now add the procedure's body inside encoding_decoding.asm and uncomment the call to XlatEncodeDecode() in function.asm -> HandleCombo
XlatEncodeDecode proc uses esi edi ebx
;
ret
XlatEncodeDecode endp
Open the window
Now we need to create a window to enter the custom xlat table. This textbox will be limited to 96 characters (explained later in the XLAT algorithm section) and contain a textbox and two buttons.
In the explorer window, select the "resources" tab and click on "add a new dialog". Add a textbox, 2 buttons, change any settings you like and give it an ID of 1009. The dialog should have the ID "1010" and name "IDC_EDIT3", and finally increment the IDs for the two buttons (to 1011 and 1012).
Now we need to define all the new controls' IDs inside the .const section of sneak.inc
IDD_XLAT equ 1009
IDC_EDIT3 equ 1010
IDC_BUTTON1011 equ 1011
IDC_BUTTON1012 equ 1012
We will call this window using the API DialogBoxParam, but we need a message handling procedure for this new window. So, in sneak.asm we are going to add a new procedure between start() and DlgProc.
The full procedure:
XlatProc proc uses esi edi ebx hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
.IF uMsg == WM_INITDIALOG
mov eax,dword ptr[hWnd]
mov HandleXlatWnd, eax
call InitProc
;ebx = input text, esi = output buffer, edi = size of ebx
.if eax == 0
invoke EndDialog,hWnd,NULL
ret
.endif
.ELSEIF uMsg == WM_COMMAND
mov eax,wParam
mov edx,eax
shr edx,16
and eax,0FFFFh
.if edx==BN_CLICKED
push eax
;*** check if input box is empty and save result ***
lea eax,XlatTable
push 96
push eax
push IDC_EDIT3
push HandleXlatWnd
call GetDlgItemText
.if eax == 96
pop eax
.if eax==IDC_BUTTON1011 ;XLAT
call XlatEncode
.elseif eax==IDC_BUTTON1012 ;un-XLAT
;call XlatDecode
.endif
.endif
.endif
.ELSEIF uMsg == WM_CLOSE
invoke EndDialog,hWnd,NULL
.ENDIF
mov eax, FALSE
ret
XlatProc endp
Since we are going to handle some controls on our new window, we need to keep track of the window's handle and save it in a new variable.
HandleXlatWnd can be defined as dword ? in sneak.inc
Like every procedure in sneak, xlat should start by calling InitProc, which loads the input text into a buffer and returns 0 in eax if there is no text to process.
When the function returns:
-EBX will contain the pointer to the input text.
-ESI will have the pointer to the result buffer.
-EDI is the size of the input text.
Of course we add the new definition for this procedure in sneak.inc (same as DlgProc)
Another point to note here is that we need to check if the input box is empty or not. The text is saved in a 96-byte buffer defined as:
XlatTable byte 96 dup (0)
Now we can go back to encoding_decoding.asm --> XlatEncodeDecode, and add a call to DialogBoxParam:
invoke DialogBoxParam,hInstance,IDD_XLAT,hParent,ADDR XlatProc,NULL
If you test the program now, don't forget to add some text in the input box of sneak before running the XLAT function, or the window will simply not appear.
The Algorithm
For each character in the clear text, we take the hexadecimal value of this character and replace it with a byte in the XLAT table whose position is the value of the character in the clear text.
Since we are going to limit our XLAT table to 96 characters, we must substract 1Eh from the clear byte value so that it fits in position 0-95 of the XlatTable array (with the exception of the character 0Gh, from which we must substract 0Ch).
call InitProc
;ebx = input text, esi = output buffer, edi = size of ebx, dword ptr[XlatTable]
mov edx,ebx ;because we use ebx for the XLAT instruction
lea ebx,XlatTable
xor ecx,ecx
.WHILE ecx < edi
mov al, byte ptr[ebx+ecx]
.IF al == 0Dh
sub al, 0Ch
.ELSE
sub al, 1Eh
.ENDIF
xlat
mov byte ptr[esi+ecx], al
inc ecx
.ENDW
mov byte ptr[esi+ecx],0 ;terminate the string for display
call DisplayResult
And we're done! The XLAT instruction loads in AL the content of address BX+AL, and clearly OriginalByte = XlatTable[OriginalByte].
A concrete example
Given the clear text:
Hey Joe
which corresponds to the hexadecimal values:
48h, 65h, 79h, 20h, 4Ah, 6Fh, 65h
(spaces and line returns will be encrypted as well)
We substract 1Eh from each so that they fit in the XlatTable:
2Ah, 47h, 5Bh, 2h, 2Ch, 51h, 47h
Or in decimals:
42, 71, 91, 2, 44, 33, 71
(N.B.: we need to add 1 to these positions - they represent a starting point in memory, not the exact position)
Now we can go to these positions in the following XlatTable and encrypt the clear text:
abcdefghij
klmnopqrst
uvwxyz1234
567890!@#$
%^&*()_-=+
ABCDEFGHIJ
KLMNOPQRST
UVWXYZ~[{]
}\|'"/?.>,
< `
;<-- line return 0D, 0A counted as 2 characters
;<-- here the TAB character (should be pasted)
Which gives the encrypted text:
"Hey Joe" --> "&V c(\V"
un-XLAT
Using the same XLAT table as above, we want to decode &V c(\V.
For each byte of this encrypted string, in order ot get back the original character, we need to:
1. Find where this character appears in the table
2. Get its position value
3. Add 1Eh to it (or + 0Ch if its value is 1)
At this point you realise the drawback of this technique...
Each character in the XlatTable must be unique!
The decryption algorithm looks like this:
XlatDecode proc
call InitProc
;ebx = input text, esi = output buffer, edi = size of ebx, dword ptr[XlatTable]
mov edx,ebx ;because we use ebx for the XLAT instruction
lea ebx,XlatTable
xor ecx,ecx
xor eax,eax
.WHILE ecx < edi
push ecx
mov al, byte ptr[edx+ecx]
xor ecx,ecx
.while ecx < 96
.if al == byte ptr[XlatTable+ecx]
xchg eax,ecx
jmp @F ;exit loop
.endif
inc ecx
.endw
@@:
pop ecx
.IF al == 1
add al, 0Ch
.ELSE
add al, 1Eh
.ENDIF
mov byte ptr[esi+ecx], al
inc ecx
.ENDW
mov byte ptr[esi+ecx],0
call DisplayResult
ret
XlatDecode EndP
See the result here:
 |
|
There are no replies to this post yet.
|