Wie werden Funktionen im evm-Bytecode getrennt?

Ich möchte den Kontrollflussgraphen (CFG) aus dem Bytecode eines Smart-Contracts erstellen (vorausgesetzt, er wird durch Kompilieren einer Solidity-Quelldatei erhalten). Diese CFG soll auch die verschiedenen Methoden des Smart Contracts unterscheiden.

Gibt es eine Möglichkeit, dies zu tun?

Hi. Meinst du mit "separat" "kategorisieren"?
Nein, ich möchte wissen, wo eine Funktion beginnt und wo sie endet.

Antworten (2)

Wie werden Funktionen im evm-Bytecode getrennt?

Solidity erstellt am Anfang des Bytecodes einen Dispatcher-Block für Funktionsaufrufe. Ähnlich wie bei if .. elseif .. elseif .. else

Einzelne Funktionsaufrufe folgen dem folgenden sich wiederholenden Muster:

DUP1
PUSH4 <4-byte function signature>
EQ
PUSH2 <jumpdestination for the function>
JUMPI

Aus diesem Block können Sie die Funktionen rekonstruieren und ihr Sprungziel finden, allerdings haben Sie nur die 4-Byte-Signaturen und keine Namen aus dem Quellcode.

Zum Beispiel für diesen intelligenten Vertragscode:

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);
    }
}

Der Dispatcher sieht so aus:

...
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
...

Wenn es möglich ist, Smart Contracts direkt in Bytecode zu schreiben, dann ist es möglich, sie zu lesen und zu analysieren. In Anbetracht dessen, dass Bytecode Assembler mit LIFO-Stack ähnelt, ist es nicht lesefreundlich. Es gibt keinen Funktionsnamen, Variablennamen, Namen fehlen überhaupt. Hier ist eine ähnliche Frage zu Assembler https://reverseengineering.stackexchange.com/questions/10604/how-to-generate-cfg-from-assembly-instructions .

Dazu würde ich:

  • Opcodes lernen http://gavwood.com/paper.pdf

  • Check Remix, es gibt eine tolle Bytecode-Übersicht nach der Kompilierung (kann nützlich sein)

  • Überprüfen Sie das Projekt https://github.com/comaeio/porosity , um zu verstehen, wie es analysiert wird

    zum Beispiel:

    • Definieren Sie die Positionen von Opcodes
    • mögliche Tags erkennen durchJUMPDEST
    • Sprünge erkennen durch PUSH2 0x.... JUMP(kann als Funktionsaufruf übernommen werden)

Beachten Sie, dass das Ergebnis nach dem Kompilieren desselben Codes durch verschiedene Compilerversionen unterschiedlich sein kann, was bedeutet, dass der Kontrollfluss unterschiedlich sein kann.

Porocity CFG

porosity.exe --code 0x60... --cfg

Geben Sie hier die Bildbeschreibung ein

Ja, das weiß ich, aber ich suche etwas ähnliches wie Soot für das EVM. Soot ist in der Lage, die Felder und Methoden aus dem reinen JVM-Bytecode nachzubauen. Es sollte also möglich sein. Ich werde mir die Porosität ansehen (obwohl sie nicht mehr unterstützt wird :/).
@Briomkez Wenn Sie die Frage dekompilieren müssen, kann dies für Sie nützlich sein ethereum.stackexchange.com/questions/188/…
Danke, ja, ich suche nicht, um den genauen Quellcode neu zu erstellen, sondern nur um eine Darstellung ähnlich der Jimple-Darstellung von Soot zu haben: mit getrennten Feldern und Methoden
@Briomkez Bitte überprüfen Sie mein Update, ich hoffe, es hilft