upb

Doing it without Weird Hacks (tm) is even easier

Rating: 4 votes, 1.50 average.
why is this box so small?:P
Code:
/*
 * Import table maker (C) 2007 upb [at] preteam [dot] org
*/

#include <string>
#include <cassert>
#include <vector>
#include <map>
#include <sstream>
#include <iostream>
#include <iomanip>

typedef unsigned long DWORD;
typedef unsigned short WORD;

struct CornField
{
	typedef DWORD Groove;
	typedef std::vector<unsigned char> t_ground;

	void pick(std::stringstream& basket)
	{		
		for (t_ground::const_iterator iG = ground.begin(); iG != ground.end(); ++iG)
			basket << *iG;
	}

	class OneHundredPercentPureAsm
	{
		OneHundredPercentPureAsm(CornField& isNot, Groove& theSolution) : isNot(isNot), theSolution(theSolution) { }
		CornField& isNot;
		Groove& theSolution;
		
		public:
		void operator<<(WORD plant)
		{ 
			std::cout << "[" << std::hex << std::setw(4) << theSolution << "] W " << plant << std::endl;
			isNot.poke(theSolution, static_cast<t_ground::value_type>(plant & 0xFF));
			isNot.poke(theSolution, static_cast<t_ground::value_type>((plant >> 8) & 0xFF));
		};

		void operator<<(DWORD plant)
		{ 
			std::cout << "[" << std::hex << std::setw(4) << theSolution << "] D " << plant << std::endl;
			isNot.poke(theSolution, static_cast<t_ground::value_type>(plant & 0xFF));
			isNot.poke(theSolution, static_cast<t_ground::value_type>((plant >> 8) & 0xFF));
			isNot.poke(theSolution, static_cast<t_ground::value_type>((plant >> 16) & 0xFF));
			isNot.poke(theSolution, static_cast<t_ground::value_type>((plant >> 24) & 0xFF));
		};

		void operator<<(const std::string& plant)
		{
			std::cout << "[" << std::hex << std::setw(4) << theSolution << "] S " << plant << std::endl;
			for (std::string::const_iterator kw = plant.begin(); kw != plant.end(); kw++)
				isNot.poke(theSolution, static_cast<t_ground::value_type>(*kw));

			isNot.poke(theSolution, static_cast<t_ground::value_type>(0));
		};

		friend struct CornField;	// we become
	};

	OneHundredPercentPureAsm operator[](Groove& idx)
	{
		return OneHundredPercentPureAsm(*this, idx);
	}

	virtual void poke(Groove& target, t_ground::value_type seed)
	{
		if (ground.size() < target + 1)
			ground.resize(target + 1);
		ground[target++] = seed;
	}

	virtual Groove start() { return 0; }

	t_ground ground;
	friend class OneHundredPercentPureAsm;		// one
};

struct MirageCornField : public CornField
{
	MirageCornField(CornField::Groove horizonDistance) : CornField(), horizonDistance(horizonDistance) { }

	virtual Groove start() { return horizonDistance; }
	virtual void poke(Groove& target, t_ground::value_type seed)
	{
		Groove actual(target - horizonDistance);
		Groove old(actual);
		CornField::poke(actual, seed);

		target += actual - old;
	}

	private:
		CornField::Groove horizonDistance;
};

struct LibraryImport
{
	LibraryImport() : ordinal(0) { };
	LibraryImport(DWORD target, const std::string& name) : ordinal(0), target(target), name(name), hasName(true) { }
	LibraryImport(DWORD target, WORD ordinal) : target(target), ordinal(ordinal), hasName(false) { }

	void plant(CornField& cornField, CornField::Groove& hole, CornField::Groove& nest) const
	{
		if (!hasName)
		{
			cornField[hole] << static_cast<DWORD>(0x80000000 | ordinal);
		} else
		{
			cornField[hole] << nest;
			cornField[nest] << ordinal;
			cornField[nest] << name;
		}
	}

	DWORD target;
	std::string name;
	WORD ordinal;
	bool hasName;
};

typedef std::pair<std::string, LibraryImport> LibraryImportPair;

struct ImportLibrary
{
	ImportLibrary& operator<<(const LibraryImportPair& rhs)
	{
		name = rhs.first;
		return *this << rhs.second;	
	}

