Browse Source

Random Code: smart opcode fuzz

cl-refactor
Dimitry 10 years ago
parent
commit
0021abf270
  1. 15
      test/fuzzTesting/createRandomStateTest.cpp
  2. 119
      test/fuzzTesting/fuzzHelper.cpp
  3. 41
      test/fuzzTesting/fuzzHelper.h

15
test/fuzzTesting/createRandomStateTest.cpp

@ -181,8 +181,15 @@ void doRandomCodeAlgo()
dev::test::RandomCodeOptions options;
options.setWeight(dev::eth::Instruction::STOP, 10); //default 50
options.setWeight(dev::eth::Instruction::SSTORE, 70);
string randomCode = dev::test::RandomCode::generate(10);
string randomData = dev::test::RandomCode::generate(10);
options.setWeight(dev::eth::Instruction::CALL, 75);
options.addAddress(Address("0xffffffffffffffffffffffffffffffffffffffff"));
options.addAddress(Address("0x1000000000000000000000000000000000000000"));
options.addAddress(Address("0x095e7baea6a6c7c4c2dfeb977efac326af552d87")); //coinbase
options.addAddress(Address("0x945304eb96065b2a98b57a48a06ae28d285a71b5"));
options.addAddress(Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"));
options.smartCodeProbability = 35;
string randomCode = dev::test::RandomCode::generate(10, options);
string randomData = dev::test::RandomCode::generate(10, options);
mValue v;
read_string(c_testExample, v);
@ -194,10 +201,10 @@ void doRandomCodeAlgo()
v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["data"] = "0x" + randomData;
// insert new value in tx
v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["value"] = dev::test::RandomCode::randomUniInt();
v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["value"] = dev::test::RandomCode::randomUniIntHex();
// insert new gasLimit in tx
v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["gasLimit"] = dev::test::RandomCode::randomUniInt();
v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["gasLimit"] = dev::test::RandomCode::randomUniIntHex();
// fill test
doStateTests(v);

119
test/fuzzTesting/fuzzHelper.cpp

@ -40,11 +40,11 @@ boostIntGenerator RandomCode::randOpCodeGen = boostIntGenerator(gen, opCodeDist)
boostIntGenerator RandomCode::randOpLengGen = boostIntGenerator(gen, opLengDist);
boostIntGenerator RandomCode::randUniIntGen = boostIntGenerator(gen, uniIntDist);
std::string RandomCode::rndByteSequence(int length)
std::string RandomCode::rndByteSequence(int length, SizeStrictness sizeType)
{
refreshSeed();
std::string hash;
length = std::max(1, length);
length = (sizeType == SizeStrictness::Strict) ? std::max(1, length) : randomUniInt() % length;
for (auto i = 0; i < length; i++)
{
uint8_t byte = randOpCodeGen();
@ -53,18 +53,6 @@ std::string RandomCode::rndByteSequence(int length)
return hash;
}
std::string RandomCode::fillArguments(int num)
{
std::string code;
for (auto i = 0; i < num; i++)
{
int length = randOpLengGen();
int pushCode = 96 + length - 1;
code += toCompactHex(pushCode) + rndByteSequence(length);
}
return code;
}
//generate smart random code
std::string RandomCode::generate(int maxOpNumber, RandomCodeOptions options)
{
@ -94,19 +82,25 @@ std::string RandomCode::generate(int maxOpNumber, RandomCodeOptions options)
}
}
else
code += fillArguments(info.args);
code += fillArguments((dev::eth::Instruction) opcode, options);
std::string byte = toCompactHex(opcode);
code += (byte == "") ? "00" : byte;
}
return code;
}
std::string RandomCode::randomUniInt()
std::string RandomCode::randomUniIntHex()
{
refreshSeed();
return "0x" + toCompactHex((int)randUniIntGen());
}
int RandomCode::randomUniInt()
{
refreshSeed();
return (int)randUniIntGen();
}
void RandomCode::refreshSeed()
{
auto now = std::chrono::steady_clock::now().time_since_epoch();
@ -114,6 +108,99 @@ void RandomCode::refreshSeed()
gen.seed(static_cast<unsigned int>(timeSinceEpoch));
}
std::string RandomCode::getPushCode(std::string hex)
{
int length = hex.length()/2;
int pushCode = 96 + length - 1;
return toCompactHex(pushCode) + hex;
}
std::string RandomCode::getPushCode(int value)
{
std::string hexString = toCompactHex(value);
return getPushCode(hexString);
}
std::string RandomCode::fillArguments(dev::eth::Instruction opcode, RandomCodeOptions options)
{
dev::eth::InstructionInfo info = dev::eth::instructionInfo(opcode);
std::string code;
bool smart = false;
unsigned num = info.args;
int rand = randOpCodeGen() % 100;
if (rand < options.smartCodeProbability)
smart = true;
if (smart)
{
switch (opcode)
{
case dev::eth::Instruction::CALL:
//(CALL gaslimit address value memstart1 memlen1 memstart2 memlen2)
code += getPushCode(randUniIntGen() % 32); //memlen2
code += getPushCode(randUniIntGen() % 32); //memstart2
code += getPushCode(randUniIntGen() % 32); //memlen1
code += getPushCode(randUniIntGen() % 32); //memlen1
code += getPushCode(randUniIntGen()); //value
code += getPushCode(toString(options.getRandomAddress()));//address
code += getPushCode(randUniIntGen()); //gaslimit
break;
default:
smart = false;
}
}
if (smart == false)
for (unsigned i = 0; i < num; i++)
{
//generate random parameters
int length = randOpLengGen();
code += getPushCode(rndByteSequence(length));
}
return code;
}
//Ramdom Code Options
RandomCodeOptions::RandomCodeOptions() : useUndefinedOpCodes(false), smartCodeProbability(50)
{
//each op code with same weight-probability
for (auto i = 0; i < 255; i++)
mapWeights.insert(std::pair<int, int>(i, 50));
setWeights();
}
void RandomCodeOptions::setWeight(dev::eth::Instruction opCode, int weight)
{
mapWeights.at((int)opCode) = weight;
setWeights();
}
void RandomCodeOptions::addAddress(dev::Address address)
{
addressList.push_back(address);
}
dev::Address RandomCodeOptions::getRandomAddress()
{
if (addressList.size() > 0)
{
int index = RandomCode::randomUniInt() % addressList.size();
return addressList[index];
}
return Address(RandomCode::rndByteSequence(20));
}
void RandomCodeOptions::setWeights()
{
std::vector<int> weights;
for (auto const& element: mapWeights)
weights.push_back(element.second);
opCodeProbability = boostDescreteDistrib(weights);
}
BOOST_AUTO_TEST_SUITE(RandomCodeTests)
BOOST_AUTO_TEST_CASE(rndCode)

