Apologies

Due to recent migration from another web hoster, I am still in the process of uploading files, so not all files are online yet. Sorry for the inconvenience.

This page contains a collection of non-research-related code, cheat sheets, and notes.

Miscellaneous code

  • Metagoofil is "an information gathering tool designed for extracting metadata of public documents (pdf,doc,xls,ppt,docx,pptx,xlsx) belonging to a target company." Here is a patch for some bugs in Metagoofil version 2.1 (Blackhat Arsenal Edition).
  • VBScript script for reducing the number of services started by Windows XP at boot time. To run it, rename the file extension as "vbs", and double-click it.

CISSP

I passed the CISSP examination on 28 May 2011 in Melbourne. Below, you can find my notes for preparing for the exam. Each of these documents is formatted in such a way that it fits nicely on the screen of a Google Nexus S. These documents do not contain the actual questions or answers from the exam itself.

  1. Access control
  2. Application security
  3. Business continuity and disaster recovery planning
  4. Cryptography
  5. Information security governance and risk management
  6. Legal regulations investigations and compliance
  7. Operations security
  8. Physical and environment security
  9. Security architecture and design
  10. Telecommunications and network security

GIT

Initializing a repository (repo): In the repo directory, do

git init

Committing changes: Assuming the file is main.c, do

git add main.c
git commit -m "Comment." main.c

Checking status and log: Assuming the file is main.c, then to check its status (modified? untracked?), do

git status main.c
To see the log, do
git log main.c
To see only log comments, do
git log --oneline main.c
To make git wrap log comments to 80 characters per line, do
git shortlog -w80 main.c

Checking differences: To check the changes you have made to, say file main.c, do

git diff main.c
To compare two commits (say with commit IDs da278fc15d6052d206aeae9f24ca3155f627d162 and 4f7b415465bea0927fc85d231b3358d98edfc946) of the file main.c, do
git diff da27..4f7b main.c
Note that it's sufficient to use the first few digits of the commit IDs as long as there is no other commit ID that starts with the same digits. Unlike CVS, GIT doesn't generate messy .#files in the directory. There are several variants of the diff command, be sure to check
git diff --help
You may want to tell GIT to use a GUI to display the differences. For me, my preference is FileMerge (command opendiff) on a Mac, so this is what I do:
git config --global diff.external ~/git-opendiff.sh
This tells GIT to execute ~/git-opendiff.sh every time the diff command is executed. In the file ~/git-opendiff.sh, I have the following commands:
#!/bin/sh
opendiff $2 $5
Caution: if you don't specify the file name with git diff, GIT will open FileMerge for every file that has been changed.

Coloring: To color-code the display, use the following commands:

git config --global color.diff auto
git config --global color.status auto
Note that all issued config commands are stored in /.gitconfig.

Checking out an older version: To check out an earlier version of main.c, say version abcd without making any changes to the history, do

mv main.c main.bak
git checkout abcd main.c
To check out the last committed version, do
git checkout HEAD main.c
A word of warning for CVS users: the checkout command is not what you used to expect! For more info, read this.

Renaming a file: To rename file oldfile to newfile, do

git mv oldfile newfile
git add -u newfile
git commit -m "Comment." newfile
To see the complete log of newfile, the --follow switch must be used:
git log --follow newfile
For more info, read this.

Migrating from CVS to GIT: This mentions an example of migrating a CVS repo to GIT, but there's too little information. My contribution here is a minimalist tutorial on the subject. In this tutorial, I assume you are the sole user of the repo. GIT stores info about file mode (permissions), so it is recommended to use a filesystem that keeps this information (i.e., not FAT).

  1. First create a directory, say ~/gittest (i.e. a directory called gittest in your home directory), then in gittest, do:
    git cvsimport -v -a -i -k -d $CVSROOT ZBS
    If you are familiar with CVS, you should know that $CVSROOT points to the CVS root repository. In this example, ZBS is the name of the project you are trying to import. To find out the meaning of the switches such as -v etc., type
    git cvsimport --help
  2. If you CVS repo is not corrupted, then the import would have been successful. Now, you need to clone the directory. Create the project directory ZBS and in the project directory do
    git clone ~/gittest
    Two steps so far and now you have a working GIT repo!

Pushing to github.com: github.com provides a convenient means to share code. To set github.com as the "origin", do

git remote add origin https://github.com/user/repo.git
git remote set-url origin git@github.com:user/repo.git
git push origin master
If you set up your SSH key pair and publish the public key to github.com, then you will be able to perform the above without having to type in your password.

More info: visual GIT tutorial, Git Community Book, GIT workflow diagram.

Printing an A5-sized book on A4 papers

