Skip to content

Instantly share code, notes, and snippets.

@icedraco
Created November 27, 2014 11:23
Show Gist options
  • Save icedraco/de9e95ac51a9a2553081 to your computer and use it in GitHub Desktop.
Save icedraco/de9e95ac51a9a2553081 to your computer and use it in GitHub Desktop.
Cellphone dictionary generator done in x86 assembly
;;; Cellphone Permutation Generator v1.0
;
; This is part of the Israeli cellphone permutation generator. This file
; implements the _start() function and provides a couple of functions, among
; which there's the generator.
;
; print(int fd, char* str)
; Prints a string to STDOUT
;
; int generate(int prefixDigit, char* filename)
; Generates cellphone numbers with a given prefix digit into a specified file.
; Returns 0 upon success or anything else if the process failed.
%define FILE_PERM 0o664
%define BUFFER_LEN 8192
section .data
cellphone_buffer_up:
db "05xxxxxxxx", 10
cellphone_buffer_down:
db "05xxxxxxxx", 10
len_cell: equ $-cellphone_buffer_down
section .bss
buffer: resb BUFFER_LEN
section .text
extern main
global _start
global generate
global print
_start:
pop dword ecx ; ecx = argc
mov esi,esp ; esi = argv
;; lea eax, [esi+4*ecx+4] ; eax = envp = (4*ecx)+esi+4
mov eax,ecx ; put the number of arguments into eax
shl eax,2 ; compute the size of argv in bytes
add eax,esi ; add the size to the address of argv
add eax,4 ; skip NULL at the end of argv
push dword eax ; char *envp[]
push dword esi ; char* argv[]
push dword ecx ; int argc
call main ; int main( int argc, char *argv[], char *envp[] )
mov ebx,eax
mov eax,1
int 0x80
nop
;------------------------------------------------------------------------------
print:
push ebp
mov ebp, esp
pushad
mov ebx, [ebp+8] ; int fd
mov ecx, [ebp+12] ; char* string
mov edx, ecx ; ECX will be mangled below - save the address
; Calculate length
mov edi, ecx
xor al, al
cld
repne scasb ; Scan until [edi] = al (aka: 0)
mov ecx, edx ; Restore ECX to [ebp+12]
mov edx, edi
sub edx, ecx ; edx now has the length
mov eax, 4 ; sys_write
int 0x80
popad
pop ebp
ret
;------------------------------------------------------------------------------
generate:
push ebp
mov ebp, esp
pushad
mov eax, [ebp+8] ; int prefix
mov ebx, [ebp+12] ; char* filename
; Set prefix
add al, 0x30
mov byte [cellphone_buffer_up + 2], al
mov byte [cellphone_buffer_down + 2], al
; Initialize the rest of the digits
mov byte [cellphone_buffer_up + 3], '5'
mov byte [cellphone_buffer_down + 3], '4'
mov dword [cellphone_buffer_up + 4], 0x30303030 ; '0000'
mov word [cellphone_buffer_up + 8], 0x3030 ; '00'
mov dword [cellphone_buffer_down + 4], 0x39393939 ; '9999'
mov word [cellphone_buffer_down + 8], 0x3939 ; '99'
; Try to open output file
mov eax, 5 ; sys_open
mov ecx, 0o2101 ; O_WRONLY|O_APPEND|O_CREATE
mov edx, FILE_PERM
int 0x80
cmp eax, 0
jl __gen_return
mov ebx, eax ; Pass the FD to EBX before we work on it
; Start writing cellphone numbers to the buffer/disk
mov edi, buffer
__write_loop:
;;; Write cell numbers to buffer (and then - to disk)
mov esi, cellphone_buffer_up
call _write_cell
cmp eax, 0
jl __gen_return ; Write error
call _increment ; Increment cell number in buffer_up (ESI)
mov esi, cellphone_buffer_down
call _write_cell
cmp eax, 0
jl __gen_return ; Write error
call _decrement ; Decrement cell number in buffer_down (ESI)
;;; Exit when _decrement determines it's done
cmp dl, 1
jl __write_loop
call _flush_buffer ; Flush any remainder within the buffer
xor eax, eax ; Report success
__gen_return:
push eax
mov eax, 6 ; sys_close
int 0x80
pop eax
popad
pop ebp
ret
;------------------------------------------------------------------------------
_write_cell:
; We have EDI pointing to current buffer position and ESI to cellphone str.
; Make sure we have enough space for len_cell bytes
mov eax, edi
add eax, len_cell
cmp eax, buffer+BUFFER_LEN
jb __add_to_buffer ; We do - don't flush it just yet
call _flush_buffer
__add_to_buffer:
push esi
mov ecx, len_cell
rep movsb
pop esi
ret
;------------------------------------------------------------------------------
_flush_buffer:
; EDI contains the current position within the buffer
mov eax, 4 ; sys_write
mov ecx, buffer
mov edx, edi
sub edx, ecx ; Now we have the byte count
int 0x80
mov edi, buffer ; Reset buffer pointer back to beginning
ret
;------------------------------------------------------------------------------
_increment:
push ecx
xor edx, edx
mov ecx, len_cell - 4 ; Using it as offset (-3 -\n)
__inc_loop:
cmp byte [esi+ecx+2], '9' ; Is this the highest digit?
jl __incr ; No - increment it
mov byte [esi+ecx+2], '0'
loop __inc_loop
inc dl
jmp __incr_done
__incr:
inc byte [esi+ecx+2]
__incr_done:
pop ecx
ret
;------------------------------------------------------------------------------
_decrement:
push ecx
xor edx, edx
mov ecx, len_cell - 4 ; Using it as offset (-3 -\n)
__dec_loop:
cmp byte [esi+ecx+2], '0' ; Is this the lowest digit?
jg __decr ; No - decrement it
mov byte [esi+ecx+2], '9'
loop __dec_loop
inc dl
jmp __decr_done
__decr:
dec byte [esi+ecx+2]
__decr_done:
pop ecx
ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment