Crystal is a “new” Ruby-syntax-based programming language, born in 2014. The main diference is, that this is not a Ruby implementation, this is another compiled programming language, but its syntax is based in ruby, so Crystal != Ruby.

You can learn more about Crystal here: crystal

Any new compiled programming language results interesting from a reverse engineering perspective, malware is becoming more and more based on this kind of compiled programming language, whose syntax is easier than C or C++, but mantaining the ability to run standalone.

A Crystal Hello World example, looks like this:

puts 'Hello world!'

Yes, just like Ruby. To compile this, let’s save it as hello.cr and execute the Crystal compiler: crystal build hello.cr. This should create a hello executable with the following characteristics: hello: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, with debug_info, not stripped

A dinamically linked, non-stripped binary. Cool!

IDA analysis.

Let’s load this newly created binary using IDA Free 7.0 for Linux, (keep calm radare2 fanboys). Something catch my attention when load finished:

lot_of_functions

Maaaaaaan 2055 functions?!!! Calm down buddy, if you take a look at other compiled languages, like Golang, this is normal. Modern compiled languages, import everything they need to be cross-platform, so lot of functions are included in a single binary to be able to compile binaries for Windows, Linux and OSX using a single compiler.

So where’s the program itself?

By default, IDA show us to the first function basic blocks executed in the program.

ida_main

Ok cool, so this function just calls another function: main_0, which also calls another function main_user_code

ida_main_0

And main_user_code just calls another function __crystal_main

ida_main_user_code

Let’s then analyze this __crystal_main function, opening their basic blocks view, something really ugly happen:

ida_what_the_hell

… what the hell man, where the fuck is our application code? Just at the end!

ida_what_the_hell

There you can see the loading of our “Hello world!” string, which is at off_9A530, and a call to puts function which seems to be a wrapper for puts_0 function, which really executes the output operation and shows our string in stdout.

Ok, so the workflow seems to be:

main -> main_0 -> main_user_code -> __crystal_main and, at the end, our script code is executed.

Let’s see how conditionals and classes works at Crystal creating a simple script with the following code:

class MyHelloClass
  def initialize(number=0)
    @number = number
  end

  def test_random
    if @number < 4
      puts "A is lower than 4"
    else
      puts "A is GREATER than 4"
    end
  end
end

puts "Now, an if sentence will appear based on rand numeric value"

num = rand(6)
a = MyHelloClass.new(num)
a.test_random

Ok simple, let’s compile it crystal build hello2.cr and open it using IDA, this time going directly to __crystal_main buttom, where our code should be.

ida_hello2

There it is, first, rand is called, which is, again a wrapper for Random::PCG32 function identified in IDA as new_98

Then, a call to new_101 is done, when inspecting this is our MyHelloClass::new function, which is the wrapper for the initialize function in our class. In Ruby, the initialize function is the constructor of the class.

ida_hello2

As you can see in this basic block, memory is created for our new object using _crystal_malloc_antomic64 function, a wrapper for GC_generic_malloc which, after lot of operations, is a malloc itself.

Then, a call test_random is done, remember, Crystal compiler does not strip binaries by default so function names remain intact.

ida_hello2

Here it is our conditional, and our puts calls on each condition. Cool!

Radare2, show us function names processed, so it’s a bit easier to identify the binary work flow with a single s sym.__crystal_main pdf call.

ida_hello2

That’s all, thanks for reading, and hope this post can be helpful for someone facing this kind of binaries for the first time.

Please, feel free to contact me if you see any mistake, also my written english is not the best, so sorry for those whose eyes explode while reading this.

See you!