	ImportLibrary& operator<<(const LibraryImport& rhs)
	{
		if (imports.find(rhs.target) != imports.end())
			throw new exception("target occupied");

		imports[rhs.target] = rhs;
		return *this;
	}

	virtual void plant(CornField& cornField, CornField::Groove& libGroove, CornField::Groove& nameGroove) const
	{
		CornField::Groove hop(nameGroove);
		cornField[libGroove] << hop;											// OriginalFirstThunk
		
		nameGroove += sizeof(DWORD) * (imports.size() + 1);

		for (t_imports::const_iterator iImp = imports.begin(); iImp != imports.end(); ++iImp)
			iImp->second.plant(cornField, hop, nameGroove);		

		cornField[hop] << static_cast<DWORD>(0);

		cornField[libGroove] << static_cast<DWORD>(-1);			// TimeStamp
		cornField[libGroove] << static_cast<DWORD>(-1);			// ForwarderChain
		cornField[libGroove] << nameGroove;								// Name
		cornField[libGroove] << unbelievablyTrickyCalculation();	// FirstThunk

		cornField[nameGroove] << name;
	}
	
	DWORD unbelievablyTrickyCalculation() const
	{
		return imports.begin()->second.target;							// Assume webbits havent eaten any corn between
	}

	typedef std::map<DWORD, LibraryImport> t_imports;
	t_imports imports;
	std::string name;

	static const CornField::Groove	GrooveAllocation = sizeof(DWORD) * 5;
	static ImportLibrary* FieldEnd;
};

struct LastImportLibrary : public ImportLibrary
{
	virtual void plant(CornField& cornField, CornField::Groove& libGroove, CornField::Groove& nameGroove) const
	{
		cornField[libGroove] << static_cast<DWORD>(0);
		cornField[libGroove] << static_cast<DWORD>(0);
		cornField[libGroove] << static_cast<DWORD>(0);
		cornField[libGroove] << static_cast<DWORD>(0);
		cornField[libGroove] << static_cast<DWORD>(0);
	}
};

ImportLibrary* ImportLibrary::FieldEnd = new LastImportLibrary();

struct ImportDirectory
{
	typedef std::map<std::string, ImportLibrary> t_importLibraries;

	ImportDirectory& operator<<(const LibraryImportPair& rhs)
	{
		libraries[rhs.first] << rhs;
		return *this;
	}

	void plant(CornField& cornField) const
	{
		CornField::Groove libGroove = cornField.start();
		CornField::Groove libNameGroove = libGroove + (libraries.size() + 1 ) * ImportLibrary::GrooveAllocation;		

		for (t_importLibraries::const_iterator iLib = libraries.begin(); iLib != libraries.end(); ++iLib)
			iLib->second.plant(cornField, libGroove, libNameGroove);
		ImportLibrary::FieldEnd->plant(cornField, libGroove, libNameGroove);
	}

	t_importLibraries libraries;
};

 // <3 operator abuse
LibraryImportPair operator/(const std::string& lhs, const LibraryImport& rhs)
{
	return std::make_pair(lhs, rhs);
}

int main(int argc, char* argv[])
{
	MirageCornField field(0x0010000);
	ImportDirectory imports;
	imports << "kernel32.dll" / LibraryImport(0x11223300, "ExitProcess")
		<< "user32.dll" / LibraryImport(0x11224400, "DialogBoxParamA")
		<< "kernel32.dll" / LibraryImport(0x11223304, "ZzZzzZ")
		<< "kernel32.dll" / LibraryImport(0x11223308, "AaaAAAaExW");

	imports.plant(field);
	std::stringstream basket;
	field.pick(basket);

	for (size_t i = 0; i < basket.str().length(); ++i)
	{
		std::cout << std::hex << std::setw(2) << std::setfill('0') << (unsigned long)(basket.str()[i] & 0xFF) << ' ';
		if ((i + 1) % 16 == 0)
			std::cout << std::endl;
	}
	return 0;
}

/*
 * Warning to certain individuals: do not try to copy paste this code into tutorials, i will understand by the variable naming :p
*/
.

Submit "Doing it without Weird Hacks (tm) is even easier" to Digg Submit "Doing it without Weird Hacks (tm) is even easier" to del.icio.us Submit "Doing it without Weird Hacks (tm) is even easier" to StumbleUpon Submit "Doing it without Weird Hacks (tm) is even easier" to Google

Categories
Uncategorized

Comments