Skip to content

Commit eaa1c7b

Browse files
committed
Implement IsRuntimeCode() & bug fixes.
Add wiki images.
1 parent f3f24de commit eaa1c7b

File tree

5 files changed

+72
-8
lines changed

5 files changed

+72
-8
lines changed

porosity/porosity/Contract.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -1024,4 +1024,41 @@ Contract::decompile(
10241024

10251025
decompiled_code.print();
10261026
printf("LOC: %d\n", decompiled_code.loc());
1027+
}
1028+
1029+
bool
1030+
Contract::IsRuntimeCode(
1031+
bytes code
1032+
)
1033+
/*++
1034+
Description:
1035+
This function analyze the input bytecode to know if it is the runtime code.
1036+
If not it returns the offset of the runtime bytecode in m_runtimeOffset
1037+
--*/
1038+
{
1039+
bool hasCODECOPY = false;
1040+
bool leaveFunction = false;
1041+
1042+
dev::eth::eachInstruction(code, [&](uint32_t _offset, Instruction _instr, u256 const& _data) {
1043+
porosity::printInstruction(_offset, _instr, _data);
1044+
1045+
if (leaveFunction) {
1046+
if (hasCODECOPY && !m_runtimeOffset) {
1047+
m_runtimeOffset = _offset;
1048+
if (g_VerboseLevel >= 5) printf("Runtime function found at offset = 0x%x\n", _offset);
1049+
}
1050+
return;
1051+
}
1052+
1053+
switch (_instr) {
1054+
case Instruction::CODECOPY:
1055+
hasCODECOPY = true;
1056+
break;
1057+
case Instruction::RETURN:
1058+
leaveFunction = true;
1059+
break;
1060+
}
1061+
});
1062+
1063+
return !hasCODECOPY;
10271064
}

porosity/porosity/Contract.h

