I want to build the control-flow-graph (CFG) from the bytecode of a smart-contract (assuming it is obtained by compiling a Solidity source file). This CFG should also distinguish the different methods of the smart contract.
Is there a way to do so?
I want to build the control-flow-graph (CFG) from the bytecode of a smart-contract (assuming it is obtained by compiling a Solidity source file). This CFG should also distinguish the different methods of the smart contract.
Is there a way to do so?
How to separate functions in evm bytecode?
Solidity will create a dispatcher block for function calls at the beginning of the bytecode. Similar to an if .. elseif .. elseif .. else
Single function calls will follow the following repeating pattern:
DUP1
PUSH4 <4-byte function signature>
EQ
PUSH2 <jumpdestination for the function>
JUMPI
From this block you can reconstruct the functions and find their jump destination, however, you will only have the 4-byte signatures and no names from the source code.
For instance for this smart contract code:
contract X {
uint x;
uint y;
function a(uint u) public {
x = u;
}
function b(uint v) public {
y = v;
}
function t(uint v) public {
a(v);
b(v);
}
function () {
t(1);
}
}
The dispatcher will look like this:
...
054 DUP1
055 PUSH4 afe29f71
060 EQ
061 PUSH2 0070
064 JUMPI
065 DUP1
066 PUSH4 cd580ff3
071 EQ
072 PUSH2 009d
075 JUMPI
076 DUP1
077 PUSH4 f0fdf834
082 EQ
083 PUSH2 00ca
086 JUMPI
...
If it is possible to write smart contracts in bytecode directly, then it is possible to read and analyze it. Taking in account that bytecode is similar to assembler with LIFO stack, it not friendly to read. There in no functions' name, variables' name, names are absent at all. Here is similar question about assembler https://reverseengineering.stackexchange.com/questions/10604/how-to-generate-cfg-from-assembly-instructions.
In order to do this I would:
learn opcodes http://gavwood.com/paper.pdf
check Remix, there is awesome bytecode overview after compilation (can be useful)
check project https://github.com/comaeio/porosity to understand how to parse it
for instance:
JUMPDEST
PUSH2 0x.... JUMP
(can assume as function call)Beware the result can be different after compiling of same code by different versions of compiler, means control-flow can be different.
Porocity CFG
porosity.exe --code 0x60... --cfg