Skip to main content

You are here

Ruby

Working with Ruby obfuscated code: Finding all classes available in a module

As a follow up to my HashiCorp Rocks! blog post. Up until now, I've never directly worked with any obfuscated code. HashiCorp obfuscates their VMware Fusion and Workstation commercial Vagrant plugins.

Like Vagrant, the plugins themselves are written in Ruby.

alpha03:lib tony$ file vagrant-vmware-fusion.rb
vagrant-vmware-fusion.rb: ASCII text, with very long lines, with CRLF, LF line terminators

However, if you try to read the source all you'll see is a bunch of encoded text. Since my Vagrant plugin has some functionality that only works after a certain action gets executed by the proprietary plugins. This is why I needed to know the exact name of that particular action (class name) exactly how it's defined inside the VMware Fusion and Workstation plugins. This was a serious problem because I can't read their source code!

Luckily, this wasn't as difficult as it seems. Finding the classes (or methods but in the case of mine I didn't need too) available in Ruby is fairly simple process. To my luck somebody had already asked and answered this question in StackOverflow.

In my case, first step was needing to know the name of the actual module itself. I found the easiest way to get the name of the module that's obfuscated, is to intentionally have it spit out an exception. In doing that, I found that the module names whose namespace I'll be searching were HashiCorp::VagrantVMwarefusion and HashiCorp::VagrantVMwareworkstation.

Once I knew the modules's name, I was able to use Ruby to view what additional modules I have within the particular module namespace. I was able to accomplish that using the following

 
t = HashiCorp::VagrantVMwareworkstation.constants.select {|c| 
HashiCorp::VagrantVMwareworkstation.const_get(c).is_a? Module
}
puts t

I above sample code spit out a bunch of modules inside HashiCorp::VagrantVMwareworkstation, but since I know the Vagrant plugin API and it's coding standards/practices. I was able to verify that the module I'm searching for is HashiCorp::VagrantVMwareworkstation::Action. Once again, looking at Plugin API and other examples, I knew that this is where the class is I'm looking is stored in. So I used the following to get the corresponding class name within HashiCorp::VagrantVMwareworkstation::Action

p = HashiCorp::VagrantVMwareworkstation::Action.constants.select { |c|
HashiCorp::VagrantVMwareworkstation::Action.const_get(c).is_a? Class
}
 puts p

I repeated the above tests for HashiCorp::VagrantVMwarefusion and I was also able to find the corresponding class name that it's defined inside the obfuscated Ruby code.

In the end I was able to get the classes HashiCorp::VagrantVMwareworkstation::Action::Suspend and HashiCorp::VagrantVMwarefusion::Action::Suspend, and everything worked as expected.

Programming: 

Awesome Applications: 

Python if __name__ == '__main__' Ruby equivalent

Python is by no chance my favorite language to work in, however I always loved the way you can beautifully write your modules and easily test them via if __name__ == '__main__' statement. I've been doing a lot of Ruby programing these past few weeks, and I came across a situation were I needed this exact feature in Ruby.

My problem:
I needed to run some unit tests to a Ruby based TCP server that gets spawn as daemon. The program is completely command line, and once spawned, their isn't any code to communicate with its child process. The unit tests itself aren't exactly to complicated. I simply need to make sure that the TCP server starts, verify the status of it using its PID, and be able to kill the process. I needed to run the unit tests without heavily modifying the existing program, and the best best to accomplished it was using a similar if __name__ == '__main__' Python approach. Lucky for me, in the Ruby world we can accomplish the awesome if __name__ == '__main__' Python statement via if __FILE__ == $0

Example:
Here is a test module called test-module.rb

#!/usr/bin/env ruby

if __FILE__ == $0
  puts "Executed via command line."
else
  puts "Included."
end

Now, if we run this test-module.rb from the command line, the if __FILE__ == $0 block will evaluate to true.

alpha03:tests $ ./test-module.rb
Executed via command line.

If the module gets included the if __FILE__ == $0 block will evaluate to false. Example script called test.rb

#!/usr/bin/env ruby

require './test-module'

Running the test.rb script that required test-module.rb

alpha03:tests tony$ ./test.rb
Included.

Conclusion:
Ruby rocks!

Programming: 

Custom Nagios mdadm monitoring: check_mdadm-raid

Simple Nagios mdadm monitoring plugin.

#!/usr/bin/env ruby

# Tony Baltazar. root[@]rubyninja.org

OK = 0
WARNING = 1
CRITICAL = 2
UNKNOWN = 3

# Note to self, mdadm exit status:
#0 The array is functioning normally.
#1 The array has at least one failed device.
#2 The array has multiple failed devices such that it is unusable.
#4 There was an error while trying to get information about the device.

raid_device = '/dev/md0'

