Я хочу построить граф потока управления (CFG) из байт-кода смарт-контракта (при условии, что он получен путем компиляции исходного файла Solidity). Эта CFG также должна различать различные методы смарт-контракта.
Есть ли способ сделать это?
Как разделить функции в байт-коде evm?
Solidity создаст блок диспетчера для вызовов функций в начале байт-кода. Похоже на if .. elseif .. elseif .. else
Одиночные вызовы функций будут следовать следующему повторяющемуся шаблону:
DUP1
PUSH4 <4-byte function signature>
EQ
PUSH2 <jumpdestination for the function>
JUMPI
Из этого блока вы можете реконструировать функции и найти место их перехода, однако у вас будут только 4-байтовые подписи и никаких имен из исходного кода.
Например, для этого кода смарт-контракта:
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);
}
}
Диспетчер будет выглядеть так:
...
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
...
Если можно писать смарт-контракты напрямую в байт-коде, значит, его можно читать и анализировать. Учитывая, что байт-код похож на ассемблер со стеком LIFO, читать его неудобно. Там нет имени функции, имени переменной, имена вообще отсутствуют. Вот аналогичный вопрос об ассемблере https://reverseengineering.stackexchange.com/questions/10604/how-to-generate-cfg-from-assembly-instructions .
Для этого я бы:
узнать коды операций http://gavwood.com/paper.pdf
проверьте Remix, есть отличный обзор байт-кода после компиляции (может быть полезным)
проверьте проект https://github.com/comaeio/porosity , чтобы понять, как его анализировать
например:
JUMPDEST
PUSH2 0x.... JUMP
(можно считать вызовом функции)Остерегайтесь, что результат может отличаться после компиляции одного и того же кода разными версиями компилятора, что означает, что поток управления может быть другим.
Пористость КФГ
porosity.exe --code 0x60... --cfg
Ричард Хоррокс
Эхсан Гохаршади