41
test/fuzzTesting/fuzzHelper.h

@ -44,28 +44,24 @@ typedef boost::random::variate_generator<boost::mt19937&, boostDescreteDistrib >
struct RandomCodeOptions
{
public:
RandomCodeOptions() : useUndefinedOpCodes(false) {
//each op code with same weight-probability
for (auto i = 0; i < 255; i++)
mapWeights.insert(std::pair<int, int>(i, 50));
setWeights();
}
void setWeight(dev::eth::Instruction opCode, int weight)
{
mapWeights.at((int)opCode) = weight;
setWeights();
}
RandomCodeOptions();
void setWeight(dev::eth::Instruction opCode, int weight);
void addAddress(dev::Address address);
dev::Address getRandomAddress();
bool useUndefinedOpCodes;
int smartCodeProbability;
boostDescreteDistrib opCodeProbability;
private:
void setWeights()
{
std::vector<int> weights;
for (auto const& element: mapWeights)
weights.push_back(element.second);
opCodeProbability = boostDescreteDistrib(weights);
}
void setWeights();
std::map<int, int> mapWeights;
std::vector<dev::Address> addressList;
};
enum class SizeStrictness
{
Strict,
Random
};
class RandomCode
@ -75,13 +71,16 @@ public:
static std::string generate(int maxOpNumber = 1, RandomCodeOptions options = RandomCodeOptions());
/// Generate random byte string of a given length
static std::string rndByteSequence(int length = 1);
static std::string rndByteSequence(int length = 1, SizeStrictness sizeType = SizeStrictness::Strict);
/// Generate random uniForm Int with reasonable value 0..0x7fffffff
static std::string randomUniInt();
static std::string randomUniIntHex();
static int randomUniInt();
private:
static std::string fillArguments(int num);
static std::string fillArguments(dev::eth::Instruction opcode, RandomCodeOptions options);
static std::string getPushCode(int value);
static std::string getPushCode(std::string hex);
static void refreshSeed();
static boost::random::mt19937 gen; ///< Random generator

Loading…
Cancel
Save