get_raid_output = %x[sudo mdadm --detail #{raid_device}].lines.to_a


get_raid_status = get_raid_output.grep(/\sState\s:\s/).to_s.match(/:\s(.*)\\n\"\]/)
raid_state = get_raid_status[1].strip



if raid_state.empty?
 print "Unable to get RAID status!"
 exit UNKNOWN
end

if /^(clean(, checking)?|active)$/.match(raid_state) 
 print "RAID OK: #{raid_state}"
 exit OK
elsif /degraded/i.match(raid_state)
 print "WARNING RAID: #{raid_state}"
 exit WARNING
elsif /fail/i.match(raid_state)
 print "CRITICAL RAID: #{raid_state}"
 exit CRITICAL
else
 print "UNKNOWN RAID detected: #{raid_state}"
 exit UNKNOWN
end

Programming: 

Awesome Applications: 

Ruby: Visual QuickStart Guide

I finally finished reading my first book on Ruby programming. Ruby: Visual QuickStart Guide, by Larry Ullman has to be the perfect introduction book for anyone trying to learn the Ruby programming language, even though sadly it only has 3 five star reviews on Amazon. The author writing thoroughly explains the concepts in a friendly and easy to understand manner. This being the third book that I’ve read from this same author, the other titles being for MySQL and PHP (no reviews on these yet since I’m not fully finished reading them).
One thing I would’ve like changed the author to change was on the database chapter, as it was mainly focused on SQLite. It would have been better if the author used MySQL instead. Also it would have been better if the author removed the dedicated chapter to Rails, and instead extended the chapter to have more generic web related like Net::HTTP, given how powerful that single class is.

Chapter 1: Getting Started
Chapter 2: Simple Scripts
Chapter 3: Simple Types
Chapter 4: Array, Ranges, and Hashes
Chapter 5: Control structures
Chapter 6: Creating Methods
Chapter 7: Creating Classes
Chapter 8: Inheritance and More
Chapter 9: Modules and Includes
Chapter 10: Regular Expressions
Chapter 11: Debugging and Error Handling
Chapter 12: Rubygems
Chapter 13: Directories and Files
Chapter 14: Databases
Chapter 15: Networking
Chapter 16: Ruby on Rails
Chapter 17: Dynamic Programing

I would highly recommended this book to anybody starting or wanting to learn Ruby.

Rating: 4/5
Ruby: Visual-QuickStart

Book: 

Scripting Language: 

Beginning Ruby

As always I’m pretty late in writing my book reviews. This time it’s been well over 6 months since I finished reading the book “Beginning Ruby” (first edition) by Peter Cooper. I have to say is this by far the best Ruby book that I’ve read so far. (This is out of a 13 book collection that I own on Ruby programming.) I’ve always been a fan of Apress “Beginning” title’s, and this book is definitely not the exception. Although this book is technically considered for beginning/intermediate programmers wanting to dive to the wonderful world of Ruby, I feel this book is perfect for all levels of programming expertise. The authors does a wonderful job explain the concepts of each chapter and slowly building you to what will be the next chapter. Like Apress’ “Beginning Perl” book help me tremendously in learning the language, I have to say this book taught how to program in Ruby.
I’ll definitely come back to this book and use as a reference. Anyone new or already experienced using Ruby, will definitely benefit from reading this book. I hope this book (all editions) gets the high praise from the Ruby community, which it deserves, as in my eyes this is a classic programming book and I see this title as the Llama/Camel book for the Ruby World.
Chapter 1: Let’s Get it Started: Installing Ruby
Chapter 2: Programming == Joy: A Whistle-Stop Tour of Ruby and Object Orientation
Chapter 3: Ruby’s Building Blocks: Data, Expressions and Flow Control
Chapter 4: Developing a Basic Ruby Application
Chapter 5: The Ruby Ecosystem
Chapter 6: Classes, Objects, and Modules
Chapter 7: Projects and Libraries
Chapter 8: Documentation, Error Handling, Debugging, and Testing
Chapter 9: Files and Databases
Chapter 10: Deploying Ruby Applications and Libraries
Chapter 11: Advance Ruby Features
Chapter 12: Tying it Together: Developing a Larger Ruby Application
Chapter 13: Ruby on Rails: Ruby’s Killer App
Chapter 14: Ruby and the Internet
Chapter 15: Networking, Sockets, and Daemons
Chapter 16: Useful Ruby Libraries and Gems

Beginning Ruby (2nd Edition)
5/5

Book: 

Scripting Language: 

301 URL redirect on Ruby on Rails

In your respective controller, specify the method of the view in questioned that needs to be redirected.

def code
   headers["Status"] = "301 Moved Permanently"
   redirect_to "https://www.example.com/alpha01"
 end

Programming: 

Awesome Applications: 

Building mysql2 gem in Ubuntu issue

Installing mysql2 (0.3.11) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

/home/tony/.rvm/rubies/ruby-1.9.3-p125/bin/ruby extconf.rb
checking for rb_thread_blocking_region()... yes
checking for rb_wait_for_single_fd()... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lz... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lsocket... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lnsl... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lmygcc... no
checking for mysql_query() in -lmysqlclient... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.

Provided configuration options:
--with-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/home/tony/.rvm/rubies/ruby-1.9.3-p125/bin/ruby
--with-mysql-config
--without-mysql-config
--with-mysql-dir
--without-mysql-dir
--with-mysql-include
--without-mysql-include=${mysql-dir}/include
--with-mysql-lib
--without-mysql-lib=${mysql-dir}/lib
--with-mysqlclientlib
--without-mysqlclientlib
--with-mlib
--without-mlib
--with-mysqlclientlib
--without-mysqlclientlib
--with-zlib
--without-zlib
--with-mysqlclientlib
--without-mysqlclientlib
--with-socketlib
--without-socketlib
--with-mysqlclientlib
--without-mysqlclientlib
--with-nsllib
--without-nsllib
--with-mysqlclientlib
--without-mysqlclientlib
--with-mygcclib
--without-mygcclib
--with-mysqlclientlib
--without-mysqlclientlib

FIX

sudo apt-get install libmysqld-pic

Programming: 

Awesome Applications: 

Premium Drupal Themes by Adaptivethemes