Statistics

Members: 1925
News: 293
Web Links: 1
Visitors: 3826348

Who's Online

Damn Vulnerable LinuxDamn Vulnerable Linux (DVL) is a Linux-based (modified Damn Small Linux) tool for IT-Security & IT-Anti- Security and Attack & Defense. [CLICK HERE FOR MORE INFOS! ]

Featured Conference Video

T16-Recon2006-Joe_Stewart-OllyBonE.gif OllyBone - Semi-Automatic Unpacking on IA-32. View the conference video here!
Home arrow Articles - Programming arrow Assembly arrow Write an 11-byte program that displays its command line.
Write an 11-byte program that displays its command line.
User Rating: / 1
PoorBest 
Written by Xbios2   
Side Story
A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux

If you're a programmer who's become fed up with software bloat, then may you find herein the perfect antidote.

This document explores methods for squeezing excess bytes out of simple programs. (Of course, the more practical purpose of this document is to describe a few of the inner workings of the ELF file format and the Linux operating system. But hopefully you can also learn something about how to make really teensy ELF executables in the process.)

Please note that the information and examples given here are, for the most part, specific to ELF executables on a Linux platform running under an Intel-386 architecture. I imagine that a good bit of the information is applicable to other ELF-based Unices, but my experiences with such are too limited for me to say with certainty.

The assembly code that appears in this document is written for use with Nasm. (Besides being more appropriate for our needs, Nasm's syntax beats the hell out of AT&T syntax for anyone who learned x86 assembly language before learning to use Gas.) Nasm is freely available and extremely portable; see http://nasm.sourceforge.net/.

Please also note that if you aren't a little bit familiar with assembly code, you may find parts of this document sort of hard to follow.


Read More >>



Before saying that these programs won't work, try them. Some of them work only fter you've run them twice. Anyway, they' ve been tested both under Windows and plain DOS and they work. Believe it or not, these are the first programs 've ever written in DOS, so I just tried various ideas until some worked, even hought I thought they wouldn't... :) The command line in DOS is found in the PSP (Program Segment Prefix) which in COM files occupies the first 100h bytes in the segment. At offset 80h, a count, char> string (first byte is length of string, and n bytes follow) contains everything typed after the filename. The last character in this string s a CR (carriage return).

The requested program should be composed of three parts:

  1. set up pointers to data
  2. display data
  3. exit

Actually all the following programs DON'T include part 3, but read on. The data (command line) can be printed either as a single string, or character by character.

APPROACH 1: Print single string


For the first approach there are two interrupts: 1. INT 21, 9 ; write $ terminated string 2. INT 21, 40 ; write to file using handle

For the first case, part 2 would be:

        mov     ah, 9
mov     dx, 81h
int     21h

that makes 7 bytes, leaving only 4 bytes to replace the last CR with a '$', which are too few. (Actually, if the user would type a $ as the last character in the comand line, this would make the smallest possible program.) The short- est program I managed to write is:

        shr     si,1                    ; D1 EE
lodsb                           ; AC
push    si                      ; 56
add     si,ax                   ; 03 F0
mov     byte ptr [si],'$'       ; C6 04 24
xcgh    bp,ax                   ; 95
pop     dx                      ; 5A
int     21                      ; CD 21

For the second case, the smallest program would be this:

        ; Solution I
mov     dx, 81h                 ; BA 81 00
mov     cl, ds:[80h]            ; 8A 0E 80 00
mov     ah, 40h                 ; B4 40
int     21h                     ; CD 21

The first two lines are part 1 (set up pointers) and the other two are part 2 (display string). If you think that something is missing you're right: we don't set BX (the handle).

APPROACH 2: Print char by char


For the second approach there are two interrupts: 1. INT 21, 2 ; write char in dl
2. INT 29 ; write char in al

Of course the second interrupt is better, since there is no need to load ah with a function value. In addition, INT 29 reads the char from AL, so it can be used together with LODSB.

The first way to implement this approach is to minimize part 2 (display loop). A program that does this is the following:

        ; Solution II
mov     si, 80h ; BE 80 00
lodsb           ; AC
mov     cl, al  ; 8A C8
more:   lodsb           ; AC
int     29h     ; CD 29
loop    more    ; E2 FB

This program printed CX characters. The second way to print the string is to print up to the CR. Here is how:

        ; Solution III
mov     si, 81h         ; BE 81 00
more:   lodsb                   ; AC
int     29h             ; CD 29
cmp     al, 13          ; 3C 0D
jne     more            ; 75 F9
nop                     ; 90

Yes, the last instruction IS a NOP. So we have an 11-byte program that works, and even has a NOP in it. Removing the NOP creates an even crazier program that is 10 bytes long, displays it's command line AND waits for a key press before terminating... Actually solution II, by substituting MOV SI,80h with SHR SI,1, does the same thing (10 bytes that display the command line and wait for the user to press a key).

BTW: I really don't know why these programs work, though I have one or two theories...

Next Issue Challenge


Write the smallest possible PE program (win32) that outputs it's command line.