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?
¿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:
JUMPDEST
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
Richard Horrocks
Ehsan Goharshady