nasm_tdjson_example
September 21, 2025 ยท View on GitHub
; TDLib Minimal Linux Client in x86-64 Assembly (NASM) ; ; nasm -f elf64 -o nasm_tdjson_example.o nasm_tdjson_example.asm ; gcc -o nasm_tdjson_example nasm_tdjson_example.o -ldl -no-pie ; ./nasm_tdjson_example
section .data ; Error messages lib_error db "Error: libtdjson.so not found", 10, 0 client_error db "Error: Failed to create client", 10, 0 input_error db "Error reading input", 10, 0 receive_error db "Error in receive function", 10, 0
; Function names
create_name db "td_json_client_create", 0
send_name db "td_json_client_send", 0
receive_name db "td_json_client_receive", 0
destroy_name db "td_json_client_destroy", 0
execute_name db "td_json_client_execute", 0
; Library name
lib_name db "libtdjson.so", 0
; Prompts
phone_prompt db "Enter phone number (international format): ", 0
code_prompt db "Enter authentication code: ", 0
password_prompt db "Enter password: ", 0
auth_success db "Authorization successful!", 10, 0
auth_wait db "Waiting for authorization...", 10, 0
; JSON messages
params_msg db '{"@type":"setTdlibParameters","database_directory":"td_data","use_message_database":true,"api_id":94575,"api_hash":"a3406de8d171bb422bb6ddf3bbd800e2","system_language_code":"en","device_model":"AsmClient","application_version":"1.0"}', 0
verbosity_msg db '{"@type":"setLogVerbosityLevel","new_verbosity_level":2}', 0
close_msg db '{"@type":"close"}', 0
newline db 10, 0
; Authorization states
auth_wait_phone db "authorizationStateWaitPhoneNumber", 0
auth_wait_code db "authorizationStateWaitCode", 0
auth_wait_password db "authorizationStateWaitPassword", 0
auth_ready db "authorizationStateReady", 0
; Format strings
fmt_phone db '{"@type":"setAuthenticationPhoneNumber","phone_number":"%s"}', 0
fmt_code db '{"@type":"checkAuthenticationCode","code":"%s"}', 0
fmt_password db '{"@type":"checkAuthenticationPassword","password":"%s"}', 0
section .bss ; Handle pointers lib_handle resq 1 client_handle resq 1
; Function pointers
create_func resq 1
send_func resq 1
receive_func resq 1
destroy_func resq 1
execute_func resq 1
; Buffers
input_buffer resb 256
phone_buffer resb 32
code_buffer resb 16
password_buffer resb 64
json_buffer resb 1024
auth_state resq 1
section .text global main extern dlopen, dlsym, printf, sleep, exit, fgets, stdin, strstr, sprintf, strlen, putchar, usleep, fflush
main: push rbp mov rbp, rsp sub rsp, 32
; Load TDLib library
mov rdi, lib_name
mov rsi, 1
call dlopen
test rax, rax
jz .dl_error
mov [lib_handle], rax
; Get function addresses
mov rdi, [lib_handle]
mov rsi, create_name
call dlsym
mov [create_func], rax
mov rdi, [lib_handle]
mov rsi, send_name
call dlsym
mov [send_func], rax
mov rdi, [lib_handle]
mov rsi, receive_name
call dlsym
mov [receive_func], rax
mov rdi, [lib_handle]
mov rsi, destroy_name
call dlsym
mov [destroy_func], rax
mov rdi, [lib_handle]
mov rsi, execute_name
call dlsym
mov [execute_func], rax
; Create TDLib client
call [create_func]
test rax, rax
jz .client_error
mov [client_handle], rax
; Set log verbosity
mov rdi, [client_handle]
mov rsi, verbosity_msg
call [execute_func]
; Set TDLib parameters
mov rdi, [client_handle]
mov rsi, params_msg
call [send_func]
; Authorization loop
xor r12, r12
mov qword [auth_state], 0
mov edi, 50000
call usleep
.auth_loop: mov rdi, [client_handle] xor rsi, rsi call [receive_func] test rax, rax jz .no_message
; Process message
mov rdi, rax
call process_message
cmp r12, 1
je .auth_complete
.no_message: ; Check if we need to request input cmp qword [auth_state], 1 ; wait_phone je .request_phone cmp qword [auth_state], 2 ; wait_code je .request_code cmp qword [auth_state], 3 ; wait_password je .request_password
mov edi, 10000
call usleep
jmp .auth_loop
.request_phone: mov rdi, phone_prompt call printf xor rdi, rdi call fflush
; Read phone number
mov rdi, phone_buffer
mov rsi, 32
mov rdx, [stdin]
call fgets
test rax, rax
jz .input_error
; Remove newline
mov rdi, phone_buffer
call remove_newline
; Create JSON for phone number
mov rdi, json_buffer
mov rsi, fmt_phone
mov rdx, phone_buffer
call sprintf
; Send to TDLib
mov rdi, [client_handle]
mov rsi, json_buffer
call [send_func]
mov qword [auth_state], 0
mov edi, 10000
call usleep
jmp .auth_loop
.request_code: mov rdi, code_prompt call printf xor rdi, rdi call fflush
; Read code
mov rdi, code_buffer
mov rsi, 16
mov rdx, [stdin]
call fgets
test rax, rax
jz .input_error
; Remove newline
mov rdi, code_buffer
call remove_newline
; Create JSON for code
mov rdi, json_buffer
mov rsi, fmt_code
mov rdx, code_buffer
call sprintf
; Send to TDLib
mov rdi, [client_handle]
mov rsi, json_buffer
call [send_func]
mov qword [auth_state], 0
mov edi, 10000
call usleep
jmp .auth_loop
.request_password: mov rdi, password_prompt call printf xor rdi, rdi call fflush
; Read password
mov rdi, password_buffer
mov rsi, 64
mov rdx, [stdin]
call fgets
test rax, rax
jz .input_error
; Remove newline
mov rdi, password_buffer
call remove_newline
; Create JSON for password
mov rdi, json_buffer
mov rsi, fmt_password
mov rdx, password_buffer
call sprintf
; Send to TDLib
mov rdi, [client_handle]
mov rsi, json_buffer
call [send_func]
mov qword [auth_state], 0
mov edi, 10000
call usleep
jmp .auth_loop
.auth_complete: mov rdi, auth_success call printf
; Main loop
mov r13, 100
.main_loop: ; Receive messages mov rdi, [client_handle] xor rsi, rsi call [receive_func] test rax, rax jz .no_msg_main
; Print message
mov rdi, rax
call printf
mov rdi, newline
call printf
.no_msg_main: mov edi, 50000 call usleep dec r13 jnz .main_loop
.cleanup: ; Send close command mov rdi, [client_handle] mov rsi, close_msg call [send_func]
mov edi, 50000
call usleep
; Destroy client
mov rdi, [client_handle]
call [destroy_func]
; Exit
xor rdi, rdi
call exit
.dl_error: mov rdi, lib_error call printf mov rdi, 1 call exit
.client_error: mov rdi, client_error call printf jmp .cleanup
.input_error: mov rdi, input_error call printf jmp .cleanup
process_message: push rbp mov rbp, rsp push r12 push r13 mov r12, rdi
mov rdi, r12
mov rsi, auth_wait_phone
call strstr
test rax, rax
jnz .wait_phone
mov rdi, r12
mov rsi, auth_wait_code
call strstr
test rax, rax
jnz .wait_code
mov rdi, r12
mov rsi, auth_wait_password
call strstr
test rax, rax
jnz .wait_password
mov rdi, r12
mov rsi, auth_ready
call strstr
test rax, rax
jnz .auth_ready
jmp .done
.wait_phone: mov qword [auth_state], 1 jmp .done
.wait_code: mov qword [auth_state], 2 jmp .done
.wait_password: mov qword [auth_state], 3 jmp .done
.auth_ready: mov r12, 1 mov qword [auth_state], 0
.done: pop r13 pop r12 pop rbp ret
remove_newline: push rbp mov rbp, rsp
mov rcx, rdi
.find_end: cmp byte [rcx], 0 je .check_newline inc rcx jmp .find_end
.check_newline: dec rcx cmp byte [rcx], 10 jne .end mov byte [rcx], 0
.end: pop rbp ret