Created
December 1, 2025 04:36
-
-
Save isopen/cd11dd0cf7cbf2672ac9d7b78d8565eb to your computer and use it in GitHub Desktop.
TDLib ARM64 Client in ARM64 Assembly (ARMv8)
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 ARM64 Client in ARM64 Assembly (ARMv8) | |
| // | |
| // https://gist.github.com/isopen/d21d74da06284ddd5d276d3350a0acb2 | |
| // docker build -t tdlib-arm64-app . | |
| // docker run -it --rm tdlib-arm64-app | |
| .section .data | |
| // Error messages | |
| lib_error: .asciz "Error: libtdjson.so not found\n" | |
| client_error: .asciz "Error: Failed to create client\n" | |
| input_error: .asciz "Error reading input\n" | |
| receive_error: .asciz "Error in receive function\n" | |
| // Function names | |
| create_name: .asciz "td_json_client_create" | |
| send_name: .asciz "td_json_client_send" | |
| receive_name: .asciz "td_json_client_receive" | |
| destroy_name: .asciz "td_json_client_destroy" | |
| execute_name: .asciz "td_json_client_execute" | |
| // Library name | |
| lib_name: .asciz "libtdjson.so" | |
| // Prompts | |
| phone_prompt: .asciz "Enter phone number (international format): " | |
| code_prompt: .asciz "Enter authentication code: " | |
| password_prompt: .asciz "Enter password: " | |
| auth_success: .asciz "Authorization successful!\n" | |
| auth_wait: .asciz "Waiting for authorization...\n" | |
| // JSON messages | |
| params_msg: .asciz "{\"@type\":\"setTdlibParameters\",\"database_directory\":\"td_data\",\"use_message_database\":true,\"api_id\":94575,\"api_hash\":\"a3406de8d171bb422bb6ddf3bbd800e2\",\"system_language_code\":\"en\",\"device_model\":\"ARMv8Client\",\"application_version\":\"1.0\"}" | |
| verbosity_msg: .asciz "{\"@type\":\"setLogVerbosityLevel\",\"new_verbosity_level\":2}" | |
| close_msg: .asciz "{\"@type\":\"close\"}" | |
| newline: .asciz "\n" | |
| // Authorization states | |
| auth_wait_phone: .asciz "authorizationStateWaitPhoneNumber" | |
| auth_wait_code: .asciz "authorizationStateWaitCode" | |
| auth_wait_password: .asciz "authorizationStateWaitPassword" | |
| auth_ready: .asciz "authorizationStateReady" | |
| // Format strings | |
| fmt_phone: .asciz "{\"@type\":\"setAuthenticationPhoneNumber\",\"phone_number\":\"%s\"}" | |
| fmt_code: .asciz "{\"@type\":\"checkAuthenticationCode\",\"code\":\"%s\"}" | |
| fmt_password: .asciz "{\"@type\":\"checkAuthenticationPassword\",\"password\":\"%s\"}" | |
| .section .bss | |
| // Handle pointers | |
| .align 8 | |
| lib_handle: .skip 8 | |
| client_handle: .skip 8 | |
| // Function pointers | |
| create_func: .skip 8 | |
| send_func: .skip 8 | |
| receive_func: .skip 8 | |
| destroy_func: .skip 8 | |
| execute_func: .skip 8 | |
| // Buffers | |
| .align 8 | |
| input_buffer: .skip 256 | |
| phone_buffer: .skip 32 | |
| code_buffer: .skip 16 | |
| password_buffer: .skip 64 | |
| json_buffer: .skip 1024 | |
| auth_state: .skip 4 | |
| .section .text | |
| .global main | |
| .extern dlopen | |
| .extern dlsym | |
| .extern printf | |
| .extern sleep | |
| .extern exit | |
| .extern fgets | |
| .extern stdin | |
| .extern strstr | |
| .extern sprintf | |
| .extern strlen | |
| .extern putchar | |
| .extern usleep | |
| .extern fflush | |
| main: | |
| stp x29, x30, [sp, -96]! | |
| mov x29, sp | |
| // Load TDLib library | |
| ldr x0, =lib_name | |
| mov x1, #1 | |
| bl dlopen | |
| cbz x0, .dl_error | |
| ldr x1, =lib_handle | |
| str x0, [x1] | |
| // Get function addresses | |
| ldr x0, [x1] | |
| ldr x1, =create_name | |
| bl dlsym | |
| ldr x1, =create_func | |
| str x0, [x1] | |
| ldr x0, =lib_handle | |
| ldr x0, [x0] | |
| ldr x1, =send_name | |
| bl dlsym | |
| ldr x1, =send_func | |
| str x0, [x1] | |
| ldr x0, =lib_handle | |
| ldr x0, [x0] | |
| ldr x1, =receive_name | |
| bl dlsym | |
| ldr x1, =receive_func | |
| str x0, [x1] | |
| ldr x0, =lib_handle | |
| ldr x0, [x0] | |
| ldr x1, =destroy_name | |
| bl dlsym | |
| ldr x1, =destroy_func | |
| str x0, [x1] | |
| ldr x0, =lib_handle | |
| ldr x0, [x0] | |
| ldr x1, =execute_name | |
| bl dlsym | |
| ldr x1, =execute_func | |
| str x0, [x1] | |
| // Create TDLib client | |
| ldr x0, =create_func | |
| ldr x0, [x0] | |
| blr x0 | |
| cbz x0, .client_error | |
| ldr x1, =client_handle | |
| str x0, [x1] | |
| // Set log verbosity | |
| ldr x0, =client_handle | |
| ldr x0, [x0] | |
| ldr x1, =verbosity_msg | |
| ldr x2, =execute_func | |
| ldr x2, [x2] | |
| blr x2 | |
| // Set TDLib parameters | |
| ldr x0, =client_handle | |
| ldr x0, [x0] | |
| ldr x1, =params_msg | |
| ldr x2, =send_func | |
| ldr x2, [x2] | |
| blr x2 | |
| // Authorization loop | |
| mov w19, #0 | |
| ldr x0, =auth_state | |
| str wzr, [x0] | |
| mov x0, #50000 | |
| bl usleep | |
| .auth_loop: | |
| ldr x0, =client_handle | |
| ldr x0, [x0] | |
| mov x1, #0 | |
| ldr x2, =receive_func | |
| ldr x2, [x2] | |
| blr x2 | |
| cbz x0, .no_message | |
| // Process message | |
| bl process_message | |
| cbnz w19, .auth_complete | |
| .no_message: | |
| // Check if we need to request input | |
| ldr x0, =auth_state | |
| ldr w0, [x0] | |
| cmp w0, #1 // wait_phone | |
| beq .request_phone | |
| cmp w0, #2 // wait_code | |
| beq .request_code | |
| cmp w0, #3 // wait_password | |
| beq .request_password | |
| mov x0, #10000 | |
| bl usleep | |
| b .auth_loop | |
| .request_phone: | |
| ldr x0, =phone_prompt | |
| bl printf | |
| mov x0, #0 | |
| bl fflush | |
| // Read phone number | |
| ldr x0, =phone_buffer | |
| mov x1, #32 | |
| ldr x2, =stdin | |
| ldr x2, [x2] | |
| bl fgets | |
| cbz x0, .input_error | |
| // Remove newline | |
| ldr x0, =phone_buffer | |
| bl remove_newline | |
| // Create JSON for phone number | |
| ldr x0, =json_buffer | |
| ldr x1, =fmt_phone | |
| ldr x2, =phone_buffer | |
| bl sprintf | |
| // Send to TDLib | |
| ldr x0, =client_handle | |
| ldr x0, [x0] | |
| ldr x1, =json_buffer | |
| ldr x2, =send_func | |
| ldr x2, [x2] | |
| blr x2 | |
| ldr x0, =auth_state | |
| str wzr, [x0] | |
| mov x0, #10000 | |
| bl usleep | |
| b .auth_loop | |
| .request_code: | |
| ldr x0, =code_prompt | |
| bl printf | |
| mov x0, #0 | |
| bl fflush | |
| // Read code | |
| ldr x0, =code_buffer | |
| mov x1, #16 | |
| ldr x2, =stdin | |
| ldr x2, [x2] | |
| bl fgets | |
| cbz x0, .input_error | |
| // Remove newline | |
| ldr x0, =code_buffer | |
| bl remove_newline | |
| // Create JSON for code | |
| ldr x0, =json_buffer | |
| ldr x1, =fmt_code | |
| ldr x2, =code_buffer | |
| bl sprintf | |
| // Send to TDLib | |
| ldr x0, =client_handle | |
| ldr x0, [x0] | |
| ldr x1, =json_buffer | |
| ldr x2, =send_func | |
| ldr x2, [x2] | |
| blr x2 | |
| ldr x0, =auth_state | |
| str wzr, [x0] | |
| mov x0, #10000 | |
| bl usleep | |
| b .auth_loop | |
| .request_password: | |
| ldr x0, =password_prompt | |
| bl printf | |
| mov x0, #0 | |
| bl fflush | |
| // Read password | |
| ldr x0, =password_buffer | |
| mov x1, #64 | |
| ldr x2, =stdin | |
| ldr x2, [x2] | |
| bl fgets | |
| cbz x0, .input_error | |
| // Remove newline | |
| ldr x0, =password_buffer | |
| bl remove_newline | |
| // Create JSON for password | |
| ldr x0, =json_buffer | |
| ldr x1, =fmt_password | |
| ldr x2, =password_buffer | |
| bl sprintf | |
| // Send to TDLib | |
| ldr x0, =client_handle | |
| ldr x0, [x0] | |
| ldr x1, =json_buffer | |
| ldr x2, =send_func | |
| ldr x2, [x2] | |
| blr x2 | |
| ldr x0, =auth_state | |
| str wzr, [x0] | |
| mov x0, #10000 | |
| bl usleep | |
| b .auth_loop | |
| .auth_complete: | |
| ldr x0, =auth_success | |
| bl printf | |
| // Main loop | |
| mov w20, #100 | |
| .main_loop: | |
| // Receive messages | |
| ldr x0, =client_handle | |
| ldr x0, [x0] | |
| mov x1, #0 | |
| ldr x2, =receive_func | |
| ldr x2, [x2] | |
| blr x2 | |
| cbz x0, .no_msg_main | |
| // Print message | |
| bl printf | |
| ldr x0, =newline | |
| bl printf | |
| .no_msg_main: | |
| mov x0, #50000 | |
| bl usleep | |
| subs w20, w20, #1 | |
| bne .main_loop | |
| .cleanup: | |
| // Send close command | |
| ldr x0, =client_handle | |
| ldr x0, [x0] | |
| ldr x1, =close_msg | |
| ldr x2, =send_func | |
| ldr x2, [x2] | |
| blr x2 | |
| mov x0, #50000 | |
| bl usleep | |
| // Destroy client | |
| ldr x0, =client_handle | |
| ldr x0, [x0] | |
| ldr x1, =destroy_func | |
| ldr x1, [x1] | |
| blr x1 | |
| // Exit | |
| mov x0, #0 | |
| bl exit | |
| .dl_error: | |
| ldr x0, =lib_error | |
| bl printf | |
| mov x0, #1 | |
| bl exit | |
| .client_error: | |
| ldr x0, =client_error | |
| bl printf | |
| b .cleanup | |
| .input_error: | |
| ldr x0, =input_error | |
| bl printf | |
| b .cleanup | |
| process_message: | |
| stp x29, x30, [sp, -32]! | |
| mov x29, sp | |
| str x19, [sp, 16] | |
| mov x19, x0 | |
| ldr x1, =auth_wait_phone | |
| bl strstr | |
| cbnz x0, .wait_phone | |
| mov x0, x19 | |
| ldr x1, =auth_wait_code | |
| bl strstr | |
| cbnz x0, .wait_code | |
| mov x0, x19 | |
| ldr x1, =auth_wait_password | |
| bl strstr | |
| cbnz x0, .wait_password | |
| mov x0, x19 | |
| ldr x1, =auth_ready | |
| bl strstr | |
| cbnz x0, .auth_ready | |
| b .done | |
| .wait_phone: | |
| ldr x0, =auth_state | |
| mov w1, #1 | |
| str w1, [x0] | |
| b .done | |
| .wait_code: | |
| ldr x0, =auth_state | |
| mov w1, #2 | |
| str w1, [x0] | |
| b .done | |
| .wait_password: | |
| ldr x0, =auth_state | |
| mov w1, #3 | |
| str w1, [x0] | |
| b .done | |
| .auth_ready: | |
| mov w19, #1 | |
| ldr x0, =auth_state | |
| str wzr, [x0] | |
| .done: | |
| ldr x19, [sp, 16] | |
| ldp x29, x30, [sp], 32 | |
| ret | |
| remove_newline: | |
| mov x1, x0 | |
| .find_end: | |
| ldrb w2, [x1] | |
| cbz w2, .check_newline | |
| add x1, x1, #1 | |
| b .find_end | |
| .check_newline: | |
| sub x1, x1, #1 | |
| ldrb w2, [x1] | |
| cmp w2, #10 | |
| bne .end | |
| mov w2, #0 | |
| strb w2, [x1] | |
| .end: | |
| ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment