CyberArmy Academy | CyberArmy Services & Support | Open Source Institute | CyberArmy Intelligence & Security | CyberArmy Projects

[Library Index]

[View category: Asm] [Discuss Article]

Adding a function to win32 SNEAK :: translation table (xlat)

Article is yet to be rated
Author:      sefo
Submitted:      10-Jun-2007 07:18:42
 


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.
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:



This article was originally published by CyberArmy.net in the CyberArmy Library.

You must be logged in to vote on an article

About Us | Privacy Policy | Mission Statement | Help