Created
          September 21, 2025 11:17 
        
      - 
      
- 
        Save isopen/41481eda87db2e6426af75be9d1f3748 to your computer and use it in GitHub Desktop. 
    nasm_tdjson_example
  
        
  
    
      This file contains hidden or 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
    
  
  
    
  | ; 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 | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment