---
# System prepended metadata

title: sailfish

---

# sailfish

https://github.com/ucsb-seclab/sailfish

Используется ANGELIC-FLAG для построения модели, которая потом проверяется на SAT

reentrancy.sol интерпретирует путь исполнения, собирая value summary analysis для переменных. После этого, используя наложенные ограниченияна перменные, строится математическая модель и производится её решение.

Функции:
- do-solve(json-obj) - solver, принимает на вход загруженный symex_path.json
- interpret-path(i-scope, i-dest-daddrs, i-entry-daddr, attack?) - принимает scope, адрес назначения и адрес входа (в формате machine-get-saddr) и флаг атаки. Последовательно выполняет блоки начиная с точки входа и до точек выхода.
- machine-get-saddr(r-addr, r-scope) - r-addr@r-scope, преобразует относительные адреса в другой формат
- reg-make-type(r-name, r-type) - создаёт переменную с нужной структурой и сохраняет в register-hash
- interpret-block(i-scope, i-insts, dest?, attack?) - принимает scope, список инструкций, флаг назначения и атаки. Выполняет блок и возвращает адрес следующего блока.
- parse-code - строка инструкции преобразуется в структуру
- interpret-inst(i-scope, i-inst, attack?) - интерпретация инструкции

Глобальные объекты:
- block-hash - Хранилище для блоков - хранит в себе блоки инструкций
- register-hash - Хранилище для регистров - хранит в себе перменные, ANGELIC-FLAG

Последовательность вызова при обработке (single_function_malicious.sol):

```mermaid
flowchart TD
    Start[/Start/] 
    --> load_json(Загрузка JSON объекта из файла)
    -.-> do-solve(["do-solve(json-obj)"])
    --> init_json_struct(Инициализация парсинга json)
    --> set_angelic_flag(ANGELIC-FLAG = True) 
    --> load_global(Загрузка глобальных блоков инструкций __GLOBAL__)
    --> load_global_var(Инициализация глобальных перменных)
    --> global_var_interpret("Для каждой переменной вызывается interpret-path")
    -.-> interpret_path_start
    global_var_interpret
    
    subgraph interpret_block
        direction TB
        interpret_block_start[["interpret-block(i-scope, i-insts, dest?, attack?)"]]
        --> angelic_if_dest(Если dest? == True, ANGELIC-FLAG = True)
    end
    
    subgraph interpret_path
        direction TB
        interpret_path_start[["interpret-path(i-scope, i-dest-daddrs, i-entry-daddr, attack?)"]]
        --> check_entry{{Точка входа - пустая?}}
        -->|Да|interpret_path_fin(Конец функции)
        check_entry -->|Нет|interpret_2("Вызвать interpret-block() для точки входа, если текущий блок - одна из точек выхода, задать dest? = True")
        --> interpret_next{{interpret-block вернул адреса следующего блока?}}
        -->|Да|interpret_rec(Вызываем interpret-path для следующего блока) -.-> interpret_path_start
        interpret_next -->|Нет|interpret_path_fin
        interpret_2 -.-> interpret_block_start
    end
    

```

## Пометки
global vars:
```
json-global-vars => (
#hasheq((init . ()) (name . "block") (type . ("struct_block"))) 
#hasheq((init . ("0x6")) (name . "msg") (type . ("struct_msg"))) 
#hasheq((init . ()) (name . "now") (type . ("integer"))) 
#hasheq((init . ()) (name . "tx") (type . ("struct_tx"))) 
#hasheq((init . ("0x7")) (name . "this") (type . ("struct_this"))) 
#hasheq((init . ("0x8")) (name . "msg_sender") (type . ("integer"))) 
#hasheq((init . ()) (name . "addmod") (type . ("function3"))) 
#hasheq((init . ()) (name . "mulmod") (type . ("function3"))) 
#hasheq((init . ()) (name . "keccak") (type . ("function1"))) 
#hasheq((init . ()) (name . "sha256") (type . ("function1"))) 
#hasheq((init . ()) (name . "sha3") (type . ("integer"))) 
#hasheq((init . ()) (name . "ripemd160") (type . ("function1"))) 
#hasheq((init . ()) (name . "ecrecover") (type . ("function4"))) 
#hasheq((init . ()) (name . "blockhash") (type . ("function1"))) 
#hasheq((init . ()) (name . "userBalance") (type . ("array" "integer" "integer"))) 
#hasheq((init . ()) (name . "Reentrancy") (type . ("integer")))
)
```
У глобальных переменных в JSON есть поле "init" - оно содержит номер глобального блока который инициализирует эту перменную

Инструкция в виде структуры:
```
msg.sender = 0x6

i-inst => #(struct:inst "struct-assign#rs-rm-li" #("msg" "sender" "0x6"))
```

u-type??


Final registers example:
```
#zhash(
("REF_5" . {[TMP_1$1 (ite TMP_1$1 0 userBalance#6$0)] [(! TMP_1$1) zvoid]})
("CLR_11" . balance$0) 
("CLR_7" . 6) 
("CLR_13" . {[TMP_1$1 userBalance#6$0] [(! TMP_1$1) zvoid]}) 
("WRP_0" . (+ balance$0 (- userBalance#6$0))) 
("block_timestamp_swap" . timestamp$0) 
("block" . #zhash(("number" . number$0) 
                  ("timestamp" . timestamp$0) 
                  ("difficulty" . difficulty$0) 
                  ("coinbase" . coinbase$0) 
                  ("gaslimit" . gaslimit$0))) 
("this" . #zhash(("address" . 5) 
                 ("balance" . (+ balance$0 (- userBalance#6$0))))) 
("now" . now$0) 
("CLR_12" . {[TMP_1$1 6] [(! TMP_1$1) zvoid]}) 
("tx" . #zhash(("gasprice" . gasprice$0) 
               ("origin" . origin$0))) 
("Reentrancy" . Reentrancy$0)
("CLR_9" . 6)
("msg_sender" . 4)
("CLR_14" . {[TMP_1$1 6] [(! TMP_1$1) zvoid]})
("sha3" . sha3$0)
("msg" . #zhash(("data" . data$0) 
                ("sig" . sig$0) 
                ("value" . value$0) 
                ("sender" . 6))) 
("CLR_10" . userBalance#6$0) 
("REF_4" . userBalance#6$0) 
("CLR_15" . {[TMP_1$1 6] [(! TMP_1$1) zvoid]}) 
("ANGELIC-FLAG" . TMP_1$1) 
("tmp_now" . tmp_now$0) 
("TMP_1" . TMP_1$1) 
("TMP_3" . {[TMP_1$1 zvoid] [(! TMP_1$1) TMP_3$0]}) 
("tmp_block_timestamp" . tmp_block_timestamp$0) 
("msg_value_swap" . value$0) 
("tmp_msg_value" . tmp_msg_value$0) 
("userBalance" . (vector
                     userBalance#0$0
                     userBalance#1$0
                     userBalance#2$0
                     userBalance#3$0
                     userBalance#4$0
                     userBalance#5$0
                     (ite TMP_1$1 0 userBalance#6$0)
                     userBalance#7$0
                     userBalance#8$0
                     userBalance#9$0)) 
("CLR_16" . {[TMP_1$1 (ite TMP_1$1 0 userBalance#6$0)] [(! TMP_1$1) zvoid]})
("CLR_17" . {[TMP_1$1 6] [(! TMP_1$1) zvoid]})
("CLR_8" . userBalance#6$0) 
("now_swap" . now$0) 
("TMP_2" . (! TMP_1$1)))

```