+17-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,17 @@ using namespace dev::eth;
2424
class Contract {
2525
public:
2626
Contract(bytes bytecode) {
27-
m_byteCodeRuntime = bytecode;
27+
m_byteCode = bytecode;
28+
if (IsRuntimeCode(bytecode)) {
29+
m_byteCodeRuntime = bytecode;
30+
}
31+
else {
32+
// In the caes IsRuntimeCode() didn't return the offset we move on.
33+
if (!m_runtimeOffset) return;
34+
35+
bytes runtimeCode(bytecode.begin() + m_runtimeOffset, bytecode.end());
36+
m_byteCodeRuntime = runtimeCode;
37+
}
2838

2939
getBasicBlocks();
3040
}
@@ -39,6 +49,11 @@ class Contract {
3949
void
4050
);
4151

52+
bool
53+
IsRuntimeCode(
54+
bytes bytecode
55+
);
56+
4257
string
4358
getGraphNodeColor(
4459
NodeType _type
@@ -240,5 +255,6 @@ class Contract {
240255
nlohmann::json m_abi_json;
241256
bytes m_byteCode;
242257
bytes m_byteCodeRuntime;
258+
uint32_t m_runtimeOffset = 0;
243259
};
244260
#endif

porosity/porosity/Debug.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ void debug() {
199199
amount","type":"uint256"}],"name":"Sent","type":"event"}]
200200
#endif
201201

202-
#if 0
202+
#if 1
203203
Contract Coin({ 0x60, 0x60, 0x60, 0x40, 0x52, 0x60, 0xe0, 0x60, 0x02, 0x0a, 0x60, 0x00, 0x35, 0x04, 0x63, 0x07, 0x54, 0x61, 0x72, 0x81, 0x14, 0x61, 0x00, 0x3c, 0x57, 0x80, 0x63, 0x27, 0xe2, 0x35, 0xe3, 0x14, 0x61, 0x00, 0x4e, 0x57, 0x80, 0x63, 0x40, 0xc1, 0x0f, 0x19, 0x14, 0x61, 0x00, 0x66, 0x57, 0x80, 0x63, 0xd0, 0x67, 0x9d, 0x34, 0x14, 0x61, 0x00, 0x8c, 0x57, 0x5b, 0x00, 0x5b, 0x61, 0x00, 0xbb, 0x60, 0x00, 0x54, 0x60, 0x01, 0x60, 0xa0, 0x60, 0x02, 0x0a, 0x03, 0x16, 0x81, 0x56, 0x5b, 0x61, 0x00, 0xbb, 0x60, 0x04, 0x35, 0x60, 0x01, 0x60, 0x20, 0x52, 0x60, 0x00, 0x90, 0x81, 0x52, 0x60, 0x40, 0x90, 0x20, 0x54, 0x81, 0x56, 0x5b, 0x61, 0x00, 0x3a, 0x60, 0x04, 0x35, 0x60, 0x24, 0x35, 0x60, 0x00, 0x54, 0x60, 0x01, 0x60, 0xa0, 0x60, 0x02, 0x0a, 0x03, 0x90, 0x81, 0x16, 0x33, 0x91, 0x90, 0x91, 0x16, 0x14, 0x61, 0x00, 0xc5, 0x57, 0x61, 0x00, 0xe4, 0x56, 0x5b, 0x61, 0x00, 0x3a, 0x60, 0x04, 0x35, 0x60, 0x24, 0x35, 0x60, 0x01, 0x60, 0xa0, 0x60, 0x02, 0x0a, 0x03, 0x33, 0x16, 0x60, 0x00, 0x90, 0x81, 0x52, 0x60, 0x01, 0x60, 0x20, 0x52, 0x60, 0x40, 0x90, 0x20, 0x54, 0x81, 0x90, 0x10, 0x15, 0x61, 0x00, 0xe8, 0x57, 0x61, 0x00, 0xe4, 0x56, 0x5b, 0x60, 0x60, 0x90, 0x81, 0x52, 0x60, 0x20, 0x90, 0xf3, 0x5b, 0x60, 0x01, 0x60, 0xa0, 0x60, 0x02, 0x0a, 0x03, 0x82, 0x16, 0x60, 0x00, 0x90, 0x81, 0x52, 0x60, 0x01, 0x60, 0x20, 0x52, 0x60, 0x40, 0x90, 0x20, 0x80, 0x54, 0x82, 0x01, 0x90, 0x55, 0x5b, 0x50, 0x50, 0x56, 0x5b, 0x60, 0x40, 0x60, 0x00, 0x81, 0x81, 0x20, 0x80, 0x54, 0x84, 0x90, 0x03, 0x90, 0x55, 0x60, 0x01, 0x60, 0xa0, 0x60, 0x02, 0x0a, 0x03, 0x80, 0x85, 0x16, 0x80, 0x83, 0x52, 0x92, 0x90, 0x91, 0x20, 0x80, 0x54, 0x84, 0x01, 0x90, 0x55, 0x33, 0x16, 0x60, 0x60, 0x90, 0x81, 0x52, 0x60, 0x80, 0x91, 0x90, 0x91, 0x52, 0x60, 0xa0, 0x82, 0x90, 0x52, 0x7f, 0x39, 0x90, 0xdb, 0x2d, 0x31, 0x86, 0x23, 0x02, 0xa6, 0x85, 0xe8, 0x08, 0x6b, 0x57, 0x55, 0x07, 0x2a, 0x6e, 0x2b, 0x5b, 0x78, 0x0a, 0xf1, 0xee, 0x81, 0xec, 0xe3, 0x5e, 0xe3, 0xcd, 0x33, 0x45, 0x90, 0x80, 0xa1, 0x50, 0x50, 0x56 });
204204
// .\solc.exe --bin-runtime --optimize E:\eth\simple.sol --abi --hashes
205205
if (g_VerboseLevel > 2) Coin.printInstructions();
@@ -230,7 +230,7 @@ void debug() {
230230

231231
#endif
232232

233-
#if 0
233+
#if 1
234234
Contract reverseMe(ThreeFuncMath);
235235
reverseMe.setABI("", "[{\"constant\":false,\"inputs\":[{\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"double\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"triple\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}], \"type\":\"function\"}]");
236236
reverseMe.setData({ 0xee, 0xe9, 0x72, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 });
@@ -247,6 +247,8 @@ void debug() {
247247
reverseMe.decompile(DOUBLE_FUNCTION_HASH);
248248
printf("------------\n");
249249
reverseMe.decompile(TRIPLE_FUNCTION_HASH);
250+
251+
printf("After execution.\n%s\n", reverseMe.getGraphviz(false).c_str());
250252
#endif
251253

252254
Contract vulnerable(VulnerableContract);

porosity/porosity/VMState.cpp

+14-5
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,21 @@ u256 address_mask("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
3131
#define IsStackEntryTypeTainted(type) (type & (UserInput | UserInputTainted))
3232
#define IsMasking160bitsAddress(x) ((x)->value.compare(address_mask) == 0)
3333

34+
#define IsStackIndexPresent(x) (m_stack.size() > x)
35+
3436
inline void
3537
VMState::SwapStackRegisters(
3638
uint32_t index_a,
3739
uint32_t index_b
3840
)
3941
{
40-
StackRegister oldValue = m_stack[index_a];
41-
StackRegister newValue = m_stack[index_b];
42+
if (IsStackIndexPresent(index_a) && IsStackIndexPresent(index_b)) {
43+
StackRegister oldValue = m_stack[index_a];
44+
StackRegister newValue = m_stack[index_b];
4245

43-
m_stack[index_b] = oldValue;
44-
m_stack[index_a] = newValue;
46+
m_stack[index_b] = oldValue;
47+
m_stack[index_a] = newValue;
48+
}
4549
}
4650

4751
std::string random_string(size_t length)
@@ -122,7 +126,12 @@ VMState::popStack(
122126
void
123127
)
124128
{
125-
m_stack.erase(m_stack.begin());
129+
if (m_stack.size()) {
130+
m_stack.erase(m_stack.begin());
131+
}
132+
else {
133+
printf("ERROR: Stack Underflow.\n");
134+
}
126135
}
127136

128137
bool

wiki/double-triple-cfg.png

53.8 KB
Loading

0 commit comments

Comments
 (0)