Created
October 23, 2025 18:09
-
-
Save isopen/c00f09d643ce65e465637f812a79695b to your computer and use it in GitHub Desktop.
TDLib ARM Client in ARM32 Assembly (ARMv7)
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 ARM Client in ARM32 Assembly (ARMv7) | |
| // | |
| // https://gist.github.com/isopen/2be1547e3e98a053cbc3a26851a5ebcd | |
| // docker build -t tdlib-arm-app . | |
| // docker run -it --rm tdlib-arm-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\":\"ARMv7Client\",\"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 4 | |
| lib_handle: .skip 4 | |
| client_handle: .skip 4 | |
| // Function pointers | |
| create_func: .skip 4 | |
| send_func: .skip 4 | |
| receive_func: .skip 4 | |
| destroy_func: .skip 4 | |
| execute_func: .skip 4 | |
| // Buffers | |
| .align 4 | |
| 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: | |
| push {r4, r5, r6, r7, r8, r9, r10, fp, lr} | |
| add fp, sp, #32 | |
| // Load TDLib library | |
| ldr r0, =lib_name | |
| mov r1, #1 | |
| bl dlopen | |
| cmp r0, #0 | |
| beq .dl_error | |
| ldr r1, =lib_handle | |
| str r0, [r1] | |
| // Get function addresses | |
| ldr r0, [r1] | |
| ldr r1, =create_name | |
| bl dlsym | |
| ldr r1, =create_func | |
| str r0, [r1] | |
| ldr r0, =lib_handle | |
| ldr r0, [r0] | |
| ldr r1, =send_name | |
| bl dlsym | |
| ldr r1, =send_func | |
| str r0, [r1] | |
| ldr r0, =lib_handle | |
| ldr r0, [r0] | |
| ldr r1, =receive_name | |
| bl dlsym | |
| ldr r1, =receive_func | |
| str r0, [r1] | |
| ldr r0, =lib_handle | |
| ldr r0, [r0] | |
| ldr r1, =destroy_name | |
| bl dlsym | |
| ldr r1, =destroy_func | |
| str r0, [r1] | |
| ldr r0, =lib_handle | |
| ldr r0, [r0] | |
| ldr r1, =execute_name | |
| bl dlsym | |
| ldr r1, =execute_func | |
| str r0, [r1] | |
| // Create TDLib client | |
| ldr r0, =create_func | |
| ldr r0, [r0] | |
| blx r0 | |
| cmp r0, #0 | |
| beq .client_error | |
| ldr r1, =client_handle | |
| str r0, [r1] | |
| // Set log verbosity | |
| ldr r0, =client_handle | |
| ldr r0, [r0] | |
| ldr r1, =verbosity_msg | |
| ldr r2, =execute_func | |
| ldr r2, [r2] | |
| blx r2 | |
| // Set TDLib parameters | |
| ldr r0, =client_handle | |
| ldr r0, [r0] | |
| ldr r1, =params_msg | |
| ldr r2, =send_func | |
| ldr r2, [r2] | |
| blx r2 | |
| // Authorization loop | |
| mov r7, #0 | |
| ldr r0, =auth_state | |
| mov r1, #0 | |
| str r1, [r0] | |
| ldr r0, =#50000 | |
| bl usleep | |
| .auth_loop: | |
| ldr r0, =client_handle | |
| ldr r0, [r0] | |
| mov r1, #0 | |
| ldr r2, =receive_func | |
| ldr r2, [r2] | |
| blx r2 | |
| cmp r0, #0 | |
| beq .no_message | |
| // Process message | |
| bl process_message | |
| cmp r7, #1 | |
| beq .auth_complete | |
| .no_message: | |
| // Check if we need to request input | |
| ldr r0, =auth_state | |
| ldr r0, [r0] | |
| cmp r0, #1 // wait_phone | |
| beq .request_phone | |
| cmp r0, #2 // wait_code | |
| beq .request_code | |
| cmp r0, #3 // wait_password | |
| beq .request_password | |
| ldr r0, =#10000 | |
| bl usleep | |
| b .auth_loop | |
| .request_phone: | |
| ldr r0, =phone_prompt | |
| bl printf | |
| mov r0, #0 | |
| bl fflush | |
| // Read phone number | |
| ldr r0, =phone_buffer | |
| mov r1, #32 | |
| ldr r2, =stdin | |
| ldr r2, [r2] | |
| bl fgets | |
| cmp r0, #0 | |
| beq .input_error | |
| // Remove newline | |
| ldr r0, =phone_buffer | |
| bl remove_newline | |
| // Create JSON for phone number | |
| ldr r0, =json_buffer | |
| ldr r1, =fmt_phone | |
| ldr r2, =phone_buffer | |
| bl sprintf | |
| // Send to TDLib | |
| ldr r0, =client_handle | |
| ldr r0, [r0] | |
| ldr r1, =json_buffer | |
| ldr r2, =send_func | |
| ldr r2, [r2] | |
| blx r2 | |
| ldr r0, =auth_state | |
| mov r1, #0 | |
| str r1, [r0] | |
| ldr r0, =#10000 | |
| bl usleep | |
| b .auth_loop | |
| .request_code: | |
| ldr r0, =code_prompt | |
| bl printf | |
| mov r0, #0 | |
| bl fflush | |
| // Read code | |
| ldr r0, =code_buffer | |
| mov r1, #16 | |
| ldr r2, =stdin | |
| ldr r2, [r2] | |
| bl fgets | |
| cmp r0, #0 | |
| beq .input_error | |
| // Remove newline | |
| ldr r0, =code_buffer | |
| bl remove_newline | |
| // Create JSON for code | |
| ldr r0, =json_buffer | |
| ldr r1, =fmt_code | |
| ldr r2, =code_buffer | |
| bl sprintf | |
| // Send to TDLib | |
| ldr r0, =client_handle | |
| ldr r0, [r0] | |
| ldr r1, =json_buffer | |
| ldr r2, =send_func | |
| ldr r2, [r2] | |
| blx r2 | |
| ldr r0, =auth_state | |
| mov r1, #0 | |
| str r1, [r0] | |
| ldr r0, =#10000 | |
| bl usleep | |
| b .auth_loop | |
| .request_password: | |
| ldr r0, =password_prompt | |
| bl printf | |
| mov r0, #0 | |
| bl fflush | |
| // Read password | |
| ldr r0, =password_buffer | |
| mov r1, #64 | |
| ldr r2, =stdin | |
| ldr r2, [r2] | |
| bl fgets | |
| cmp r0, #0 | |
| beq .input_error | |
| // Remove newline | |
| ldr r0, =password_buffer | |
| bl remove_newline | |
| // Create JSON for password | |
| ldr r0, =json_buffer | |
| ldr r1, =fmt_password | |
| ldr r2, =password_buffer | |
| bl sprintf | |
| // Send to TDLib | |
| ldr r0, =client_handle | |
| ldr r0, [r0] | |
| ldr r1, =json_buffer | |
| ldr r2, =send_func | |
| ldr r2, [r2] | |
| blx r2 | |
| ldr r0, =auth_state | |
| mov r1, #0 | |
| str r1, [r0] | |
| ldr r0, =#10000 | |
| bl usleep | |
| b .auth_loop | |
| .auth_complete: | |
| ldr r0, =auth_success | |
| bl printf | |
| // Main loop | |
| mov r8, #100 | |
| .main_loop: | |
| // Receive messages | |
| ldr r0, =client_handle | |
| ldr r0, [r0] | |
| mov r1, #0 | |
| ldr r2, =receive_func | |
| ldr r2, [r2] | |
| blx r2 | |
| cmp r0, #0 | |
| beq .no_msg_main | |
| // Print message | |
| bl printf | |
| ldr r0, =newline | |
| bl printf | |
| .no_msg_main: | |
| ldr r0, =#50000 | |
| bl usleep | |
| subs r8, r8, #1 | |
| bne .main_loop | |
| .cleanup: | |
| // Send close command | |
| ldr r0, =client_handle | |
| ldr r0, [r0] | |
| ldr r1, =close_msg | |
| ldr r2, =send_func | |
| ldr r2, [r2] | |
| blx r2 | |
| ldr r0, =#50000 | |
| bl usleep | |
| // Destroy client | |
| ldr r0, =client_handle | |
| ldr r0, [r0] | |
| ldr r1, =destroy_func | |
| ldr r1, [r1] | |
| blx r1 | |
| // Exit | |
| mov r0, #0 | |
| bl exit | |
| .dl_error: | |
| ldr r0, =lib_error | |
| bl printf | |
| mov r0, #1 | |
| bl exit | |
| .client_error: | |
| ldr r0, =client_error | |
| bl printf | |
| b .cleanup | |
| .input_error: | |
| ldr r0, =input_error | |
| bl printf | |
| b .cleanup | |
| process_message: | |
| push {r4, r5, r6, r7, r8, lr} | |
| mov r4, r0 | |
| ldr r1, =auth_wait_phone | |
| bl strstr | |
| cmp r0, #0 | |
| bne .wait_phone | |
| mov r0, r4 | |
| ldr r1, =auth_wait_code | |
| bl strstr | |
| cmp r0, #0 | |
| bne .wait_code | |
| mov r0, r4 | |
| ldr r1, =auth_wait_password | |
| bl strstr | |
| cmp r0, #0 | |
| bne .wait_password | |
| mov r0, r4 | |
| ldr r1, =auth_ready | |
| bl strstr | |
| cmp r0, #0 | |
| bne .auth_ready | |
| b .done | |
| .wait_phone: | |
| ldr r0, =auth_state | |
| mov r1, #1 | |
| str r1, [r0] | |
| b .done | |
| .wait_code: | |
| ldr r0, =auth_state | |
| mov r1, #2 | |
| str r1, [r0] | |
| b .done | |
| .wait_password: | |
| ldr r0, =auth_state | |
| mov r1, #3 | |
| str r1, [r0] | |
| b .done | |
| .auth_ready: | |
| mov r7, #1 | |
| ldr r0, =auth_state | |
| mov r1, #0 | |
| str r1, [r0] | |
| .done: | |
| pop {r4, r5, r6, r7, r8, pc} | |
| remove_newline: | |
| mov r1, r0 | |
| .find_end: | |
| ldrb r2, [r1] | |
| cmp r2, #0 | |
| beq .check_newline | |
| add r1, r1, #1 | |
| b .find_end | |
| .check_newline: | |
| sub r1, r1, #1 | |
| ldrb r2, [r1] | |
| cmp r2, #10 | |
| bne .end | |
| mov r2, #0 | |
| strb r2, [r1] | |
| .end: | |
| bx lr |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment