<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
	<title>CriticalSecurity - Recent Topics</title>
	<description></description>
	<link>http://www.criticalsecurity.net/index.php</link>
	<pubDate>Sun, 14 Mar 2010 02:59:18 +0000</pubDate>
	<ttl>3</ttl>
	<item>
		<title><![CDATA[St. Patrick'S Day]]></title>
		<link>http://www.criticalsecurity.net/index.php/topic/32859-st-patricks-day/</link>
		<description><![CDATA[So, what are you guys going to get up to? I'm going to be free from 6, probably drink until 12 and wake up in a bush somewhere 20 minutes before I should be at work. Anybody have some more civilised plans?]]></description>
		<pubDate>Sun, 14 Mar 2010 01:21:45 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32859-st-patricks-day/</guid>
	</item>
	<item>
		<title>Master Boot Record Editor Application</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32858-master-boot-record-editor-application/</link>
		<description><![CDATA[During my latest researches I developed an application which can edit your computer's master boot record. It's not the fancy coding, but it works and I like its dangerous usage <img src='http://www.criticalsecurity.net/public/style_emoticons/default/tongue.gif' class='bbc_emoticon' alt=':P' />. I've decided to publish it for anyone interested in this kind of stuff, maybe it proves helpful or interesting. First of all...<br />
<br />
<span style='color: #8B0000'><span style='font-size: 36px;'><strong class='bbc'>!!! BIG FAT HEAVY WARNING !!!</strong></span><br />
This can easily totally fuck up your current setup along with the primary partition table, so you could end up reformatting your computer if you mess something up. I won't be held responsible for any possible damage done to your machine. I know what I'm talking about because it happened to me, too, luckily the damage was small, the only thing I lost is the time while I was repairing it and some links. So use it on a virtual machine or on some computer designated for tests and destruction. Also, it does not do anything on its own, so it's your responsibility to specify the right destructive flags. Consider yourself warned.</span><br />
<br />
The program has been made in Microsoft Visual C++ 2008 Express Edition and successfully tested on Microsoft Windows XP SP2. I don't know if it works on Windows Vista or Seven. (I doubt it, because I've heard they had changed some permissions, so raw disk reading is not supported any more. If anyone decides to test it, please post your findings.)<br />
<br />
The program uses <a href='http://msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx' class='bbc_url' title='External link'>CreateFile</a>, <a href='http://msdn.microsoft.com/en-us/library/aa365467%28VS.85%29.aspx' class='bbc_url' title='External link'>ReadFile</a> and <a href='http://msdn.microsoft.com/en-us/library/aa365747%28VS.85%29.aspx' class='bbc_url' title='External link'>WriteFile</a> functions to view and edit the MBR changes. I've spent some time getting it to work because I was getting errors while trying to read it. In the end it came up that the system file buffering is turned off, so you can read or write only the disk sector size and its multiples (I used <a href='http://msdn.microsoft.com/en-us/library/aa364935%28VS.85%29.aspx' class='bbc_url' title='External link'>GetDiskFreeSpace</a> function). Also, the file pointer had to be manually set (function SetFilePointer) and the data had to be aligned in memory (function <a href='http://msdn.microsoft.com/en-us/library/aa366887%28VS.85%29.aspx' class='bbc_url' title='External link'>VirtualAlloc</a> does the good job). Also, as the MBR reading happens always, the file pointer has to be reset again before the MBR rewriting, otherwise you write the sector after the MBR. There were a couple of web pages that helped me, but I lost the most of them. The most important is <a href='http://bootmaster.filerecovery.biz/appnote3.html' class='bbc_url' title='External link'>this one</a>.<br />
<br />
The program has the ability to store the MBR in a binary file, which can then be disassembled with "ndisasm" program (for instance) and examined or changed and rewritten(which was my goal). Furthermore, a user can observe boot sectors on different disks, like NTFS boot sector which usually boots Windows.<br />
<br />
If anyone engages in the quest of writing their own MBRs or systems, I'd be very interested to see what you've come up with. This is my next assignment, we'll see how it goes.<br />
<br />
Here are a couple of useful tools to use along with the MBREditor:<br />
<ul class='bbc'><li><a href='http://www.nasm.us/' class='bbc_url' title='External link'>nasm with ndisasm</a><br /></li><li><a href='http://www.chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm' class='bbc_url' title='External link'>XVI32 hexeditor</a></li></ul><br />
<br />
The code:<br />
<br />
MBREditor.cpp<br />
<div class='bbc_spoiler'>
	<span>Spoiler</span> <input type='button' class='bbc_spoiler_show' value='Show' />
	<div class='bbc_spoiler_wrapper'><div class='bbc_spoiler_content' style="display:none;"><br />
<pre class='prettyprint'>
// MBREditor.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "MBREditor.h"

int main(int argc, char* argv&#91;&#93;)
{
	// Parsing arguments
	INT arg_i = 1;			// Argument index
	DWORD dataElements = 0;	// What data do we want to output / change
	DWORD action = 0;		// 0 - output to screen, 1 - read from device to file, 2 - write from file to device
	DWORD iRes;				// Function ReadMBR / WriteMBR result
	BOOL binaryOutput = 0;	// Is binary (raw) output requested flag (hexadecimal output)

	DWORD binOuptuLength = SIZE_MBR;				// Used for binary output, user can change it with a -b flag
	LPCH fileName;									// User enters this for MBR store / load
	LPCH userPath = "PhysicalDrive0";				// The device whose MBR we want to read
	CHAR devicePath&#91;MAX_PATH_LENGTH&#93; = "&#092;&#092;&#092;&#092;.&#092;&#092;";	// Default string for device naming

	LPCH buffer = NULL;								// Pointer to the local MBR buffer (after it's read from the device)
	DWORD dwBytesRead;								// ReadMBR function fills these
	DWORD dwBufferSize;
	HANDLE hVolume;									// Holds a handle to the device whose MBR we are inspecting

	// Intro output
	fprintf(stderr, "%s", intro);

	//
	// Flags are getting parsed
	//
	while (arg_i &lt; argc)
	{
		if (argv&#91;arg_i&#93;&#91;0&#93; == '-')
		{
			switch (argv&#91;arg_i&#93;&#91;1&#93;)
			{
				// Checking for action:
				case 'r':
					// Mandatory argument
					if ((arg_i + 1 &gt;= argc) || (argv&#91;arg_i + 1&#93;&#91;0&#93; == '-'))
					{
						fprintf(stderr, "ERROR: -r flag needs an argument representing the file name and path.&#092;n");
						return -1;
					}
					action = 1;
					arg_i++;
					fileName = argv&#91;arg_i&#93;;
					break;
				case 'w':
					// Mandatory argument
					if ((arg_i + 1 &gt;= argc) || (argv&#91;arg_i + 1&#93;&#91;0&#93; == '-'))
					{
						fprintf(stderr, "ERROR: -w flag needs an argument representing the file name and path.&#092;n");
						return -1;
					}
					action = 2;
					arg_i++;
					fileName = argv&#91;arg_i&#93;;
					break;
				// Checking for data flags (default is all of them):
				case 'c':
					dataElements = dataElements | deCode;
					break;
				case 'd':
					dataElements = dataElements | deDiskSignature;
					break;
				case 'n':
					dataElements = dataElements | deNulls;
					break;
				case 'p':
					dataElements = dataElements | dePrimaryPartitions;
					break;
				case 'm':
					dataElements = dataElements | deMBRSignature;
					break;
				// Aditional: Checking for different device location
				case 'v':
					// Mandatory argument
					if ((arg_i + 1 &gt;= argc) || (argv&#91;arg_i + 1&#93;&#91;0&#93; == '-'))
					{
						fprintf(stderr, "ERROR: -v flag needs an argument representing the volume or file to perform on.&#092;n");
						return -1;
					}
					arg_i++;
					userPath = argv&#91;arg_i&#93;;
					break;
				// Aditional: request for binary (hexadecimal user-readable) output only
				case 'b':
					binaryOutput = 1;
					// Optional argument
					if ((arg_i + 1 &lt; argc) && (argv&#91;arg_i + 1&#93;&#91;0&#93; != '-'))
					{
						arg_i++;
						binOuptuLength = atoi(argv&#91;arg_i&#93;);
						if (binOuptuLength == 0)
						{
							fprintf(stderr, "ERROR: Wrong binary output size entered.&#092;n");
							return -1;
						}
					}
					break;
				// Help requested
				case 'h':
					fprintf(stderr, "%s", helpText);
					return 0;
				default:
					fprintf(stderr, "WARNING: Flag %s has not been defined.&#092;n", argv&#91;arg_i&#93;);
			}
		}
		else
		{
			fprintf(stderr, "WARNING: Unusable argument %s.&#092;n", argv&#91;arg_i&#93;);
		}
		arg_i++;
	}
	printf("&#092;n");

	// Defaults to all data
	if (dataElements == 0) dataElements = ALL_DATA;

	// Concatenates the initial device definition "&#092;&#092;.&#092;" with the user-submitted 
	// or default device.
	strncat_s(devicePath, MAX_PATH_LENGTH - 1, userPath, MAX_PATH_LENGTH - 5);

	//
	// Opening the volume for raw reading and writing
	//
	hVolume = CreateFileA(
		devicePath,
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_NO_BUFFERING,
		NULL
	);

	if (hVolume == INVALID_HANDLE_VALUE)
	{
		// ERROR:
		fprintf(stderr, "ERROR: CreateFile function failed, error no %d&#092;n", GetLastError());
		return -1;
	}

	//
	// Initialization finished
	//

	// Reading the MBR contents
	buffer = ReadMBR(buffer, devicePath, hVolume, &dwBytesRead, &dwBufferSize);

	if (buffer == NULL)
	{
		CloseHandle(hVolume);
		fprintf(stderr, "Unrecoverable ERROR happened in ReadMBR function. Exiting.&#092;n");
		return -1;
	}

	switch (action)
	{
		// Output to the screen (default):
		case 0:
			if (binaryOutput)
				RawOutputData(buffer, binOuptuLength);
			else
				OutputData(buffer, dataElements);
			break;
		// Writing from MBR to binary file (total binary format, ready for ndisasm utility)
		case 1:
			iRes = PrintToFile(buffer, dataElements, fileName);
			
			// Releasing the resources
			VirtualFree(buffer, dwBufferSize, MEM_RELEASE);
			CloseHandle(hVolume);

			// Printing to file and exiting
			return iRes;
			break;
		// Writing from binary file to MBR
		case 2:
			iRes = WriteMBR(buffer, hVolume, dwBufferSize, dataElements, fileName);
			 
			// Releasing the resources
			VirtualFree(buffer, dwBufferSize, MEM_RELEASE);
			CloseHandle(hVolume);

			// Writing to MBR and exiting
			return iRes;
			break;
	}

	// Releasing the resources
	VirtualFree(buffer, dwBufferSize, MEM_RELEASE);
	CloseHandle(hVolume);

	// Finishing
	return 0;
}

//
//	LPCH ReadMBR(LPCH buffer, LPCH deviceName, HANDLE hVolume, PDWORD dwBytesRead, PDWORD dwBufferSize)
//
//	Reads master boot record data into a buffer. As we are dealing with
//	the disk device, no bufferning must be used. This means we have to
//	follow some alignment rules when reserving the memory, reading and
//	writing. These rules are explained here:
//
//	http://msdn.microsoft.com/en-us/library/cc644950%28VS.85%29.aspx
//
//	Parameters:
//		LPCH buffer				- Initial empty pointer
//		LPCH deviceName			- Pointer to the device name
//		HANDLE hVolume			- handle to the volume whose MBR is being read
//		PDWORD dwBytesRead		- Returns number of bytes read
//		PDWORD dwBufferSize		- Returns the size of the allocated page
//
//	Return value:				- Pointer to the page holding the data
LPCH ReadMBR(LPCH buffer, LPCH deviceName, HANDLE hVolume, PDWORD dwBytesRead, PDWORD dwBufferSize)
{
	DWORD iRes;						// Test result integer
	DWORD dwBytesPerSector;
	DWORD dwBufferSizeLocal;
	DWORD dwBytesReadLocal = 0;

	*dwBytesRead = 0;

	//
	// Rule no 1: File access sizes must be a number of bytes that is an
	//            integer multiple of the volume sector size.
	//
	
	iRes = GetDiskFreeSpaceA(
		deviceName,
		NULL,
		&dwBytesPerSector,
		NULL,
		NULL
	);

	if (iRes == 0)
	{
		// ERROR:
		//fprintf(stderr, "ERROR: GetDiskFreeSpace function failed, error no %d&#092;n", GetLastError());
		
		//return NULL;
		dwBytesPerSector = 512;
	}
	

	if (dwBytesPerSector &lt;= SIZE_MBR)
	{
		// If the sector is smaller than usual MBR size, we simply read the
		// whole MBR
		dwBufferSizeLocal = SIZE_MBR;
	}
	else
	{
		// Otherwise, we need to read more data than needed.
		dwBufferSizeLocal = dwBytesPerSector;
	}
	
	//
	// Rule no 2: File access buffer addresses for read and write operations 
	//            should be sector-aligned, which means aligned on addresses 
	//            in memory that are integer multiples of the volume sector size.
	//
	buffer = (LPCH)VirtualAlloc(NULL, dwBufferSizeLocal, MEM_COMMIT, PAGE_READWRITE);
	
	if (buffer == NULL)
	{
		// ERROR:
		fprintf(stderr, "ERROR: VirtualAlloc function failed, error no %d&#092;n", GetLastError());

		return NULL;
	}

	//
	// Reading the MBR
	//
	// First we need to align the file pointer to 0 - the reading starting position
	iRes = SetFilePointer(hVolume, 0, NULL, FILE_BEGIN);

	if (iRes == INVALID_SET_FILE_POINTER)
	{
		// ERROR:
		fprintf(stderr, "ERROR: SetFilePointer function failed, error no %d&#092;n", GetLastError());

		// Releasing the resources
		VirtualFree(buffer, dwBufferSizeLocal, MEM_RELEASE);

		return NULL;
	}

	// Then we issue the read command
	iRes = ReadFile(hVolume, buffer, dwBufferSizeLocal, &dwBytesReadLocal, NULL);

	if (iRes == 0)
	{
		// ERROR:
		fprintf(stderr, "ERROR: ReadFile function failed, error no %d&#092;n", GetLastError());

		// Releasing the resources
		VirtualFree(buffer, dwBufferSizeLocal, MEM_RELEASE);

		return NULL;
	}

	// Successful return
	*dwBytesRead = dwBytesReadLocal;
	*dwBufferSize = dwBufferSizeLocal;
	return buffer;
}

//
//	void RawOutputData(LPCH buffer, DWORD size)
//
//	Outputs each character in the hexadecimal form, usually 16 chars in a
//	row. Treats each character as an ASCII char (as a byte).
VOID RawOutputData(LPCH buffer, DWORD size)
{
	DWORD i, j, row = 0;

	for (i=0; i&lt;size; i++)
	{
		printf("  %-4.4x:  ", row * 16);

		for (j=0; j&lt;ELEMENTS_IN_ROW; j++)
		{
			if ((j % 4 == 0) && (j != 0)) printf("| ");
			printf("%02.2X ", (unsigned char)buffer&#91;i * ELEMENTS_IN_ROW + j&#93;);
		}
		
		printf("&#092;n");
		row++;
	}

	printf("&#092;n");
}


//
//	OutputData(LPCH buffer, DWORD dataElements)
//
//	Outputs the MBR data for the user. User can also select the combination of 
//	the data parts to output using different flags stated at the beginning of 
//	this program. The data is printed according to the combination of bits 
//	activated by different flags.
//
//	Data selector bits:
//		1  - Code
//		2  - Disk Signature
//		4  - Nulls
//		8  - Primary partitions
//		16 - MBR Signature
//
//		31 - All
VOID OutputData(LPCH buffer, DWORD dataElements)
{
	UMBRCS bufToStruct;

	DWORD i, j;

	bufToStruct.buffer = buffer;

	// First output the code
	if ((dataElements & deCode) == deCode)
	{
		printf("Code (%d bytes):&#092;n", SIZE_CODE);
		RawOutputData(buffer, SIZE_CODE / 16);
	}

	// Then comes the disk signature (optional)
	if ((dataElements & deDiskSignature) == deDiskSignature)
	{
		printf("Disk signature (%d bytes):&#092;t", SIZE_DISK_SIGNATURE, " ");
		
		for (i=0; i&lt;SIZE_DISK_SIGNATURE; i++)
			printf(" %02.2X", (unsigned char)bufToStruct.structure-&gt;seDiskSignature&#91;i&#93;);

		printf("&#092;n&#092;n");
	}

	// Then come the nulls (optional)
	if ((dataElements & deNulls) == deNulls)
	{
		printf("Nulls (%d bytes):&#092;t&#092;t", SIZE_NULLS, " ");
		
		for (i=0; i&lt;SIZE_NULLS; i++)
			printf(" %02.2X", (unsigned char)bufToStruct.structure-&gt;seNulls&#91;i&#93;);

		printf("&#092;n&#092;n");
	}

	// Then comes the primary partitions table (optional)
	if ((dataElements & dePrimaryPartitions) == dePrimaryPartitions)
	{
		printf("Primary partitions (%d bytes):&#092;n", SIZE_PRIMARY_PARTITIONS);
		
		for (i=0; i&lt;SIZE_PRIMARY_PARTITIONS / 16; i++)
		{
			printf("  Partition %d:", i + 1);
			for (j=0; j&lt;16; j++)
				printf(" %02.2X", (unsigned char)bufToStruct.structure-&gt;sePrimaryPartitions&#91;i * 16 + j&#93;);
			printf("&#092;n");
		}

		printf("&#092;n");
	}

	// Then comes the MBR signature
	if ((dataElements & deMBRSignature) == deMBRSignature)
	{
		printf("MBR signature (%d bytes):&#092;t", SIZE_MBR_SIGNATURE);
		
		for (i=0; i&lt;SIZE_MBR_SIGNATURE; i++)
		{
			printf(" %02.2X", (unsigned char)bufToStruct.structure-&gt;seMBRSignature&#91;i&#93;);
		}

		printf("&#092;n&#092;n");
	}
}

//
//	DWORD PrintToFile(LPCH buffer, DWORD dataElements, char *fileName)
//
//	Outputs the MBR section to a file in the binary mode. Can be used for 
//	making MBR backup copies. The same flags apply as in the OutputData 
//	function case.
//
//	Parameters:
//		LPCH buffer				- Pointer to the page holding the data
//		DWORD dataElements		- What data should be outputted to the file
//		PCHAR fileName			- The file name and path for the output
//
//	Return value:				- 0 on success, -1 on failure
//
//	TODO:
//		- fwrite test for errors - compare bytes to write and written bytes
//		- when writing only some pieces of code, align them properly, possibly
//			with null bytes where the data isn't requested to be written to file
DWORD PrintToFile(LPCH buffer, DWORD dataElements, PCHAR fileName)
{
	UMBRCS bufToStruct;
	FILE *lpFile;
	CHAR file_path&#91;MAX_PATH_LENGTH&#93;;
	DWORD iRes = 0;
	
	bufToStruct.buffer = buffer;
	
	// Open the file for writing
	iRes = fopen_s(&lpFile, fileName, "wb");

	if (iRes != 0)
	{
		fprintf(stderr, "ERROR: fopen_s function failed, error no %d:&#092;n&#092;t%s&#092;n&#092;n", iRes, fileName);
		return -1;
	}


	// First output the code
	if ((dataElements & deCode) == deCode)
	{
		fwrite(bufToStruct.structure-&gt;seCode, 1, SIZE_CODE, lpFile);
	}

	// Then comes the disk signature (optional)
	if ((dataElements & deDiskSignature) == deDiskSignature)
	{
		fwrite(bufToStruct.structure-&gt;seDiskSignature, 1, SIZE_DISK_SIGNATURE, lpFile);
	}

	// Then come the nulls (optional)
	if ((dataElements & deNulls) == deNulls)
	{
		fwrite(bufToStruct.structure-&gt;seNulls, 1, SIZE_NULLS, lpFile);
	}

	// Then comes the primary partitions table (optional)
	if ((dataElements & dePrimaryPartitions) == dePrimaryPartitions)
	{
		fwrite(bufToStruct.structure-&gt;sePrimaryPartitions, 1, SIZE_PRIMARY_PARTITIONS, lpFile);
	}

	// Then comes the MBR signature
	if ((dataElements & deMBRSignature) == deMBRSignature)
	{
		fwrite(bufToStruct.structure-&gt;seMBRSignature, 1, SIZE_MBR_SIGNATURE, lpFile);
	}

	fclose(lpFile);

	GetFullPathNameA(fileName, MAX_PATH_LENGTH, file_path, NULL);
	printf("MBR is successfully stored in file: &#092;n&#092;n%s&#092;n&#092;n", file_path);

	return 0;
}

//
//	DWORD WriteMBR(LPCH buffer, HANDLE hVolume, DWORD dwBufferSize, DWORD dataElements, PCHAR fileName)
//
//	Writes a binary file to the desired MBR section. It is possible to write only some pieces of the data,
//	but they must be properly aligned as in the MBR definition. 
//
//	Parameters:
//		LPCH buffer				- Pointer to the page holding the data
//		DWORD dwBufferSize		- Length of the buffer to write
//		DWORD dataElements		- What data should be inputted from the file
//		PCHAR fileName			- The file name and path for the input
//
//	Return value:				- 0 on success, -1 on failure
//
DWORD WriteMBR(LPCH buffer, HANDLE hVolume, DWORD dwBufferSize, DWORD dataElements, PCHAR fileName)
{
	UMBRCS bufToStruct;
	DWORD dwBytesWritten;
	FILE *lpFile;
	DWORD iRes = 0;
	CHAR file_path&#91;MAX_PATH_LENGTH&#93;;
	
	bufToStruct.buffer = buffer;

	//
	// First read the data to be written from a file
	//
	iRes = fopen_s(&lpFile, fileName, "rb");

	if (iRes != 0)
	{
		fprintf(stderr, "ERROR: fopen_s function failed, error no %d:&#092;n&#092;t%s&#092;n&#092;n", iRes, fileName);
		return -1;
	}

	//
	// Edit the contents of the original buffer by directly reading from file
	// and rewriting the desired contents.
	//
	// First output the code
	if ((dataElements & deCode) == deCode)
	{
		fread(bufToStruct.structure-&gt;seCode, 1, SIZE_CODE, lpFile);
	}
	else
	{
		fseek(lpFile, SIZE_CODE, SEEK_CUR);
	}

	// Then comes the disk signature (optional)
	if ((dataElements & deDiskSignature) == deDiskSignature)
	{
		fread(bufToStruct.structure-&gt;seDiskSignature, 1, SIZE_DISK_SIGNATURE, lpFile);
	}
	else
	{
		fseek(lpFile, SIZE_DISK_SIGNATURE, SEEK_CUR);
	}

	// Then come the nulls (optional)
	if ((dataElements & deNulls) == deNulls)
	{
		fread(bufToStruct.structure-&gt;seNulls, 1, SIZE_NULLS, lpFile);
	}
	else
	{
		fseek(lpFile, SIZE_NULLS, SEEK_CUR);
	}

	// Then comes the primary partitions table (optional)
	if ((dataElements & dePrimaryPartitions) == dePrimaryPartitions)
	{
		fread(bufToStruct.structure-&gt;sePrimaryPartitions, 1, SIZE_PRIMARY_PARTITIONS, lpFile);
	}
	else
	{
		fseek(lpFile, SIZE_PRIMARY_PARTITIONS, SEEK_CUR);
	}

	// Then comes the MBR signature
	if ((dataElements & deMBRSignature) == deMBRSignature)
	{
		fread(bufToStruct.structure-&gt;seMBRSignature, 1, SIZE_MBR_SIGNATURE, lpFile);
	}
	else
	{
		fseek(lpFile, SIZE_MBR_SIGNATURE, SEEK_CUR);
	}


	// We need to reset the file pointer before writing
	iRes = SetFilePointer(hVolume, 0, NULL, FILE_BEGIN);

	if (iRes == INVALID_SET_FILE_POINTER)
	{
		// ERROR:
		fprintf(stderr, "ERROR: SetFilePointer function failed, error no %d&#092;n", GetLastError());

		// Releasing the resources
		fclose(lpFile);

		return -1;
	}

	//
	// Writing the changes to the volume. The whole local MBR is written to the disk, so
	// that the WriteFile does not complain about aligns.
	//
	iRes = WriteFile(hVolume, buffer, dwBufferSize, &dwBytesWritten, NULL);

	if (iRes == 0)
	{
		// ERROR:
		fprintf(stderr, "ERROR: WriteFile function failed, error no %d&#092;n", GetLastError());

		// Releasing the resources
		fclose(lpFile);
		return -1;
	}

	
	GetFullPathNameA(fileName, MAX_PATH_LENGTH, file_path, NULL);

	printf("MBR is successfully rewritten from file: &#092;n&#092;n%s&#092;n&#092;n", file_path);

	// Releasing the resources
	fclose(lpFile);

	return 0;
}

//
// void PrintUsage()
//
// Outputs the program usage.
void PrintUsage()
{
	fprintf(stderr, "%s", helpText);
}
</pre><br />
</div></div>
</div><br />
<br />
MBREditor.h<br />
<div class='bbc_spoiler'>
	<span>Spoiler</span> <input type='button' class='bbc_spoiler_show' value='Show' />
	<div class='bbc_spoiler_wrapper'><div class='bbc_spoiler_content' style="display:none;"><br />
<pre class='prettyprint'>
#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;
#include &lt;conio.h&gt;
#include &lt;WinIoCtl.h&gt;

//
// Function definitions
//
LPCH ReadMBR(LPCH buffer, LPCH DeviceName, HANDLE hVolume, PDWORD dwBytesRead, PDWORD dwBufferSize);
DWORD WriteMBR(LPCH buffer, HANDLE hVolume, DWORD dwBufferSize, DWORD dataElements, PCHAR fileName);
DWORD PrintToFile(LPCH buffer, DWORD dataElements, PCHAR fileName);
VOID OutputData(LPCH buffer, DWORD dataElements);
VOID RawOutputData(LPCH buffer, DWORD size);
VOID PrintUsage();

//
// MBR data elements sizes
//
static const DWORD SIZE_MBR = 512;
static const DWORD SIZE_CODE = 440;
static const DWORD SIZE_DISK_SIGNATURE = 4;
static const DWORD SIZE_NULLS = 2;
static const DWORD SIZE_PRIMARY_PARTITIONS = 64;
static const DWORD SIZE_MBR_SIGNATURE = 2;

//
// Different data parts from MBR. "ALL_DATA" is consisted from all
// the "de*" bits (all the values are OR-ed together): 
// ALL_DATA = deCode | deDiskSignature | deNulls | dePrimaryPartitions | deMBRSignature
//
static const DWORD ALL_DATA = 31;

static const DWORD deCode = 1;
static const DWORD deDiskSignature = 2;
static const DWORD deNulls = 4;
static const DWORD dePrimaryPartitions = 8;
static const DWORD deMBRSignature = 16;

//
// Other constants
//
static const DWORD ELEMENTS_IN_ROW = 16;
static const DWORD MAX_PATH_LENGTH = 1024;

//
// Structure representing MBR fields
//
typedef struct _sMBR
{
	char seCode&#91;SIZE_CODE&#93;;
	char seDiskSignature&#91;SIZE_DISK_SIGNATURE&#93;;
	char seNulls&#91;SIZE_NULLS&#93;;
	char sePrimaryPartitions&#91;SIZE_PRIMARY_PARTITIONS&#93;;
	char seMBRSignature&#91;SIZE_MBR_SIGNATURE&#93;;
} SMBR, *LPSMBR;

//
// Union that converts one long char buffer to a MBR structure
//
typedef union _bufToStruct
{
	LPCH buffer;
	LPSMBR structure;
} UMBRCS, *LPUMBRCS;

//
// Output texts
//
static const char *helpText = 
" Usage:&#092;n"
"&#092;n"
"&#092;nAction:&#092;n&#092;n"
"  When no flags are selected, the MBR contents are printed to the screen in&#092;n"
"  a human-readable format.&#092;n&#092;n"
"    -r &#91;a&#93;    - Read MBR from a device to a file, argument is the file name&#092;n"
"    -w &#91;a&#93;    - Write MBR from a file to a device, argument is the file name&#092;n"
"&#092;nData:&#092;n&#092;n"
"  Use these flags to select only particular data to print, read or write to&#092;n"
"  file. Several flags can be selected, all the flags are selected by default.&#092;n&#092;n"
"    -c        - Code&#092;n"
"    -d        - Disk signature&#092;n"
"    -n        - Nulls&#092;n"
"    -p        - Primary partitions table&#092;n"
"    -m        - MBR Signature&#092;n"
"&#092;nOther:&#092;n&#092;n"
"  When defining a disk bootloader, use the drive letter without trailing&#092;n"
"  backslash, for instance, use &#092;"C:&#092;" instead of &#092;"C:&#092;&#092;&#092;".&#092;n&#092;n"
"    -v &#91;a&#93;    - Device, without this flag, &#092;"PhysicalDrive0&#092;" is used&#092;n"
"    -b &#91;ao&#93;   - Binary output / raw output, optional argument is the length&#092;n"
"                of raw output, default is 512 bytes.&#092;n"
"    -h        - Print this help&#092;n";

static const char *intro = 
"&#092;n==================&#092;n"
"    MBR Editor&#092;n"
"==================&#092;n&#092;n"
"Created by:  Nutcracker from www.criticalsecurity.net&#092;n"
"Date:        13.03.2010.&#092;n"
"Version:     v1.0&#092;n&#092;n";

</pre><br />
</div></div>
</div>]]></description>
		<pubDate>Sat, 13 Mar 2010 17:48:19 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32858-master-boot-record-editor-application/</guid>
	</item>
	<item>
		<title>Perl System.</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32857-perl-system/</link>
		<description><![CDATA[Hello, In C we have something like " system("cd Desktop/marrie/");".. This is called pipelining if i am not mistaken.<br />
I am now trying to do this in perl too. How can i accomplish this? Can anyone give me a sample code?<br />
<br />
In python i think we have os.system().]]></description>
		<pubDate>Sat, 13 Mar 2010 10:51:53 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32857-perl-system/</guid>
	</item>
	<item>
		<title>Slow Performance Mysql</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32855-slow-performance-mysql/</link>
		<description><![CDATA[Hello guys,<br />
<br />
At work I recently moved our e-commerce software From an iMac to a FreeBSD based server. Since the move, mysql searches that were taking &lt; 1 second before are now taking about 20 seconds. I've messed with the my.cnf file and haven't noticed any significant performance. <br />
<br />
Does anyone have suggestions?<br />
<br />
<strong class='bbc'>Uptime</strong>- 12:04PM  up 16 days, 52 mins, 3 users, load averages: 1.19, 1.25, 1.25<br />
<br />
<strong class='bbc'>Top Output</strong><br />
<div class='bbc_spoiler'>
	<span>Spoiler</span> <input type='button' class='bbc_spoiler_show' value='Show' />
	<div class='bbc_spoiler_wrapper'><div class='bbc_spoiler_content' style="display:none;"><br />
last pid:  8400;  load averages:  1.23,  1.18,  1.23  up 16+00:47:39    11:59:27<br />
64 processes:  2 running, 62 sleeping<br />
<br />
Mem: 195M Active, 857M Inact, 198M Wired, 112M Buf, 752M Free<br />
Swap: 4070M Total, 4070M Free<br />
<br />
<br />
  PID USERNAME  THR PRI NICE   SIZE    RES STATE  C   TIME   WCPU COMMAND<br />
95241 root        1 121    0  1960K  1152K RUN    0 947:15 96.29% zip<br />
 8398 root        1   4    0  4868K  3116K sbwait 0   0:00  1.00% sshd<br />
  898 mysql      14  20    0   523M   144M kserel 0  25:59  0.00% mysqld<br />
  700 root        1   8    0 19036K 11952K nanslp 0   0:24  0.00% httpd<br />
  724 root        1  96    0  3484K  3012K select 0   0:19  0.00% sendmail<br />
  713 root        1 122    0  3524K  2704K select 0   0:14  0.00% sshd<br />
44526 www         1   4    0 21964K 15588K accept 0   0:05  0.00% httpd<br />
48948 www         1   4    0 22844K 16200K accept 0   0:04  0.00% httpd<br />
74517 www         1   4    0 21964K 15284K accept 0   0:04  0.00% httpd<br />
  552 root        1  96    0  1376K  1032K select 0   0:03  0.00% syslogd<br />
80513 www         1   4    0 21836K 15432K accept 0   0:03  0.00% httpd<br />
  270 _dhcp       1  96    0  1464K  1148K select 0   0:03  0.00% dhclient<br />
  748 root        1   8    0  1404K  1116K nanslp 0   0:03  0.00% cron<br />
92499 www         1   4    0 21984K 15624K accept 0   0:03  0.00% httpd<br />
 2881 www         1   4    0 21804K 15112K accept 0   0:01  0.00% httpd<br />
95197 www         1   4    0 21144K 14476K accept 0   0:01  0.00% httpd<br />
  654 root        1  96    0  1288K   824K select 0   0:01  0.00% usbd<br />
 3015 www         1   4    0 21956K 15524K accept 0   0:01  0.00% httpd<br />
<br />
<br />
</div></div>
</div><br />
<br />
<br />
MySQL.cnf<br />
<div class='bbc_spoiler'>
	<span>Spoiler</span> <input type='button' class='bbc_spoiler_show' value='Show' />
	<div class='bbc_spoiler_wrapper'><div class='bbc_spoiler_content' style="display:none;"><br />
# Example MySQL config file for large systems.<br />
#<br />
# This is for a large system with memory = 512M where the system runs mainly<br />
# MySQL.<br />
#<br />
# You can copy this file to<br />
# /etc/my.cnf to set global options,<br />
# mysql-data-dir/my.cnf to set server-specific options (in this<br />
# installation this directory is /var/db/mysql) or<br />
# ~/.my.cnf to set user-specific options.<br />
#<br />
# In this file, you can use all long options that a program supports.<br />
# If you want to know which options a program supports, run the program<br />
# with the "--help" option.<br />
<br />
# The following options will be passed to all MySQL clients<br />
[client]<br />
#password	= your_password<br />
port		= 3306<br />
socket		= /tmp/mysql.sock<br />
<br />
# Here follows entries for some specific programs<br />
<br />
# The MySQL server<br />
[mysqld]<br />
port		= 3306<br />
socket		= /tmp/mysql.sock<br />
skip-locking<br />
key_buffer = 512M<br />
max_allowed_packet = 2M<br />
table_cache = 1024<br />
sort_buffer_size = 8M<br />
read_buffer_size = 128M<br />
read_rnd_buffer_size = 8M<br />
myisam_sort_buffer_size = 128M<br />
thread_cache_size = 8<br />
query_cache_size= 128M<br />
# Try number of CPU's*2 for thread_concurrency<br />
thread_concurrency = 8<br />
<br />
# Don't listen on a TCP/IP port at all. This can be a security enhancement,<br />
# if all processes that need to connect to mysqld run on the same host.<br />
# All interaction with mysqld must be made via Unix sockets or named pipes.<br />
# Note that using this option without enabling named pipes on Windows<br />
# (via the "enable-named-pipe" option) will render mysqld useless!<br />
# <br />
#skip-networking<br />
<br />
# Disable Federated by default<br />
skip-federated<br />
<br />
# Replication Master Server (default)<br />
# binary logging is required for replication<br />
log-bin=mysql-bin<br />
<br />
# required unique id between 1 and 2^32 - 1<br />
# defaults to 1 if master-host is not set<br />
# but will not function as a master if omitted<br />
server-id	= 1<br />
<br />
# Replication Slave (comment out master section to use this)<br />
#<br />
# To configure this host as a replication slave, you can choose between<br />
# two methods :<br />
#<br />
# 1) Use the CHANGE MASTER TO command (fully described in our manual) -<br />
#    the syntax is:<br />
#<br />
#    CHANGE MASTER TO MASTER_HOST=&lt;host&gt;, MASTER_PORT=&lt;port&gt;,<br />
#    MASTER_USER=&lt;user&gt;, MASTER_PASSWORD=&lt;password&gt; ;<br />
#<br />
#    where you replace &lt;host&gt;, &lt;user&gt;, &lt;password&gt; by quoted strings and<br />
#    &lt;port&gt; by the master's port number (3306 by default).<br />
#<br />
#    Example:<br />
#<br />
#    CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,<br />
#    MASTER_USER='joe', MASTER_PASSWORD='secret';<br />
#<br />
# OR<br />
#<br />
# 2) Set the variables below. However, in case you choose this method, then<br />
#    start replication for the first time (even unsuccessfully, for example<br />
#    if you mistyped the password in master-password and the slave fails to<br />
#    connect), the slave will create a master.info file, and any later<br />
#    change in this file to the variables' values below will be ignored and<br />
#    overridden by the content of the master.info file, unless you shutdown<br />
#    the slave server, delete master.info and restart the slaver server.<br />
#    For that reason, you may want to leave the lines below untouched<br />
#    (commented) and instead use CHANGE MASTER TO (see above)<br />
#<br />
# required unique id between 2 and 2^32 - 1<br />
# (and different from the master)<br />
# defaults to 2 if master-host is set<br />
# but will not function as a slave if omitted<br />
#server-id       = 2<br />
#<br />
# The replication master for this slave - required<br />
#master-host     =   &lt;hostname&gt;<br />
#<br />
# The username the slave will use for authentication when connecting<br />
# to the master - required<br />
#master-user     =   &lt;username&gt;<br />
#<br />
# The password the slave will authenticate with when connecting to<br />
# the master - required<br />
#master-password =   &lt;password&gt;<br />
#<br />
# The port the master is listening on.<br />
# optional - defaults to 3306<br />
#master-port     =  &lt;port&gt;<br />
#<br />
# binary logging - not required for slaves, but recommended<br />
#log-bin=mysql-bin<br />
<br />
# Point the following paths to different dedicated disks<br />
#tmpdir		= /tmp/		<br />
#log-update 	= /path-to-dedicated-directory/hostname<br />
<br />
# Uncomment the following if you are using BDB tables<br />
#bdb_cache_size = 64M<br />
#bdb_max_lock = 100000<br />
<br />
# Uncomment the following if you are using InnoDB tables<br />
#innodb_data_home_dir = /var/db/mysql/<br />
#innodb_data_file_path = ibdata1:10M:autoextend<br />
#innodb_log_group_home_dir = /var/db/mysql/<br />
#innodb_log_arch_dir = /var/db/mysql/<br />
# You can set .._buffer_pool_size up to 50 - 80 %<br />
# of RAM but beware of setting memory usage too high<br />
#innodb_buffer_pool_size = 256M<br />
#innodb_additional_mem_pool_size = 20M<br />
# Set .._log_file_size to 25 % of buffer pool size<br />
#innodb_log_file_size = 64M<br />
#innodb_log_buffer_size = 8M<br />
#innodb_flush_log_at_trx_commit = 1<br />
#innodb_lock_wait_timeout = 50<br />
<br />
[mysqldump]<br />
quick<br />
max_allowed_packet = 16M<br />
<br />
[mysql]<br />
no-auto-rehash<br />
# Remove the next comment character if you are not familiar with SQL<br />
#safe-updates<br />
<br />
[isamchk]<br />
key_buffer = 128M<br />
sort_buffer_size = 128M<br />
read_buffer = 2M<br />
write_buffer = 2M<br />
<br />
[myisamchk]<br />
key_buffer = 128M<br />
sort_buffer_size = 128M<br />
read_buffer = 2M<br />
write_buffer = 2M<br />
<br />
[mysqlhotcopy]<br />
interactive-timeout<br />
<br />
</div></div>
</div>]]></description>
		<pubDate>Fri, 12 Mar 2010 17:09:40 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32855-slow-performance-mysql/</guid>
	</item>
	<item>
		<title>Database Transfer</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32853-database-transfer/</link>
		<description><![CDATA[I have been running my website and database on my own computer using XAMPP. To submit my website I need to transfer it all to the university server. I have set up sql on my university account but I am having trouble transferring the database because of the following differences<br />
<br />
Home:<br />
mysql version : 5.1.41<br />
OS : Windows<br />
<br />
University:<br />
mysql version : 4.0.12<br />
OS : UNIX<br />
<br />
<br />
To export I have been using phpMyAdmin <br />
<br />
To import I have been using  mysql -u username -p &lt; database.sql<br />
<br />
I keep getting the following error<br />
<br />
Unknown system variable 'SQL_MODE'<br />
<br />
<br />
<br />
Any ideas?<br />
<br />
Thanks<br />
<br />
Calypso]]></description>
		<pubDate>Thu, 11 Mar 2010 14:49:16 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32853-database-transfer/</guid>
	</item>
	<item>
		<title>It Lawyer</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32852-it-lawyer/</link>
		<description><![CDATA[Hello everyone!<br />
<br />
I am studing Law LLB in a uni in England. We are currently being asked to choose the courses we are going to do for the next year so pretty much I have to make some plans for my future. <br />
<br />
What i have in my mind is studing Law which have to do with computer crime, hacking, illegal data exchange and staff like that. So i guess doing a Master in IT Law(when the time comes) will be the only kind of law(i think) which will have to do with these kind of staff. <br />
<br />
That`s why i make this topic so if someone believe that there are any alternatives ways of succeeding that I will be glad. Also what unis will be available to do this kind of master and even what country is better to do it.]]></description>
		<pubDate>Wed, 10 Mar 2010 18:17:32 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32852-it-lawyer/</guid>
	</item>
	<item>
		<title>Root This Box</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32849-root-this-box/</link>
		<description><![CDATA[So one of the things I was missing from HTS was rootthisbox. Here I present a proposal for rootthisbox.net, CriticalSecurity now has its own version of rootthisbox. Domain has been registered and now we need to get our assess into gear to create some challenges/games. I think initally we should have similar games to the last rootthisbox, ie. break in, add your name to a file and you will be awarded points. I like the idea of having a challenge every once in a while, maybe even some hands on hacking tutorials. <br />
<br />
This is to be a project run by CS for CS so the better we make it the more fun we can have. Let me know your thoughts/suggestions.]]></description>
		<pubDate>Wed, 10 Mar 2010 08:24:06 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32849-root-this-box/</guid>
	</item>
	<item>
		<title>Need Some Feedback On Securitytube.Net</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32847-need-some-feedback-on-securitytube-net/</link>
		<description><![CDATA[Hello All,<br />
<br />
I have been running SecurityTube.net for the last year or so. For those who have not ever visited the site, here is the link : <a href='http://www.securitytube.net' class='bbc_url' title='External link'>http://www.securitytube.net</a> .<br />
<br />
Basically the site contains a lot of videos I have made on topics related to security and hacking, other members have made and embeds of good videos from sites such as youtube and vimeo.<br />
<br />
The objective of the site was to become a good collection of quality videos people can learn from.<br />
<br />
I am planning to revamp the website and wanted to know your feedback on it. Would be great if you could tell me what you like / dislike about the site and what things you feel i could add to make it more useful.<br />
<br />
Please be honest with your feedback. I am open to criticism.<br />
<br />
Vivek]]></description>
		<pubDate>Tue, 09 Mar 2010 07:12:26 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32847-need-some-feedback-on-securitytube-net/</guid>
	</item>
	<item>
		<title>Dos Attack</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32846-dos-attack/</link>
		<description><![CDATA[Hi guys,<br />
<br />
I am trying to use PackETH v1.6 which can run on windows OS, to simulate the SYN FLOOD attack to load-balancer.<br />
<br />
But i fail to see any packet going through when i display the interface statistics.<br />
<br />
I wonder if anyone can show me how to configure the PackETH tool.<br />
<br />
Thanks.<br />
<a class='resized_img' rel='lightbox[221407]' id='ipb-attach-url-789-1268535558-74' href="http://www.criticalsecurity.net/index.php?app=core&module=attach&section=attach&attach_rel_module=post&attach_id=789" title="packETH01.JPG -  159.76K,  27"><img src="http://www.criticalsecurity.net/uploads/monthly_03_2010/post-79300-126811795069_thumb.jpg" id='ipb-attach-img-789-1268535558-74' style='width:100;height:63' class='attach' width="100" height="63" alt="" /></a><a class='resized_img' rel='lightbox[221407]' id='ipb-attach-url-790-1268535558-76' href="http://www.criticalsecurity.net/index.php?app=core&module=attach&section=attach&attach_rel_module=post&attach_id=790" title="packETH02.JPG -  156.62K,  31"><img src="http://www.criticalsecurity.net/uploads/monthly_03_2010/post-79300-126811796567_thumb.jpg" id='ipb-attach-img-790-1268535558-76' style='width:100;height:63' class='attach' width="100" height="63" alt="" /></a><a class='resized_img' rel='lightbox[221407]' id='ipb-attach-url-791-1268535558-76' href="http://www.criticalsecurity.net/index.php?app=core&module=attach&section=attach&attach_rel_module=post&attach_id=791" title="packETH03.JPG -  117.76K,  20"><img src="http://www.criticalsecurity.net/uploads/monthly_03_2010/post-79300-126811797923_thumb.jpg" id='ipb-attach-img-791-1268535558-76' style='width:100;height:63' class='attach' width="100" height="63" alt="" /></a>]]></description>
		<pubDate>Tue, 09 Mar 2010 07:00:38 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32846-dos-attack/</guid>
	</item>
	<item>
		<title>Optimizing Php File</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32845-optimizing-php-file/</link>
		<description><![CDATA[My forms are pretty short, 10-15 fields. What if the form was 30,50,100 long as some job application forms are. Also I have three forms therefore I have to make 3 php files. Surely there is a better way to update a database. <br />
<br />
I am thinking along the line of a php file taking the following parameters<br />
<br />
1. Database  username, password, name, fields  etc<br />
2. Html form name<br />
<br />
Then the script would loop through the form and find all input object such as textfields, comboBoxes, texboxes etc and upload these to the database<br />
<br />
Is this possible??<br />
<br />
<br />
<pre class='prettyprint'>
&lt;?php

$TitleGeneral = $_POST&#91;'TitleGeneral'&#93;;
$FirstNameGeneral = $_POST&#91;'FirstNameGeneral'&#93;;
$LastNameGeneral = $_POST&#91;'LastNameGeneral'&#93;;

$AddressGeneral = $_POST&#91;'AddressGeneral'&#93;;
$TownGeneral = $_POST&#91;'TownGeneral'&#93;;
$CountyGeneral = $_POST&#91;'CountyGeneral'&#93;;

$PostCodeGeneral= $_POST&#91;'PostCodeGeneral'&#93;;
$CountryGeneral = $_POST&#91;'CountryGeneral'&#93;;
$EmailGeneral = $_POST&#91;'EmailGeneral'&#93;;
$TelephoneGeneral = $_POST&#91;'TelephoneGeneral'&#93;;
$MobileGeneral = $_POST&#91;'MobileGeneral'&#93;;
$EnquiryDescriptionGeneral = $_POST&#91;'EnquiryDescriptionGeneral'&#93;;
$MarketingGeneral = $_POST&#91;'MarketingGeneral'&#93;;




mysql_connect("localhost", "root", "") or die;
mysql_select_db("Camira");

$query = "INSERT INTO General (

    ID,
    TitleGeneral,
    FirstNameGeneral,
    LastNameGeneral,
    AddressGeneral,
    TownGeneral,
    CountyGeneral,
    PostCodeGeneral,
    CountryGeneral,
    EmailGeneral,
    TelephoneGeneral,
    MobileGeneral,
    EnquiryDescriptionGeneral,
    MarketingGeneral

    )VALUES (
    
    'NULL',
    '".$TitleGeneral."',
    '".$FirstNameGeneral."',
    '".$LastNameGeneral."',
    '".$AddressGeneral."',
    '".$TownGeneral."',
    '".$CountyGeneral."',
    '".$PostCodeGeneral."',
    '".$CountryGeneral."',
    '".$EmailGeneral."',
    '".$TelephoneGeneral."',
    '".$MobileGeneral."',
    '".$EnquiryDescriptionGeneral."',
    '".$MarketingGeneral."')";

mysql_query($query) or die ('Error updating db2');
/*echo "DB updateed with " .$Name;*/
include("&#46;&#46;/Home/Home.php")
?&gt;

</pre>]]></description>
		<pubDate>Sun, 07 Mar 2010 20:11:38 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32845-optimizing-php-file/</guid>
	</item>
	<item>
		<title>Newb Question: Printing All Prime Numbers B/W 1 And 100?</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32844-newb-question-printing-all-prime-numbers-bw-1-and-100/</link>
		<description><![CDATA[Hey, guys<br />
<br />
I had an account on here before, but had to make a new one. I suppose the boards were redone. Anyways, I am embarking on 9++ and have a program that prints the prime numbers between 1 and 100, but I can't figure out step-by-step why the code works. I tried to follow it, but I end up losing myself. Sad? I know. If someone can please explain, it would be appreciated. Thanks in advance. <br />
<br />
<pre class='prettyprint'>
// Find prime numbers between 1 and 100. 
 
#include &lt;iostream&gt; 
using namespace std; 
 
int main() {    
  int i, j; 
  bool isprime; 
 
  for(i=1; i &lt; 100; i++) { 
    isprime = true;  
 
    // see if the number is evenly divisible 
    for(j=2; j &lt;= i/2; j++) 
      // if it is, then its not prime 
      if((i%j) == 0) isprime = false; 
 
    if(isprime) 
      cout &lt;&lt; i &lt;&lt; " is prime.&#092;n"; 
  } 
 
  return 0; 
}
 </pre>]]></description>
		<pubDate>Sun, 07 Mar 2010 18:07:03 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32844-newb-question-printing-all-prime-numbers-bw-1-and-100/</guid>
	</item>
	<item>
		<title>Mac Spoofing In Vista</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32843-mac-spoofing-in-vista/</link>
		<description><![CDATA[Are there any USB network adapters that support MAC spoofing for Vista?<br />
Right now the network adapter card in my laptop is a Atheros AR5007 802.11b/g WiFi Adapter, and I've tried SMAC, Technitium and Hide my MAC Address software and no changes will take effect. I've even went in to the properties and put a value in the Network Address and rebooted and that didn't work either. So just want to know if anyone knows of an adapter that will let you do this.  I've scoured the net and am having a really hard time finding any successful MAC spoofing in Vista, maybe I'm just looking in the wrong place!  LOL!  Any advice would be appreciated!<br />
Thanks!]]></description>
		<pubDate>Sun, 07 Mar 2010 13:24:16 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32843-mac-spoofing-in-vista/</guid>
	</item>
	<item>
		<title>Telnet Tls Decryption</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32842-telnet-tls-decryption/</link>
		<description><![CDATA[Hi all,<br />
<br />
I would like to test the security on the connections to my IBM CICS server which is using TLS SSL protocol I am using wireshark and I have the private RSA key and have setup wireshark ssl preference to use the mentioned key<br />
ip,port,pro,path_to_key but apparently I am not getting the packets payload decrypted... <br />
<br />
can someone help ???!!!]]></description>
		<pubDate>Sun, 07 Mar 2010 11:14:06 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32842-telnet-tls-decryption/</guid>
	</item>
	<item>
		<title>Sql</title>
		<link>http://www.criticalsecurity.net/index.php/topic/32841-sql/</link>
		<description><![CDATA[In my website I have a form and when someone clicks the submit button I want all data to be validated and submitted to an sql database<br />
<br />
Now using j&#097;v&#097;script I have written a small script to make sure all field have been correctly filled in, how do i transfer this infomation to an sql database. I have <br />
<br />
I already have xampp installed and have apache and mysql local sever running<br />
<br />
Thanks <br />
<br />
Calypso]]></description>
		<pubDate>Sun, 07 Mar 2010 11:09:58 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32841-sql/</guid>
	</item>
	<item>
		<title><![CDATA[[Alg002] Implemented In Assembly (X86)]]></title>
		<link>http://www.criticalsecurity.net/index.php/topic/32840-alg002-implemented-in-assembly-x86/</link>
		<description><![CDATA[Disclaimer:<br />
Don't get discouraged if you feel this code is complicated - implementing ALG002 can be done a lot easier, especially if you're using a higher level language than assembly. This code is provided for those (like me) who prefer learning stuff by example. Assembly is very easy to learn, but quite hard to be able to write decent code in as it's so specific to the details of the task at hand.<br />
<br />
This project is set up much like in <a href='http://www.criticalsecurity.net/index.php/topic/32798-alg001-implemented-in-assembly-x86/' class='bbc_url' title='External link'>this thread</a>, that is, a Visual Studio project with both assembly and c/c++ code. This time a struct is also defined (although it could also have been just a pointer to a 208 byte large area as the c/c++ code hasn't any use for the data in the struct).<br />
<br />
First up is the header file:<br />
<pre class='prettyprint'>// alg002.h
#pragma once

#ifdef __cplusplus
extern "C" {
#endif
    typedef struct
    {
        unsigned int state&#91;3&#93;;
        unsigned int length;
        unsigned int buffer&#91;48&#93;;
    }
    ALG002_context;

    void extern ALG002_reset(ALG002_context* ctx);
    void extern ALG002_input(ALG002_context* ctx, void* input, unsigned int length);
    void extern ALG002_result(ALG002_context* ctx, unsigned char output&#91;8&#93;);
#ifdef __cplusplus
}
#endif
</pre><br />
Then it's the actual assembly code:<br />
<pre class='prettyprint'>; alg002.asm
.686
.XMM
.model flat, stdcall
option casemap:none

;===========================================;
;   Prototypes                              ;
;===========================================;
ALG002_reset    proto C ctx:DWORD
ALG002_input    proto C ctx:DWORD, src:DWORD, len:DWORD
ALG002_result   proto C ctx:DWORD, dst:DWORD
ALG002_process  proto C ctx:DWORD

;===========================================;
;   Constants                               ;
;===========================================;
C_ALG002_0      equ     010B6B4CCh
C_ALG002_1      equ     05C341141h
C_ALG002_2      equ     0E8CEA154h

;===========================================;
;   Structures                              ;
;===========================================;
ALG002_CTX  struc
    state   dd   3 dup (?)
    count   dd   ?
    buffer  dd  48 dup (?)
ALG002_CTX  ends

;===========================================;
;   Macros                                  ;
;===========================================;
round1  MACRO   a,b,c,i,t1,t2
    mov     eax,b
    not     eax
    and     eax,&#91;ebx&#93;.buffer&#91;i*4&#93;
    mov     ecx,b
    or      ecx,c
    xor     eax,ecx     ; eax = f
    lea     a,&#91;a+eax+t1-1&#93;
    sub     a,&#91;ebx&#93;.buffer&#91;i*4&#93;
    rol     a,t2
    add     a,b
    ENDM

round2  MACRO   a,b,c,i,t1,t2
    mov     eax,c
    mov     ecx,c
    not     eax
    or      ecx,&#91;ebx&#93;.buffer&#91;i*4&#93;
    and     eax,b
    xor     eax,ecx     ; eax = f
    lea     a,&#91;a+eax+t1-1&#93;
    sub     a,&#91;ebx&#93;.buffer&#91;i*4&#93;
    rol     a,t2
    add     a,b
    ENDM

round3  MACRO   a,b,c,i,t1,t2
    mov     eax,&#91;ebx&#93;.buffer&#91;i*4&#93;
    not     eax
    xor     eax,b
    xor     eax,c       ; eax = f
    lea     a,&#91;a+eax+t1-1&#93;
    sub     a,&#91;ebx&#93;.buffer&#91;i*4&#93;
    rol     a,t2
    add     a,b
    ENDM

;===========================================;


.data
padding db  80h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
        db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
        db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
        db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h


.code
;===============================================;
; In:   ctx (context)                           ;
; Out:  -nothing-                               ;
;===============================================;
ALG002_reset    proc C  ctx:DWORD
    push    ebx
    mov     ebx,ctx
    assume  ebx:ptr ALG002_CTX
    mov     &#91;ebx&#93;.state&#91;0*4&#93;,C_ALG002_0
    mov     &#91;ebx&#93;.state&#91;1*4&#93;,C_ALG002_1
    mov     &#91;ebx&#93;.state&#91;2*4&#93;,C_ALG002_2
    mov     &#91;ebx&#93;.count,0
    assume  ebx:nothing
    pop     ebx
    ret
ALG002_reset    endp

;===============================================;
; In:   ctx (context)                           ;
;       src (arbitrary block of data)           ;
;       len (number of octets of data)          ;
; Out:  -nothing-                               ;
;===============================================;
ALG002_input    proc C  ctx:DWORD, src:DWORD, len:DWORD
    pushad
    mov     ebx,ctx
    assume  ebx:ptr ALG002_CTX
    mov     ecx,len
    and     ecx,ecx
    jz      _done

    mov     esi,src
    mov     eax,&#91;ebx&#93;.count
    mov     edx,64
    and     eax,3Fh
    add     &#91;ebx&#93;.count,ecx
    sub     edx,eax
    lea     edi,&#91;ebx&#93;.buffer&#91;eax&#93;
    and     eax,eax
    jz      _skip
    cmp     ecx,edx
    jb      _skip
    sub     ecx,edx
@@: movsb
    dec     edx
    jnz     @b
    invoke  ALG002_process, ebx
    lea     edi,&#91;ebx&#93;.buffer
_skip:
    cmp     ecx,64
    jb      _skip2
    push    edi
    push    ecx
    lea     edi,&#91;ebx&#93;.buffer
    mov     ecx,16
    rep movsd
    invoke  ALG002_process, ebx
    pop     ecx
    pop     edi
    sub     ecx,64
    jmp     _skip
_skip2:
    rep movsb

_done:
    assume  ebx:nothing
    popad
    ret
ALG002_input    endp

;===============================================;
; In:   ctx (context)                           ;
; Out:  dst (64bit digest)                      ;
;===============================================;
ALG002_result   proc C  ctx:DWORD, dst:DWORD
    local   msglen:DWORD

    pushad
    mov     ebx,ctx
    assume  ebx:ptr ALG002_CTX
    mov     eax,&#91;ebx&#93;.count
    mov     ecx,eax
    shl     ecx,3
    mov     msglen,ecx

    and     eax,3Fh
    mov     ecx,60
    cmp     eax,60
    jl      @f
    add     ecx,64
@@: sub     ecx,eax
    invoke  ALG002_input, ebx, addr padding, ecx
    invoke  ALG002_input, ebx, addr msglen, 4

    mov     edi,dst
    mov     eax,&#91;ebx&#93;.state&#91;1*4&#93;
    mov     edx,&#91;ebx&#93;.state&#91;2*4&#93;
    mov     &#91;edi+0*4&#93;,eax
    mov     &#91;edi+1*4&#93;,edx

    assume  ebx:nothing
    popad
    ret
ALG002_result   endp

;===============================================;
; In:   ctx (context)                           ;
; Out:  -nothing-                               ;
;===============================================;
ALG002_process  proc C  ctx:DWORD
    pushad
    mov     ebx,ctx
    assume  ebx:ptr ALG002_CTX

    ; expand message block
    xor     ecx,ecx
_expand_msg:
    mov     eax,&#91;ebx&#93;.buffer&#91;ecx*4+ 0*4&#93;
    mov     edx,&#91;ebx&#93;.buffer&#91;ecx*4+ 2*4&#93;
    rol     edx,5
    xor     eax,edx
    mov     edx,&#91;ebx&#93;.buffer&#91;ecx*4+ 9*4&#93;
    shr     edx,2
    xor     eax,edx
    mov     edx,&#91;ebx&#93;.buffer&#91;ecx*4+15*4&#93;
    rol     edx,13
    xor     eax,edx
    mov     &#91;ebx&#93;.buffer&#91;ecx*4+16*4&#93;,eax
    inc     ecx
    cmp     ecx,32
    jne     _expand_msg

    ; get internal state
    mov     edx,&#91;ebx&#93;.state&#91;0*4&#93;
    mov     esi,&#91;ebx&#93;.state&#91;1*4&#93;
    mov     edi,&#91;ebx&#93;.state&#91;2*4&#93;

    ; do the rounds
    round1  edx,esi,edi, 0,0243F6A88h,11
    round1  edi,edx,esi, 1,085A308D3h, 3
    round1  esi,edi,edx, 2,013198A2Eh, 6
    round1  edx,esi,edi, 3,003707344h,19
    round1  edi,edx,esi, 4,0A4093822h,11
    round1  esi,edi,edx, 5,0299F31D0h, 3
    round1  edx,esi,edi, 6,0082EFA98h, 6
    round1  edi,edx,esi, 7,0EC4E6C89h,19
    round1  esi,edi,edx, 8,0452821E6h,11
    round1  edx,esi,edi, 9,038D01377h, 3
    round1  edi,edx,esi,10,0BE5466CFh, 6
    round1  esi,edi,edx,11,034E90C6Ch,19
    round1  edx,esi,edi,12,0C0AC29B7h,11
    round1  edi,edx,esi,13,0C97C50DDh, 3
    round1  esi,edi,edx,14,03F84D5B5h, 6
    round1  edx,esi,edi,15,0B5470917h,19

    round2  edi,edx,esi,16,09216D5D9h, 4
    round2  esi,edi,edx,17,08979FB1Bh,14
    round2  edx,esi,edi,18,0D1310BA6h,21
    round2  edi,edx,esi,19,098DFB5ACh, 2
    round2  esi,edi,edx,20,02FFD72DBh, 4
    round2  edx,esi,edi,21,0D01ADFB7h,14
    round2  edi,edx,esi,22,0B8E1AFEDh,21
    round2  esi,edi,edx,23,06A267E96h, 2
    round2  edx,esi,edi,24,0BA7C9045h, 4
    round2  edi,edx,esi,25,0F12C7F99h,14
    round2  esi,edi,edx,26,024A19947h,21
    round2  edx,esi,edi,27,0B3916CF7h, 2
    round2  edi,edx,esi,28,00801F2E2h, 4
    round2  esi,edi,edx,29,0858EFC16h,14
    round2  edx,esi,edi,30,0636920D8h,21
    round2  edi,edx,esi,31,071574E69h, 2

    round3  esi,edi,edx,32,0A458FEA3h,17
    round3  edx,esi,edi,33,0F4933D7Eh, 5
    round3  edi,edx,esi,34,00D95748Fh,28
    round3  esi,edi,edx,35,0728EB658h,18
    round3  edx,esi,edi,36,0718BCD58h,17
    round3  edi,edx,esi,37,082154AEEh, 5
    round3  esi,edi,edx,38,07B54A41Dh,28
    round3  edx,esi,edi,39,0C25A59B5h,18
    round3  edi,edx,esi,40,09C30D539h,17
    round3  esi,edi,edx,41,02AF26013h, 5
    round3  edx,esi,edi,42,0C5D1B023h,28
    round3  edi,edx,esi,43,0286085F0h,18
    round3  esi,edi,edx,44,0CA417918h,17
    round3  edx,esi,edi,45,0B8DB38EFh, 5
    round3  edi,edx,esi,46,08E79DCB0h,28
    round3  esi,edi,edx,47,0603A180Eh,18

    add     &#91;ebx&#93;.state&#91;0*4&#93;,edx
    add     &#91;ebx&#93;.state&#91;1*4&#93;,esi
    add     &#91;ebx&#93;.state&#91;2*4&#93;,edi
    assume  ebx:nothing
    popad
    ret
ALG002_process  endp

    end</pre><br />
All the procedures take (at least) one parameter which is a pointer to a ALG002_CTX structure. Use of <strong class='bbc'>assume</strong> allows us to tell the assembler that a register (ebx in this case) holds a pointer to a structure of a given type. This allows us to address offsets into said structure without having to calculate these by hand and, most importantly, any changes made to the struct are automatically reflected in the assembled code when this is taken care of by the assembler.<br />
<br />
It's good practice to add a 'assume &lt;register&gt;:nothing' whenever you're done using that register for the assumed purpose, as that will let the assembler warn you if you keep on using it for this later on. Beware, though, the assembler doesn't try to keep track of any changes to the given register so if I were to, for instance, change ebx half-way through ALG002_input and then continue using ebx as a ALG002_CTX pointer, the code would (most likely) fail horribly, yet the assembler would give any warnings.<br />
<br />
ALG002_reset simply set the states to their 'magic' values and zeroes the length. ALG002_input simply fills the internal buffer and calls ALG002_process whenever the buffer is full, while keeping track of how many bytes we've added (the number of bytes will be converted to number of bits at the very end). ALG002_result pads the input and appends the number of bits digested and then returns the digest which is state[1] and state[2].<br />
<br />
The actual hashing is being done in the ALG002_process procedure and here's what most of the interesting stuff is going on. As you may have noticed, I'm not doing the 'bit-mashing' in a loop but have unrolled it. Loops take time because of branching (multiple branches because of there being three different rounds) and stuff, but unrolling this has also another big advantage.<br />
<br />
Looking closely at the algorithm you may notice that the three internal state registers are rotated each step, i.e. c =&gt; a, b =&gt; c etc. This requires an extra register (or memory location) to accomplish and we're a bit short on registers (we could use ebp, though - or mmx/xmm registers). The actual rotating takes time as well.<br />
<br />
This rotating isn't actually neccesary, though. By using macros instead of 'regular code', we can easily rotate these registers in the parameter lists instead, or 'aliasing' them if you like (this is actually also done internally in the micro-code pipeline in the modern CPUs). It doesn't matter what the register is called as long as the expected value is in it, and that the expected register ends up with the result. Since we're executing these macros a total of 48 times, we've fully rotated the registers 16 times, thus leaving us with the changed states in the original registers (not that it'd be a problem to adjust for it if it were 32 iterations, though).<br />
<br />
Since we're using macros and writing one line for each iteration, there's no point in retrieving the values from <em class='bbc'>table1</em> and <em class='bbc'>table2</em>. Iteration 5 will always use the fifth entry of <em class='bbc'>table1</em> and the second entry of <em class='bbc'>table 2</em> so we'll save us the time/cost of looking it up and simply have the respective numbers as constants. Writing the list of 'macro-calls' may take some time but it's usually only done once.<br />
<br />
Looking at the three different macros you'll see that the first part is different between them, while the second part is the same. The first part calculates the <em class='bbc'>f</em> as given in the algorithm, while the second part is the calculating of the new b. We've gotten rid of the part where the registers are rotated, and by using different macro parameters we've gotten rid of the two table lookups.<br />
<br />
How I do that latter part may (initially) be a little hard to understand, though:<br />
<pre class='prettyprint'>    lea     a,&#91;a+eax+t1-1&#93;
    sub     a,&#91;ebx&#93;.buffer&#91;i*4&#93;</pre>is simply a shorter version of<pre class='prettyprint'>   add     a,eax
   mov     ecx,&#91;ebx&#93;.buffer&#91;i*4&#93;
   not     ecx
   add     a,t1
   add     a,ecx</pre>which shouldn't be hard to see that (keep in mind that a is used instead of b as we're not rotating the actual state registers) is basically the same as 'b = b + ((a + f + ~buffer[idx] + table1_val) &lt;&lt;&lt; table2_val)' from the algorithm description. But how can it be shortened like that two-liner above?<br />
<br />
Remember how adding the <a href='http://en.wikipedia.org/wiki/Two%27s_complement' class='bbc_url' title='External link'>two's complement</a> of a number is the same as subtracting it? Bitwise NOT done twice (or any even number of times) is the same as not doing it at all, so by subtracting the dword from the buffer rather than adding it, we're eliminating the need to put that value into a register just so that we can NOT it and then add it. Of course, that's just the ones' complement, so we also have to subtract one in order to get the (reverse) two's complement.<br />
<br />
'Luckily' (or, rather, by design) we're adding a constant value (from <em class='bbc'>table 1</em>), so all we have to do is subtract one from this value - thus this operation is eliminated as well. Now we're left with adding two registers and a constant value. The op-code lea may be used for this - actually adding reg + mul*reg + const, where mul is 1 - giving us <em class='bbc'>lea reg,[reg1+reg2+const]</em>.<br />
<br />
The complex lea op-code is translated into a series of simpler micro-code instructions where the CPU can execute out-of-order and use more (temporary) registers than we can, thus it's about as fast (depending on additional dependencies in the near code etc) and it's certainly smaller, making it more likely that the entire procedure may fit in the cache (not really of importance here, but when we start cracking hashes it wil be..). (I wonder how many compilers are able to optimize stuff like this to this level? I'm guessing that carefully hand-coded assembly still might have an edge over the professional compilers.. =P)<br />
<br />
Well, that's about it. I hope you learned something useful from this - and feel free to ask and/or comment, on this code or assembly in general.<br />
<br />
~pH7<br />
<br />
Edit:<br />
The code tag seems to have stopped preserving empty lines and that makes the code harder to read - sorry about that.. =/]]></description>
		<pubDate>Sat, 06 Mar 2010 14:44:43 +0000</pubDate>
		<guid>http://www.criticalsecurity.net/index.php/topic/32840-alg002-implemented-in-assembly-x86/</guid>
	</item>
</channel>
</rss>