Created
November 27, 2014 11:23
-
-
Save icedraco/de9e95ac51a9a2553081 to your computer and use it in GitHub Desktop.
Cellphone dictionary generator done in x86 assembly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; 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