1
mirror of https://github.com/rapid7/metasploit-framework synced 2024-11-12 11:52:01 +01:00
metasploit-framework/HACKING
Joshua Drake 5d4d225abe add blurb about += vs <<
git-svn-id: file:///home/svn/framework3/trunk@9745 4d416f70-5f16-0410-b530-b9f4589650da
2010-07-09 16:19:22 +00:00

94 lines
3.5 KiB
Plaintext

# $Id$
This file contains some brief instructions on contributing to the
Metasploit Framework.
Code Style
==========
In order to maintain consistentcy and readability, we ask that you
adhere to the following style guidlines:
- Hard tabs, not spaces
- Try to keep your lines under 100 columns (assuming four-space tabs)
- do; end instead of {} for a block
Code No-Nos
===========
1. Don't print to standard output. Doing so means that users of
interfaces other than msfconsole, such as msfrpc and msfweb, won't see
your output. You can use print_line to accomplish the same thing as
puts.
2. Don't use "sleep". It has been known to cause issues with
multi-threaded programs on various platforms. Instead, we use
"select(nil, nil, nil, <time>)" throughout the framework. We have
found this works around the underlying issue.
3. Always use Rex sockets, not ruby sockets. This includes
third-party libraries such as Net::Http. There are several very good
reasons for this rule. First, the framework doesn't get notified on
the creation of ruby sockets and won't know how to clean them up in
case your module raises an exception without cleaning up after itself.
Secondly, non-Rex sockets do not know about routes and therefore can't
be used through a meterpreter tunnel. Lastly, regular sockets miss
out on msf's proxy and ssl features. Msf includes many protocols
already implemented with Rex and if the protocol you need is missing,
porting another library to use them is straight-forward. See our
Net::SSH modifications in lib/net/ssh/ for an example.
4. When opening an IO stream, always force binary with "b" mode (or
using IO#binmode). This not only helps keep Windows and non-Windows
runtime environments consistent with each other, but also guarantees
that files will be treated as ASCII-8BIT instead of UTF-8.
5. Don't use String#[] for a single character. This returns a Fixnum in
ruby 1.8 and a String in 1.9, so it's safer to use the following idiom:
str[idx,1]
which always returns a String. If you need the ASCII byte, unpack it like
so:
str[idx,1].unpack("C")
6. Whenever possible, avoid using '+' or '+=' to concatenate strings.
The '<<' operator is significantly faster. The difference will become
even more apparent when doing string manipulation in a loop. The
following table approximates the underlying implementation:
Ruby Pseudo-C
----------- ----------------
a = b + c a = malloc(b.len+c.len+1);
strcpy(a, b);
memcpy(a+b.len, c, c.len);
a[b.len + c.len] = '\0';
a = b a = b;
a << c a = realloc(a, a.len+c.len+1);
memcpy(a+a.len, c, c.len);
a[a.len + c.len] = '\0';
Note that the original value of 'b' is lost in the second case. Care
must be taken to duplicate strings that you do not want to modify.
Creating New Modules
====================
When creating a new module, the simplest way to start is to copy
another module that uses the same protocol and modify it to your
needs. If you're creating an exploit module, generally you'll want
to edit the exploit() method. Auxiliary Scanner modules use one of
run_host(), run_range(), or run_batch() instead of exploit().
Non-scanner aux modules use run().
Licensing
=========
By submitting code contributions to the Metasploit Project it is
assumed that you are offering your code under a BSD or similar
license. MIT and Ruby Licenses are also fine. We specifically cannot
include GPL code.
When possible, such as aux and exploit modules, be sure to include
your license designation in the file in the approriate place.