Log in

View Full Version : Doing it without Weird Hacks (tm) is even easier


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
*/

.

Kayaker
October 23rd, 2007, 23:54
I hate to post a blog comment that isn't a comment on the blog post, but you asked.. (I'm assuming this is what you meant)

Quote:
[Originally Posted by upb;69765]why is this box so small?:P


Why are your indents so large?

The vBulletin bbcode CODE tags, which are just formatted PRE tags, have a set width of 640px. This is probably to accomodate the smaller width "non-Liquid" style, which you can set in your User Control Panel or from the checkbox at the bottom left of the page.
Notice it looks even worse on the original Blog page, the PRE setting is for width: 410px; (one benefit of moving our style of blogging to a forum)

It's always kind of bugged me too, for the sake of a few characters suddenly the horizontal scroll bar kicks in when there is space left with the "Liquid" style to accomodate a nicer looking CODE block without the scroll bars. I could try to modify that to have a variable percentage width for CODE tags, but it would mean also taking into account the current users selection for page style, as well as their postbit setting (where name/join date/posts info stuff is) which can be on the left side (taking up room) or on top. I'll put it on the TODO list of vbulletin hacks I'm working on (about 6th in line at this point

Cheers,
Kayaker