To me, reading A4-sized documents/books while commuting is cumbersome. I prefer A5-sized documents, but A5 documents are not widely available -- in fact I haven't seen any (paper sizes are nicely explained here). This is why I propose

  1. printing documents on A4 papers, with 2 pages on 1 side of a paper, or in other words, a total of 4 pages on 2 sides of one sheet of paper,
  2. cutting the papers in half,
  3. interleaving the papers,
  4. and finally binding the papers.

To achieve this, we need to print the pages in this order: 1,3,4,2,5,7,8,9,... or 1,4,3,2,5,8,7,9,.... The following Perl script re-orders a PDF document according to the first scheme, using Perl module PDF::API2 and the LaTeX program texexec:

#!/usr/bin/perl
			
use strict;
use warnings;

use PDF::API2;

undef $/;

if ($#ARGV < 1) {
	print STDERR "Usage: $0 {input filename} {output filename}\n";
	exit 0;
}

# open and read file
my ($ifn, $ofn, $pdf, $pages, $i, $order, $cmd);

$ifn = $ARGV[0];
$ofn = $ARGV[1];
$pdf = PDF::API2->open($ifn);
$pages = $pdf->pages;

print STDERR "Number of pages = $pages\n";

# order = 1,3,4,2,...
$i = 1;
while ($i <= $pages) {
	if ($i+1 > $pages) {
		$order .= $i;
	} elsif ($i+2 > $pages) {
		$order .= $i.','.($i+1).','.$i.','.($i+1).',';
	} elsif ($i+3 > $pages) {
		$order .= $i.','.($i+2).','.($i+2).','.($i+1).',';
	} else {
		$order .= $i.','.($i+2).','.($i+3).','.($i+1).',';
	}
	$i += 4;
}
if (rindex($order, ",") eq length($order)-1) {
	$order = substr($order, 0, length($order)-1);
}

# exec cmd
$cmd = "texexec --pdfselect --selection=$order \"$ifn\" --result=\"$ofn\"";
print STDERR $cmd;
system $cmd;

The result:

Enhancing Javadoc-generated documentation

Javadoc by default generates an index.html that shows 3 frames, the bottom left of which is an "All classes" frame (file name allclasses-frame.html). Scrolling this particular frame to locate the right class is rather cumbersome if there are a lot of classes. Won't it be nice if we have a Search box where we can type in the class name and it will bring us straight to the documentation of the class? The following HTML and JavaScript code achieves just this.

<!-- [Custom] begin -->
<script language="javascript">
function find() {
	// preprocessing
	var target = document.getElementById("TARGET").value.replace(/\s+/g, "");
	var matchHead = document.getElementById("MATCHHEAD").checked;
	var matchAny = document.getElementById("MATCHANY").checked;	
	//window.alert(target+", "+partial);	// debug
	if (target == "") return;

	// matching
	var matched = false;
	var altHref = null;
	for (i = 0; i < document.links.length; i++) {
		var href = document.links[i].href;
		var slashPos = href.lastIndexOf('/');
		var dotPos = href.lastIndexOf('.');
		var className = href.substring(slashPos+1, dotPos);
		//window.alert(className);	// debug
		if (target.toLowerCase() == className.toLowerCase()) {			
			parent.frames["classFrame"].document.location = href;
			matched = true;
			return;
		} else {
			if (matchHead && altHref == null && className.search(new RegExp(target, "i")) == 0) {
				altHref = href;
			}
			if (matchAny && altHref == null && className.search(new RegExp(target, "i")) >= 0) {
				altHref = href;
			}
		}
	}
	if (!matched) {
		if ((matchHead || matchAny) && altHref != null) {
			parent.frames["classFrame"].document.location = altHref;
		} else {
			window.alert("Class not found.");
		}
	}
}
</script>
<div style="position: fixed; background: #f0f0f0; width: 100%; top: 0pt;">
	<!-- Note: Doing submit causes the page to be reloaded, which is slow. -->
	<form onsubmit="javascript:find();">
		<input type="text" size="20" id="TARGET"></input>
		<input type="button" size="6" value="Find" onclick="javascript:find();"></input><br>		
		<input type="radio" name="match_type" id="COMPLETE">Complete match only</input><br>
		<input type="radio" name="match_type" id="MATCHHEAD" CHECKED>Input maybe a prefix</input><br>
		<input type="radio" name="match_type" id="MATCHANY">Input maybe a sub-string</input>
	</form>
</div>
<div style="height: 5em;"></div>
<!-- [Custom] end -->

By sticking this code fragment right after the BODY tag in the file allclasses-frame.html, the functionality as depicted in the screenshot can be obtained: