Skip to content

Remove unnecessary main function call in the generated wasm file #14

Closed
@9oelM

Description

@9oelM

Due to the compiler not being able to remove memset or memcpy or any other compiler builtin functions which must not be present in the hook code since it only can contain two functions which are $hook and $cbak, I poked around a lot and found that wasm32-wasi would not include any compiler builtins by default.

Below is the generated code with the target set as wasm32-wasi. Obviously because it doesn't do much, it doesn't have any reasons to insert compiler builtins anyway even if it were wasm32-unknown-unknown. But this is just to illustrate the problem that #![no_main] doesn't work yet for wasm32-wasi target.

Clearly, the main function is included.

(module
  (type (;0;) (func (result i32)))
  (type (;1;) (func))
  (type (;2;) (func (param i32)))
  (type (;3;) (func (param i32 i32) (result i32)))
  (type (;4;) (func (param i32 i32 i32 i32 i32) (result i64)))
  (type (;5;) (func (param i32 i32 i64) (result i64)))
  (type (;6;) (func (param i32) (result i64)))
  (import "env" "__main_void" (func (;0;) (type 0)))
  (import "env" "__wasm_call_dtors" (func (;1;) (type 1)))
  (import "env" "__wasi_proc_exit" (func (;2;) (type 2)))
  (import "env" "_g" (func (;3;) (type 3)))
  (import "env" "trace" (func (;4;) (type 4)))
  (import "env" "accept" (func (;5;) (type 5)))
  (func (;6;) (type 1))
  (func (;7;) (type 1)
    (local i32)
    block  ;; label = @1
      block  ;; label = @2
        i32.const 0
        i32.load offset=1048616
        br_if 0 (;@2;)
        i32.const 0
        i32.const 1
        i32.store offset=1048616
        call 6
        call 0
        local.set 0
        call 1
        local.get 0
        br_if 1 (;@1;)
        return
      end
      unreachable
      unreachable
    end
    local.get 0
    call 2
    unreachable)
  (func (;8;) (type 6) (param i32) (result i64)
    i64.const 0)
  (func (;9;) (type 6) (param i32) (result i64)
    (local i32)
    i32.const 0
    i32.const 0
    i32.load offset=1048620
    i32.const 1
    i32.add
    local.tee 1
    i32.store offset=1048620
    local.get 1
    i32.const 1
    call 3
    drop
    i32.const 1048576
    i32.const 18
    i32.const 1048594
    i32.const 0
    i32.const 0
    call 4
    drop
    i32.const 1048594
    i32.const 20
    i64.const 21
    call 5
    drop
    unreachable)
  (table (;0;) 1 1 funcref)
  (memory (;0;) 17)
  (global (;0;) (mut i32) (i32.const 1048576))
  (export "memory" (memory 0))
  (export "_start" (func 7))
  (export "cbak" (func 8))
  (export "hook" (func 9))
  (data (;0;) (i32.const 1048576) "accept.rs: Called.accept.rs: Finished."))

So I tried modifying the code into this, effectively just deleting the functions related to the main function call and modifying function indexes (types):

(module
  (type (;3;) (func (param i32 i32) (result i32)))
  (type (;4;) (func (param i32 i32 i32 i32 i32) (result i64)))
  (type (;5;) (func (param i32 i32 i64) (result i64)))
  (type (;6;) (func (param i32) (result i64)))
  (import "env" "_g" (func $_g (type 0)))
  (import "env" "trace" (func $trace (type 1)))
  (import "env" "accept" (func $accept (type 2)))
  (func $cbak (type 3) (param i32) (result i64)
    i64.const 0)
  (func $hook (type 3) (param i32) (result i64)
    (local i32)
    i32.const 0
    i32.const 0
    i32.load offset=1048620
    i32.const 1
    i32.add
    local.tee 1
    i32.store offset=1048620
    local.get 1
    i32.const 1
    call $_g
    drop
    i32.const 1048576
    i32.const 18
    i32.const 1048594
    i32.const 0
    i32.const 0
    call $trace
    drop
    i32.const 1048594
    i32.const 20
    i64.const 21
    call $accept
    drop
    unreachable)
  (table (;0;) 1 1 funcref)
  (memory (;0;) 17)
  (global $__stack_pointer (mut i32) (i32.const 1048576))
  (export "memory" (memory 0))
  (export "cbak" (func $cbak))
  (export "hook" (func $hook))
  (data $.rodata (i32.const 1048576) "accept.rs: Called.accept.rs: Finished."))

And this will pass the guard checker and be able to successfully run as a hook as well.

But the problem is idk how to remove the main function call with the config. Otherwise I would need to write some simple script using sth like to strip off these functions related to the main function call, since their placement and appearance is quite deterministic (because they don't do anything).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions