Rating:

As you can see from most other writeups, the decompilation for this program looks pretty clean.

```c
char v4[8]; // [rsp+28h] [rbp-8h] BYREF

gnat_argc = a1;
gnat_argv = (__int64)a2;
gnat_envp = (__int64)a3;
__gnat_initialize(v4);
sub_1D7C();
sub_298A();
sub_1D52();
__gnat_finalize();
return (unsigned int)gnat_exit_status;
```
```
__int64 sub_298A()
{
ada__calendar__delays__delay_for(1000000000000000LL);
sub_2616();
sub_24AA();
sub_2372();
sub_25E2();
sub_2852();
sub_2886();
sub_28BA();
sub_2922();
sub_23A6();
sub_2136();
sub_2206();
sub_230A();
sub_2206();
sub_257A();
sub_28EE();
sub_240E();
sub_26E6();
sub_2782();
sub_28EE();
sub_2102();
sub_23DA();
sub_226E();
sub_21D2();
sub_2372();
sub_23A6();
sub_21D2();
return sub_2956();
}
```
After looking for awhile, it's rather straightforward that we are looking at an ada program and in `sub_298A()`, there is a `1000000000000000` second delay before it prints individual letters of our flag in the subsequent function calls.

Many people who did the challenge or wrote writeups manually went through each function to obtain the characters individually. I had a different take on it.

After figuring out that the flag will be printed after the delay, I decided to get rid of the delay by hacking the delay (library hijacking or LD_PRELOAD as some may call it)

Essentially, I wrote a small c shared library with the delay function, except that it does nothing.

```
# hacksleep.c
int ada__calendar__delays__delay_for(int a) {
return 1;
}
```

And then I will compile with `gcc -shared -fPIC hacksleep.c -o hacksleep.o`

Running `LD_PRELOAD="./hacksleep.o" ./svchost.exe` gave me the flag.

![](https://i.imgur.com/jYA5zWs.png)

Do we stop here? Technically yes, but the flag mentioned disassembly... let's try this the GDB way :)

Doing an `entry-break` in gef lands me at the first instruction, unfortunately we can't simply `break *main` as we do not know where main is.

![](https://i.imgur.com/IZv602v.png)

Let's figure where main is using `__libc_start_main`. After stepping a few times with `ni`, we quickly find ourself in `__libc_start_main+0`

![](https://i.imgur.com/D9Qzb5c.png)

Something we should know about `__libc_start_main` is the arguments that it takes

> int __libc_start_main(int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end));
[see here](https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/baselib---libc-start-main-.html)

The first argument if `__libc_start_main` is the address of `main` function itself, which will be inside `RDI` since `RDI` contains the first argument to our `__libc_start_main` function. (_see [calling conventions](https://caprinux.github.io/lawofpwn/innerworkings/how_does_assembly_work#calling-conventions)_)

```
gef➤ print $rdi
$2 = 0x555555401fcc
```

We can then break at the address with `break *$rdi` and `continue`

After stepping a few time, we find the function with `ada__calendar__delays__delay_for@plt`

![](https://i.imgur.com/aDyfUbS.png)

We will then step into the function with `si` and keep stepping until our `rip` is on the instruction that it calls `ada__calendar__delays__delay_for`.

Here's where we can hack it, we can simply set our `rip` to the next instruction, skipping the call to delay entirely.

In my case, I will do `set $pc=0x55555540299d`, and then `continue`

![](https://i.imgur.com/M5uXPgi.png)

Hope that gave you a fresh perspective on debugging and preloading libraries.