upb
October 23rd, 2007, 23:14
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:oke(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:air<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
*/
.