Как разделить функции в байт-коде evm?

Я хочу построить граф потока управления (CFG) из байт-кода смарт-контракта (при условии, что он получен путем компиляции исходного файла Solidity). Эта CFG также должна различать различные методы смарт-контракта.

Есть ли способ сделать это?

Всем привет. Под "отдельным" вы имеете в виду "категоризировать"?
Нет, я хочу знать, где начинается функция и где она заканчивается.

Ответы (2)

Как разделить функции в байт-коде 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

введите описание изображения здесь

Да, я это знаю, но я ищу что-то похожее на Soot для EVM. Soot может перестроить из чистого байт-кода JVM поля и методы. Так что это должно быть возможно. Я посмотрю на пористость (хотя она больше не поддерживается :/).
@Briomkez Если вам нужна декомпиляция, вопрос может быть вам полезен ethereum.stackexchange.com/questions/188/…
Спасибо, да, я не пытаюсь перестроить точный исходный код, а только для того, чтобы иметь представление, подобное представлению Soot's Jimple: с разделенными полями и методами
@Briomkez, пожалуйста, проверьте мое обновление, надеюсь, оно поможет