Buenos días. Nos encontramos ante un reto de reversing bastante sencillo e ideal para comenzar. El CTF terminó apenas una hora y participe con el equipo PKTeam. Para la resolución del reto use radare2 para debuggear el binario y Hopper para ver el pseudocódigo. Del mismo modo si ustedes quieren practicar este reto pueden pedírmelo por privado en Telegram @naivenom o descargarlo directamente de la página del CTF pero desconozco la disponibilidad que tendrá la web. https://teaser.insomnihack.ch/challenges/
Análisis de la función beginer_reverse
Antes de comenzar recomiendo que echéis un ojo a la función desensamblada al final de la entrada a la misma vez que se ven instrucción por instrucción. En la función main vemos como se le pasa la dirección de una función al registro rcx.
[0x5631bdca8b10]> pd
;-- main:
0x5631bdca8b10 50 push rax
0x5631bdca8b11 4889f0 mov rax, rsi
0x5631bdca8b14 4863d7 movsxd rdx, edi
0x5631bdca8b17 488d0d82fbff. lea rcx, sym.beginer_reverse::main::h80fa15281f646bc1 ; 0x5631bdca86a0 ; "UAWAVAUATSH\x81\xec\x88"
0x5631bdca8b1e 48890c24 mov qword [rsp], rcx
Como reversers nos interesa ver el punto de entrada de la iteración como usuarios de la aplicación. Para ello rápidamente dentro de la función localizamos la llamada que leerá de nuestro input los bytes introducidos.
0x55c41831d769 e802a10000 call sym.std::io::stdio::Stdin::read_line::h85c3421ca914511e ;[1]
En esta instrucción nos pide un input como usuario. Introducimos: AAAA
0x55c41831d76e 48837c245801 cmp qword [rsp + 0x58], 1
Seguidamente compara el valor del stack con 1. Vemos lo que contiene:
[0x55c41831d6c0]> px@rsp+0x58
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x7ffc4817bdd8 0000 0000 0000 0000 0500 0000 0000 0000 ................
Contiene 0x0.
Por lo tanto no saltará en la instrucción siguiente JE.
0x55c41831d77a 488b0424 mov rax, qword [rsp]
En esta instruccion se mueve el contenido del registro rsp. rsp contiene un puntero por tanto el valor del registro rax será el contenido del puntero. Es decir, rax ahora contiene 0x2.
0x55c41831d77e f04881280100. lock sub qword [rax], 1
Después de esta instruccion rax vale 0x1.
En nuestro caso de input saltará con la siguiente instrucción JNE.
0x55c41831d790 4c8b6c2408 mov r13, qword [rsp + 8]
Mueve el contenido del stack en el registro r13.
[0x55c41831d795]> px@r13
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D 0123456789ABCD
0x7f9ba7a20018 4141 4141 0a00 0000 0000 0000 0000 AAAA..........
0x55c41831d795 488b442418 mov rax, qword [rsp + 0x18]
Mueve a rax el valor del stack, en este caso 0x5 debido a que introducimos 5 bytes las A y el salto de linea.
0x55c41831d79a 4885c0 test rax, rax
Ahora hace la instrucción test, y como no es 0x0 no saltará en la siguiente instrucción JE. La hipótesis es que no tiene que saltar porque se presupone que tiene que existir un input por parte del usuario de la aplicación y siempre se cuenta con el salto de linea en este caso.
0x55ac9742679f 4a8d0c28 lea rcx, [rax + r13]
Ahora mueve una dirección de memoria al registro rcx. La resultante es la suma del contenido de rax=0x5 + la direccion de memoria que contiene el registro r13.
[0x55ac974267a3]> px@rax+r13
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x7fc66802001d 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x7fc66802002d 0000 0000 0000 0000 0000 0000 0000 0000 ................
[0x55ac974267a3]> px@rcx
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x7fc66802001d 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x7fc66802002d 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x55ac974267a3 0fb651ff movzx edx, byte [rcx - 1]
Mueve a edx:0xa que corresponde al salto de linea.
0x55ac974267a7 41b801000000 mov r8d, 1
Mueve el valor 0x1 a r8.
0x55ac974267ad 84d2 test dl, dl
Como el valor del registro dl no es 0x0 no saltará en la siguiente instrucción JS. Sabiendo que coge el último valor si queremos que salte deberíamos de introducir el input con un script seteando el ultimo valor a NULL o 0x0.
0x55ac974267b1 4c29c0 sub rax, r8
Le resta 1 al registro rax quedando ahora como 0x4.
0x55ac974267b4 4889442418 mov qword [rsp + 0x18], rax
Lo mueve al stack
0x55ac974267b9 4a8d0c28 lea rcx, [rax + r13]
En rcx ahora tenemos.
[0x55ac974267a3]> px@rcx
- offset - 0 1 2 3 4 5 6 7 8 9 A 0123456789A
0x7fc66802001c 0a00 0000 0000 0000 0000 00 ...........
El valor del salto de linea, o el ultimo valor de lo introducido por input.
0x55ac9742683e 48c744242004. mov qword [rsp + 0x20], 4
0x55ac97426847 0f57c0 xorps xmm0, xmm0
0x55ac9742684a 0f11442428 movups xmmword [rsp + 0x28], xmm0
0x55ac9742684f 4885c0 test rax, rax
Se mueve al stack el valor de 4.
[0x55ac97426822]> px@rsp+0x20
- offset - 0 1 2 3 4 5 6 7 8 9 A 0123456789A
0x7ffc62509b80 04
[0x55ac97426822]> px@rsp+0x28
- offset - 0 1 2 3 4 5 6 7 8 9 A 0123456789A
0x7ffc62509b88 0000 0000 0000 0000 0000 00 ...........
0x7ffc62509b93 0000 0000 0096 a618 69c6 7f ........i..
Por último hace un test rax,rax pero resulta que rax es 0x4 por lo tanto no saltará en la siguiente instrucción JE.
0x55ac97426858 4c29e9 sub rcx, r13
Deja el registro rcx como 0x4.
0x55ac9742685d 41be04000000 mov r14d, 4
0x55ac97426863 bf04000000 mov edi, 4
0x55ac97426868 31ed xor ebp, ebp
0x55ac9742686a 48894c2438 mov qword [rsp + 0x38], rcx
0x55ac9742686f 90 nop
Mueve a esos registros el valor de 0x4 y por último mueve el 0x4 del registro rcx al stack.
0x55ac97426870 450fb6642d00 movzx r12d, byte [r13 + rbp]
0x55ac97426876 4889f3 mov rbx, rsi
0x55ac97426879 4839f5 cmp rbp, rsi
0x55ac9742687c 757f jne 0x55ac974268fd
Mueve al registro r12 el primer valor de nuestro input siendo 0x41. Seguidamente mueve el valor de rsi a rbx quedando como 0x0 y por último compara el valor de rbp=0x0 con rsi=0x0. En este caso no va a saltar en la siguiente instruccion JNE ya que es cero y son iguales.
0x55ac9742687e 4883c301 add rbx, 1
Le suma uno a rbx. ¿Posible contador?. En la siguiente instrucción JB no salta. Salta si está abajo o salta si no está arriba o si no es igual.
0x55ac97426888 488d0436 lea rax, [rsi + rsi]
Deja a rax como 0x0.
0x55ac9742688c 4839c3 cmp rbx, rax
Compara el valor de rbx=0x1 con rax=0x0.
0x55ac97426893 4889d8 mov rax, rbx
0x55ac97426896 ba04000000 mov edx, 4
El valor de rax es igual ahora a 0x1. Y el valor de rdx es 0x4.
0x55ac9742689b 48f7e2 mul rdx
Después de esta instrucción el valor de rax=0x4 y el valor de rdx=0x0. En la siguiente instrucción JO no salta. Salta si hay desbordamiento (overflow).
0x55b3e50c18a4 4989c7 mov r15, rax
0x55b3e50c18a7 4885f6 test rsi, rsi
0x55b3e50c18aa 7423 je 0x55b3e50c18cf
El valor de r15 ahora es 0x4. Seguidamente como rsi es igual a 0x0 va a tomar el salto JE.
0x55b3e50c18cf be04000000 mov esi, 4
0x55b3e50c18d4 4c89ff mov rdi, r15
0x55b3e50c18d7 e874050000 call sym.__rust_alloc
0x55b3e50c18dc 4989c6 mov r14, rax
0x55b3e50c18df 4885c0 test rax, rax
0x55b3e50c18e2 488b4c2438 mov rcx, qword [rsp + 0x38] ; [0x38:8]=-1 ; '8' ; 56
Mueve a esi el valor de 4 y se mueve a rdi el valor del registro r15.
Después de la llamada a la función los valores de retorno están en los registros rax y rdx.
[0x55b3e50c18cf]> px@rax
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x7efe78620020 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x7efe78620030 0000 0000 0000 0000 0000 0000 0000 0000 ................
[0x55b3e50c18cf]> px@rdx
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x7efe7860db88 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x7efe7860db98 0000 0000 0000 0000 0000 0000 0000 0000 ................
Seguidamente se mueve al registro r14 el valor de rax. Hace un test rax,rax y luego mueve al registro rcx el valor del stack siendo 0x4.
Como rax contiene una dirección de memoria y no el valor 0x0 no toma el salto JE.
0x55b3e50c18ed 4c89742420 mov qword [rsp + 0x20], r14
0x55b3e50c18f2 48895c2428 mov qword [rsp + 0x28], rbx
Mueve al stack los contenidos de ambos registros.
0x55b3e50c18fd 458924ae mov dword [r14 + rbp*4], r12d
0x55b3e50c1901 4883c501 add rbp, 1
Mueve el valor de r12 a r14. En este punto tenemos que rbp=0x0. Después de ejecutarse la instrucción.
[0x55b3e50c1901]> px@r14
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E 0123456789ABCDE
0x7efe78620020 4100 0000 0000 0000 0000 0000 0000 00 A..............
Seguidamente le suma uno a rbp quedando rbp como=0x1.
0x55b3e50c1905 48896c2430 mov qword [rsp + 0x30], rbp
0x55b3e50c190a 4839e9 cmp rcx, rbp
Mueve el valor al stack y luego compara el valor de rcx=0x4 con el valor rbp. Como no son iguales saltara en el JNE.
0x55b3e50c1870 450fb6642d00 movzx r12d, byte [r13 + rbp]
0x55b3e50c1876 4889f3 mov rbx, rsi
0x55b3e50c1879 4839f5 cmp rbp, rsi
Ahora mueve el siguiente byte 0x41 o segunda A ya que el registro rbp=0x1.
[0x55b3e50c1870]> px@0x7efe78620019
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E 0123456789ABCDE
0x7efe78620019 4141 410a 0000 0041 0000 0000 0000 00 AAA....A.......
Finalmente compara el valor de rbp=0x1 con rsi=0x1. Como es igual no tomara el salto JNE.
0x55b3e50c187e 4883c301 add rbx, 1
Le suma 1 a rbx. Y no toma el salto JB.
0x55b3e50c1888 488d0436 lea rax, [rsi + rsi]
0x55b3e50c188c 4839c3 cmp rbx, rax
0x55b3e50c188f 480f42d8 cmovb rbx, rax
0x55b3e50c1893 4889d8 mov rax, rbx
0x55b3e50c1896 ba04000000 mov edx, 4
0x55b3e50c189b 48f7e2 mul rdx
Mismas instrucciones que lo visto anteriormente. Ahora al terminar el valor de rax=0x8 y el valor de rdx=0x0. No toma el salto JO de overflow.
0x55b3e50c18a4 4989c7 mov r15, rax
Mueve a r15 el valor del registro rax=0x8. Ahora hace test rsi, rsi pero como rsi=0x1 en la instrucción JE no saltara.
0x55b3e50c18ac 48c1e602 shl rsi, 2
0x55b3e50c18b0 ba04000000 mov edx, 4
0x55b3e50c18b5 4c89f9 mov rcx, r15
0x55b3e50c18b8 e8b3050000 call sym.__rust_realloc
Después de la primera instrucción rsi vale ahora=0x4 y rcx vale ahora=0x8. El valor de retorno de la función cuando se llama son los siguientes:
[0x55b3e50c18bd]> 1px@rax
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E 0123456789ABCDE
0x7efe78620020 4100 0000 0000 0000 0000 0000 0000 00 A..............
[0x55b3e50c18bd]> 1px@rdx
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E 0123456789ABCDE
0x55b3e5125118 0d00 0000 0000 0000 0000 1c00 0000 00 ...............
[0x55b3e50c18bd]> 1px@rcx
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E 0123456789ABCDE
0x55b3e510f900 0800 0000 0000 0000 1000 0000 0000 00 ...............
0x55b3e510f90f 0020 0000 0000 0000 0030 0000 0000 00 . .......0.....
0x55b3e50c18fd 458924ae mov dword [r14 + rbp*4], r12d
Otra vez estamos en esta instrucción pero ya sabemos que ahora con rbp=0x1 la cosa cambia y después de ejecutar tenemos nuestro 0x41 en esa dirección de memoria.
[0x55b3e50c18ed]> px@r14 + rbp*4
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E 0123456789ABCDE
0x7efe78620024 4100 0000 0000 0000 0000 0000 0000 00 A..............
Simulando rbp como 0x0 anteriormente visto:
[0x55b3e50c18ed]> px@r14 + 0*4
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E 0123456789ABCDE
0x7efe78620020 4100 0000 4100 0000 0000 0000 0000 00 A...A..........
0x55b3e50c1901 4883c501 add rbp, 1
Le suma uno a rbp.
Ahora otra vez va a realizar lo mismo en el bucle por lo tanto, en la siguiente iteración simulamos de nuevo rbp como 0x0 y vemos nuestro tercer byte que introdujimos 0x41.
[0x55b3e50c18f7]> px@r14 + 0*4
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E 0123456789ABCDE
0x7efe7862e010 4100 0000 4100 0000 4100 0000 0000 00 A...A...A......
Y ultima iteración.
[0x55b3e50c18fd]> px@r14 + 0*4
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E 0123456789ABCDE
0x7efe7862e010 4100 0000 4100 0000 4100 0000 4100 00 A...A...A...A..
Seguimos debuggeando y nos localizamos en otra parte del código.
0x55b3e50c191f 488d04ad0000. lea rax, [rbp*4]
0x55b3e50c1927 31c9 xor ecx, ecx
0x55b3e50c1929 0f1f80000000. nop dword [rax]
0x55b3e50c1930 4839c8 cmp rax, rcx
Le pasa a rax=0x10, es decir, 0x4*0x4. En la comparación no es igual por lo tanto no tomara el salto JE.
0x55b3e50c1935 418b140e mov edx, dword [r14 + rcx]
0x55b3e50c1939 83c2e0 add edx, 0xffffffffffffffe0
0x55b3e50c193c 4883c104 add rcx, 4
0x55b3e50c1940 83fa5f cmp edx, 0x5f ; '_' ; 95
0x55b3e50c1943 72eb jb 0x55b3e50c1930
Se mueve a rdx el valor primero 0x41 y luego se le suma quedando como 0x21. Seguidamente se le suma a rcx el valor de 4 quedando como:0x4 y finalmente se compara con 0x5f el valor de rdx que era 0x21. En el siguiente salto JB saltará. Salta si está abajo o salta si no está arriba o si no es igual.
0x55b3e50c1930 4839c8 cmp rax, rcx
Tras unas iteraciones ahora es igual estos registros por lo tanto saltará en el JE.
0x557d73c8a962 4c8b7c2440 mov r15, qword [rsp + 0x40]
Ahora andamos en esta localización en el código y le pasa el valor del stack a r15.
[0x557d73c8a930]> px@r15
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x7f5012229000 0e01 0000 1201 0000 6601 0000 c601 0000 ........f.......
0x557d73c8a967 4c8b442450 mov r8, qword [rsp + 0x50]
El valor de r8 ahora es 0x22.
0x557d73c8a96c 4c39c5 cmp rbp, r8
0x557d73c8a96f 490f47e8 cmova rbp, r8
0x557d73c8a973 4885ed test rbp, rbp
En la comparación compara rbp=0x4 con r8=0x22. Como rbp es distinto a 0x0 no saltará en el siguiente JE. En las siguientes intrucciones xorea algunos registros para dejarlos a cero.
0x557d73c8a980 4939d6 cmp r14, rdx
En esta instrucción compara r14 con rdx.
[0x557d73c8a973]> 1px@r14
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x7f501222e010 4100 0000 4100 0000 4100 0000 4100 0000 A...A...A...A...
rdx=0x0.
No realiza el salto lógicamente porque no es lo mismo en la siguiente instrucción JE.
0x557d73c8a985 418b3cb7 mov edi, dword [r15 + rsi*4]
0x557d73c8a989 c1ff02 sar edi, 2
0x557d73c8a98c 83f70a xor edi, 0xa
0x557d73c8a98f 31c0 xor eax, eax
0x557d73c8a991 413b3cb6 cmp edi, dword [r14 + rsi*4]
0x557d73c8a995 488d7601 lea rsi, [rsi + 1] ; 1
0x557d73c8a999 0f94c0 sete al
0x557d73c8a99c 4801c1 add rcx, rax ; '#'
0x557d73c8a99f 4883c2fc add rdx, 0xfffffffffffffffc
0x557d73c8a9a3 4839ee cmp rsi, rbp
0x557d73c8a9a6 72d8 jb 0x557d73c8a980
1. En la primera instrucción se le pasa al registro edi=0x10e.
2. Luego se convierte con la instrucción sar el registro edi=0x43.
3. Se xorea con 0xa el registro edi, quedando como=0x49.
4. En la comparacion se compara el valor existente en r14+rsi*4 y el registro edi. Vemos en cada uno de ellos.
En edi=0x49.
[0x557d73c8a97c]> px@r14
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E 0123456789ABCDE
0x7f501222e010 4100 0000 4100 0000 4100 0000 4100 00 A...A...A...A..
Compara 0x49 con 0x41. 0x49 en ascii es una «I» que puede corresponder al formato de la flag «INS{}». Por tanto ya encontramos la parte del código que nos interesa para resolver el reto.
Flag:
INS{y0ur_a_r3a1_h4rdc0r3_r3v3rs3r}
Función beginer_reverse desensamblada
[0x5631bdca86a0]> pd 300
;-- beginer_reverse::main::h80fa15281f646bc1:
0x5631bdca86a0 55 push rbp
0x5631bdca86a1 4157 push r15
0x5631bdca86a3 4156 push r14
0x5631bdca86a5 4155 push r13
0x5631bdca86a7 4154 push r12
0x5631bdca86a9 53 push rbx
0x5631bdca86aa 4881ec880000. sub rsp, 0x88
0x5631bdca86b1 bf88000000 mov edi, 0x88 ; 136
0x5631bdca86b6 be04000000 mov esi, 4
0x5631bdca86bb e890070000 call sym.__rust_alloc
0x5631bdca86c0 4885c0 test rax, rax
,=< 0x5631bdca86c3 0f84d5030000 je 0x5631bdca8a9e
| 0x5631bdca86c9 0f280530a904. movaps xmm0, xmmword map.home_naivenom_ctf_beginner_reverse.r ; [0x5631bdcf3000:16]=-1
| 0x5631bdca86d0 0f1100 movups xmmword [rax], xmm0
| 0x5631bdca86d3 0f280536a904. movaps xmm0, xmmword [0x5631bdcf3010] ; [0x5631bdcf3010:16]=-1
| 0x5631bdca86da 0f114010 movups xmmword [rax + 0x10], xmm0
| 0x5631bdca86de 0f28053ba904. movaps xmm0, xmmword [0x5631bdcf3020] ; [0x5631bdcf3020:16]=-1
| 0x5631bdca86e5 0f114020 movups xmmword [rax + 0x20], xmm0
| 0x5631bdca86e9 0f280540a904. movaps xmm0, xmmword [0x5631bdcf3030] ; [0x5631bdcf3030:16]=-1
| 0x5631bdca86f0 0f114030 movups xmmword [rax + 0x30], xmm0
| 0x5631bdca86f4 0f280545a904. movaps xmm0, xmmword [0x5631bdcf3040] ; [0x5631bdcf3040:16]=-1
| 0x5631bdca86fb 0f114040 movups xmmword [rax + 0x40], xmm0
| 0x5631bdca86ff 0f28054aa904. movaps xmm0, xmmword [0x5631bdcf3050] ; [0x5631bdcf3050:16]=-1
| 0x5631bdca8706 0f114050 movups xmmword [rax + 0x50], xmm0
| 0x5631bdca870a 0f28054fa904. movaps xmm0, xmmword [0x5631bdcf3060] ; [0x5631bdcf3060:16]=-1
| 0x5631bdca8711 0f114060 movups xmmword [rax + 0x60], xmm0
| 0x5631bdca8715 0f280554a904. movaps xmm0, xmmword [0x5631bdcf3070] ; [0x5631bdcf3070:16]=-1
| 0x5631bdca871c 0f114070 movups xmmword [rax + 0x70], xmm0
| 0x5631bdca8720 48b9e2010000. movabs rcx, 0x1de000001e2 ; 2052994367970
| 0x5631bdca872a 488988800000. mov qword [rax + 0x80], rcx
| 0x5631bdca8731 4889442440 mov qword [rsp + 0x40], rax
| 0x5631bdca8736 0f280543a904. movaps xmm0, xmmword [0x5631bdcf3080] ; [0x5631bdcf3080:16]=-1
| 0x5631bdca873d 0f11442448 movups xmmword [rsp + 0x48], xmm0
| 0x5631bdca8742 48c744240801. mov qword [rsp + 8], 1
| 0x5631bdca874b 0f57c0 xorps xmm0, xmm0
| 0x5631bdca874e 0f11442410 movups xmmword [rsp + 0x10], xmm0
| 0x5631bdca8753 e8d89f0000 call sym.std::io::stdio::stdin::hcd3fd1740d5196a7
| 0x5631bdca8758 48890424 mov qword [rsp], rax
| 0x5631bdca875c 488d7c2458 lea rdi, [rsp + 0x58] ; 'X' ; 88
| 0x5631bdca8761 4889e6 mov rsi, rsp
| 0x5631bdca8764 488d542408 lea rdx, [rsp + 8] ; 8
| 0x5631bdca8769 e802a10000 call sym.std::io::stdio::Stdin::read_line::h85c3421ca914511e
| 0x5631bdca876e 48837c245801 cmp qword [rsp + 0x58], 1 ; [0x58:8]=-1 ; 'X' ; 1
,==< 0x5631bdca8774 0f8435030000 je 0x5631bdca8aaf
|| 0x5631bdca877a 488b0424 mov rax, qword [rsp]
|| 0x5631bdca877e f04881280100. lock sub qword [rax], 1
,===< 0x5631bdca8786 7508 jne 0x5631bdca8790
||| 0x5631bdca8788 4889e7 mov rdi, rsp
||| 0x5631bdca878b e830060000 call sym._alloc::sync::Arc_T__::drop_slow::h82dbb96617da66a0
`---> 0x5631bdca8790 4c8b6c2408 mov r13, qword [rsp + 8] ; [0x8:8]=-1 ; 8
|| 0x5631bdca8795 488b442418 mov rax, qword [rsp + 0x18] ; [0x18:8]=-1 ; 24
|| 0x5631bdca879a 4885c0 test rax, rax
,===< 0x5631bdca879d 7420 je 0x5631bdca87bf
||| 0x5631bdca879f 4a8d0c28 lea rcx, [rax + r13]
||| 0x5631bdca87a3 0fb651ff movzx edx, byte [rcx - 1]
||| 0x5631bdca87a7 41b801000000 mov r8d, 1
||| 0x5631bdca87ad 84d2 test dl, dl
||| 0x5631bdca87af 7815 js 0x5631bdca87c6
||| 0x5631bdca87b1 4c29c0 sub rax, r8
||| 0x5631bdca87b4 4889442418 mov qword [rsp + 0x18], rax
||| 0x5631bdca87b9 4a8d0c28 lea rcx, [rax + r13]
||| 0x5631bdca87bd eb7f jmp 0x5631bdca883e
`---> 0x5631bdca87bf 31c0 xor eax, eax
|| 0x5631bdca87c1 4c89e9 mov rcx, r13
|| 0x5631bdca87c4 eb78 jmp 0x5631bdca883e
|| 0x5631bdca87c6 488d71ff lea rsi, [rcx - 1]
|| 0x5631bdca87ca 4939f5 cmp r13, rsi
|| 0x5631bdca87cd 743a je 0x5631bdca8809
|| 0x5631bdca87cf 0fb671fe movzx esi, byte [rcx - 2]
|| 0x5631bdca87d3 89f3 mov ebx, esi
|| 0x5631bdca87d5 80e3c0 and bl, 0xc0
|| 0x5631bdca87d8 80fb80 cmp bl, 0x80 ; 128
|| 0x5631bdca87db 7530 jne 0x5631bdca880d
|| 0x5631bdca87dd 488d79fe lea rdi, [rcx - 2]
|| 0x5631bdca87e1 4939fd cmp r13, rdi
|| 0x5631bdca87e4 742c je 0x5631bdca8812
|| 0x5631bdca87e6 0fb679fd movzx edi, byte [rcx - 3]
|| 0x5631bdca87ea 89fb mov ebx, edi
|| 0x5631bdca87ec 80e3c0 and bl, 0xc0
|| 0x5631bdca87ef 80fb80 cmp bl, 0x80 ; 128
|| 0x5631bdca87f2 7522 jne 0x5631bdca8816
|| 0x5631bdca87f4 488d69fd lea rbp, [rcx - 3]
|| 0x5631bdca87f8 4939ed cmp r13, rbp
|| 0x5631bdca87fb 741e je 0x5631bdca881b
|| 0x5631bdca87fd 0fb669fc movzx ebp, byte [rcx - 4]
|| 0x5631bdca8801 83e507 and ebp, 7
|| 0x5631bdca8804 c1e506 shl ebp, 6
|| 0x5631bdca8807 eb14 jmp 0x5631bdca881d
|| 0x5631bdca8809 31f6 xor esi, esi
|| 0x5631bdca880b eb1d jmp 0x5631bdca882a
|| 0x5631bdca880d 83e61f and esi, 0x1f
|| 0x5631bdca8810 eb18 jmp 0x5631bdca882a
|| 0x5631bdca8812 31ff xor edi, edi
|| 0x5631bdca8814 eb0c jmp 0x5631bdca8822
|| 0x5631bdca8816 83e70f and edi, 0xf
|| 0x5631bdca8819 eb07 jmp 0x5631bdca8822
|| 0x5631bdca881b 31ed xor ebp, ebp
|| 0x5631bdca881d 83e73f and edi, 0x3f
|| 0x5631bdca8820 09ef or edi, ebp
|| 0x5631bdca8822 c1e706 shl edi, 6
|| 0x5631bdca8825 83e63f and esi, 0x3f
|| 0x5631bdca8828 09fe or esi, edi
|| 0x5631bdca882a c1e606 shl esi, 6
|| 0x5631bdca882d 83e23f and edx, 0x3f
|| 0x5631bdca8830 09f2 or edx, esi
|| 0x5631bdca8832 81fa00001100 cmp edx, 0x110000
|| 0x5631bdca8838 0f8517020000 jne 0x5631bdca8a55
|| 0x5631bdca883e 48c744242004. mov qword [rsp + 0x20], 4
|| 0x5631bdca8847 0f57c0 xorps xmm0, xmm0
|| 0x5631bdca884a 0f11442428 movups xmmword [rsp + 0x28], xmm0
|| 0x5631bdca884f 4885c0 test rax, rax
|| 0x5631bdca8852 0f84bd000000 je 0x5631bdca8915
|| 0x5631bdca8858 4c29e9 sub rcx, r13
|| 0x5631bdca885b 31f6 xor esi, esi
|| 0x5631bdca885d 41be04000000 mov r14d, 4
|| 0x5631bdca8863 bf04000000 mov edi, 4
|| 0x5631bdca8868 31ed xor ebp, ebp
|| 0x5631bdca886a 48894c2438 mov qword [rsp + 0x38], rcx
|| 0x5631bdca886f 90 nop
|| 0x5631bdca8870 450fb6642d00 movzx r12d, byte [r13 + rbp]
|| 0x5631bdca8876 4889f3 mov rbx, rsi
|| 0x5631bdca8879 4839f5 cmp rbp, rsi
|| 0x5631bdca887c 757f jne 0x5631bdca88fd
|| 0x5631bdca887e 4883c301 add rbx, 1
|| 0x5631bdca8882 0f8200020000 jb 0x5631bdca8a88
|| 0x5631bdca8888 488d0436 lea rax, [rsi + rsi]
|| 0x5631bdca888c 4839c3 cmp rbx, rax
|| 0x5631bdca888f 480f42d8 cmovb rbx, rax
|| 0x5631bdca8893 4889d8 mov rax, rbx
|| 0x5631bdca8896 ba04000000 mov edx, 4
|| 0x5631bdca889b 48f7e2 mul rdx
|| 0x5631bdca889e 0f80e4010000 jo 0x5631bdca8a88
|| 0x5631bdca88a4 4989c7 mov r15, rax
|| 0x5631bdca88a7 4885f6 test rsi, rsi
|| 0x5631bdca88aa 7423 je 0x5631bdca88cf
|| 0x5631bdca88ac 48c1e602 shl rsi, 2
|| 0x5631bdca88b0 ba04000000 mov edx, 4
|| 0x5631bdca88b5 4c89f9 mov rcx, r15
|| 0x5631bdca88b8 e8b3050000 call sym.__rust_realloc
|| 0x5631bdca88bd 4989c6 mov r14, rax
|| 0x5631bdca88c0 4885c0 test rax, rax
|| 0x5631bdca88c3 488b4c2438 mov rcx, qword [rsp + 0x38] ; [0x38:8]=-1 ; '8' ; 56
|| 0x5631bdca88c8 7523 jne 0x5631bdca88ed
|| 0x5631bdca88ca e9c0010000 jmp 0x5631bdca8a8f
|| 0x5631bdca88cf be04000000 mov esi, 4
|| 0x5631bdca88d4 4c89ff mov rdi, r15
|| 0x5631bdca88d7 e874050000 call sym.__rust_alloc
|| 0x5631bdca88dc 4989c6 mov r14, rax
|| 0x5631bdca88df 4885c0 test rax, rax
|| 0x5631bdca88e2 488b4c2438 mov rcx, qword [rsp + 0x38] ; [0x38:8]=-1 ; '8' ; 56
|| 0x5631bdca88e7 0f84a2010000 je 0x5631bdca8a8f
|| 0x5631bdca88ed 4c89742420 mov qword [rsp + 0x20], r14
|| 0x5631bdca88f2 48895c2428 mov qword [rsp + 0x28], rbx
|| 0x5631bdca88f7 4c89f7 mov rdi, r14
|| 0x5631bdca88fa 4889de mov rsi, rbx
|| 0x5631bdca88fd 458924ae mov dword [r14 + rbp*4], r12d
|| 0x5631bdca8901 4883c501 add rbp, 1
|| 0x5631bdca8905 48896c2430 mov qword [rsp + 0x30], rbp
|| 0x5631bdca890a 4839e9 cmp rcx, rbp
|| 0x5631bdca890d 0f855dffffff jne 0x5631bdca8870
|| 0x5631bdca8913 eb0a jmp 0x5631bdca891f
|| 0x5631bdca8915 41be04000000 mov r14d, 4
|| 0x5631bdca891b 31db xor ebx, ebx
|| 0x5631bdca891d 31ed xor ebp, ebp
|| 0x5631bdca891f 488d04ad0000. lea rax, [rbp*4]
|| 0x5631bdca8927 31c9 xor ecx, ecx
|| 0x5631bdca8929 0f1f80000000. nop dword [rax]
|| 0x5631bdca8930 4839c8 cmp rax, rcx
|| 0x5631bdca8933 742d je 0x5631bdca8962
|| 0x5631bdca8935 418b140e mov edx, dword [r14 + rcx]
|| 0x5631bdca8939 83c2e0 add edx, 0xffffffffffffffe0
|| 0x5631bdca893c 4883c104 add rcx, 4
|| 0x5631bdca8940 83fa5f cmp edx, 0x5f ; '_' ; 95
|| 0x5631bdca8943 72eb jb 0x5631bdca8930
|| 0x5631bdca8945 488d3d44a704. lea rdi, [0x5631bdcf3090] ; "an error occuredSubmit this and get you'r points!\n"
|| 0x5631bdca894c 488d15bde505. lea rdx, str.src_main.rsError_reading_input: ; 0x5631bdd06f10
|| 0x5631bdca8953 be10000000 mov esi, 0x10 ; 16
|| 0x5631bdca8958 e833020000 call sym.std::panicking::begin_panic::h770c088eb8f42530
|| 0x5631bdca895d e92b010000 jmp 0x5631bdca8a8d
|| 0x5631bdca8962 4c8b7c2440 mov r15, qword [rsp + 0x40] ; [0x40:8]=-1 ; '@' ; 64
|| 0x5631bdca8967 4c8b442450 mov r8, qword [rsp + 0x50] ; [0x50:8]=-1 ; 'P' ; 80
|| 0x5631bdca896c 4c39c5 cmp rbp, r8
|| 0x5631bdca896f 490f47e8 cmova rbp, r8
|| 0x5631bdca8973 4885ed test rbp, rbp
|| 0x5631bdca8976 7437 je 0x5631bdca89af
|| 0x5631bdca8978 31d2 xor edx, edx
|| 0x5631bdca897a 31f6 xor esi, esi
|| 0x5631bdca897c 31c9 xor ecx, ecx
|| 0x5631bdca897e 6690 nop
|| 0x5631bdca8980 4939d6 cmp r14, rdx
|| 0x5631bdca8983 7423 je 0x5631bdca89a8
|| 0x5631bdca8985 418b3cb7 mov edi, dword [r15 + rsi*4]
|| 0x5631bdca8989 c1ff02 sar edi, 2
|| 0x5631bdca898c 83f70a xor edi, 0xa
|| 0x5631bdca898f 31c0 xor eax, eax
|| 0x5631bdca8991 413b3cb6 cmp edi, dword [r14 + rsi*4]
|| 0x5631bdca8995 488d7601 lea rsi, [rsi + 1] ; 1
|| 0x5631bdca8999 0f94c0 sete al
|| 0x5631bdca899c 4801c1 add rcx, rax ; '#'
|| 0x5631bdca899f 4883c2fc add rdx, 0xfffffffffffffffc
|| 0x5631bdca89a3 4839ee cmp rsi, rbp
|| 0x5631bdca89a6 72d8 jb 0x5631bdca8980
|| 0x5631bdca89a8 4c39c1 cmp rcx, r8
|| 0x5631bdca89ab 7409 je 0x5631bdca89b6
|| 0x5631bdca89ad eb47 jmp 0x5631bdca89f6
|| 0x5631bdca89af 31c9 xor ecx, ecx
|| 0x5631bdca89b1 4c39c1 cmp rcx, r8
|| 0x5631bdca89b4 7540 jne 0x5631bdca89f6
|| 0x5631bdca89b6 488d0543e505. lea rax, [0x5631bdd06f00] ; section..data.rel.ro
|| 0x5631bdca89bd 4889442458 mov qword [rsp + 0x58], rax
|| 0x5631bdca89c2 48c744246001. mov qword [rsp + 0x60], 1
|| 0x5631bdca89cb 48c744246800. mov qword [rsp + 0x68], 0
|| 0x5631bdca89d4 488d05eda604. lea rax, [0x5631bdcf30c8]
|| 0x5631bdca89db 4889442478 mov qword [rsp + 0x78], rax
|| 0x5631bdca89e0 48c784248000. mov qword [rsp + 0x80], 0
|| 0x5631bdca89ec 488d7c2458 lea rdi, [rsp + 0x58] ; 'X' ; 88
|| 0x5631bdca89f1 e88aa30000 call sym.std::io::stdio::_print::h77f73d11755d3bb8
|| 0x5631bdca89f6 4885db test rbx, rbx
|| 0x5631bdca89f9 7414 je 0x5631bdca8a0f
|| 0x5631bdca89fb 48c1e302 shl rbx, 2
|| 0x5631bdca89ff ba04000000 mov edx, 4
|| 0x5631bdca8a04 4c89f7 mov rdi, r14
|| 0x5631bdca8a07 4889de mov rsi, rbx
|| 0x5631bdca8a0a e851040000 call sym.__rust_dealloc
|| 0x5631bdca8a0f 488b742410 mov rsi, qword [rsp + 0x10] ; [0x10:8]=-1 ; 16
|| 0x5631bdca8a14 4885f6 test rsi, rsi
|| 0x5631bdca8a17 740f je 0x5631bdca8a28
|| 0x5631bdca8a19 488b7c2408 mov rdi, qword [rsp + 8] ; [0x8:8]=-1 ; 8
|| 0x5631bdca8a1e ba01000000 mov edx, 1
|| 0x5631bdca8a23 e838040000 call sym.__rust_dealloc
|| 0x5631bdca8a28 488b742448 mov rsi, qword [rsp + 0x48] ; [0x48:8]=-1 ; 'H' ; 72
|| 0x5631bdca8a2d 4885f6 test rsi, rsi
|| 0x5631bdca8a30 7411 je 0x5631bdca8a43
|| 0x5631bdca8a32 48c1e602 shl rsi, 2
|| 0x5631bdca8a36 ba04000000 mov edx, 4
|| 0x5631bdca8a3b 4c89ff mov rdi, r15
|| 0x5631bdca8a3e e81d040000 call sym.__rust_dealloc
|| 0x5631bdca8a43 4881c4880000. add rsp, 0x88
|| 0x5631bdca8a4a 5b pop rbx
|| 0x5631bdca8a4b 415c pop r12
|| 0x5631bdca8a4d 415d pop r13
|| 0x5631bdca8a4f 415e pop r14
|| 0x5631bdca8a51 415f pop r15
|| 0x5631bdca8a53 5d pop rbp
|| 0x5631bdca8a54 c3 ret
Un saludo, @naivenom.