¿Cómo separar funciones en bytecode evm?

Quiero construir el gráfico de flujo de control (CFG) a partir del código de bytes de un contrato inteligente (suponiendo que se obtenga al compilar un archivo fuente de Solidity). Este CFG también debería distinguir los diferentes métodos del contrato inteligente.

¿Hay una manera de hacerlo?

Hola. ¿Por "separar" te refieres a "categorizar"?
No, quiero saber dónde comienza y dónde termina una función.

Respuestas (2)

¿Cómo separar funciones en bytecode evm?

Solidity creará un bloque de despachador para llamadas de funciones al comienzo del código de bytes. Similar a un if .. elseif .. elseif .. else

Las llamadas de una sola función seguirán el siguiente patrón repetitivo:

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

Desde este bloque puede reconstruir las funciones y encontrar su destino de salto, sin embargo, solo tendrá las firmas de 4 bytes y ningún nombre del código fuente.

Por ejemplo, para este código de contrato inteligente:

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

El despachador se verá así:

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

Si es posible escribir contratos inteligentes en código de bytes directamente, entonces es posible leerlos y analizarlos. Teniendo en cuenta que el código de bytes es similar al ensamblador con pila LIFO, no es fácil de leer. No hay nombre de funciones, nombre de variables, nombres están ausentes en absoluto. Aquí hay una pregunta similar sobre el ensamblador https://reverseengineering.stackexchange.com/questions/10604/how-to-generate-cfg-from-assembly-instructions .

Para hacer esto yo haría:

  • aprende los códigos de operación http://gavwood.com/paper.pdf

  • verifique Remix, hay una descripción general increíble del código de bytes después de la compilación (puede ser útil)

  • verifique el proyecto https://github.com/comaeio/porosity para comprender cómo analizarlo

    por ejemplo:

    • definir ubicaciones de códigos de operación
    • detectar posibles etiquetas porJUMPDEST
    • detectar saltos por PUSH2 0x.... JUMP(puede asumir como llamada de función)

Tenga cuidado, el resultado puede ser diferente después de compilar el mismo código con diferentes versiones del compilador, lo que significa que el flujo de control puede ser diferente.

Porosidad CFG

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

ingrese la descripción de la imagen aquí

Sí, lo sé, pero estoy buscando algo similar a Soot para EVM. Soot puede reconstruir a partir del código de bytes JVM puro los campos y los métodos. Así que debería ser posible. Echaré un vistazo a la porosidad (aunque no es más compatible :/).
@Briomkez Si necesita descompilar la pregunta, puede serle útil ethereum.stackexchange.com/questions/188/…
Gracias, sí, no estoy buscando reconstruir el código fuente exacto, sino solo tener una representación similar a la representación Jimple de Soot: con campos y métodos separados
@Briomkez por favor revise mi actualización, espero que ayude