Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
9oelM opened this issue Sep 16, 2023 · 1 comment · Fixed by #13
Closed

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

9oelM opened this issue Sep 16, 2023 · 1 comment · Fixed by #13

Comments

@9oelM
Copy link
Member

9oelM commented Sep 16, 2023

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

@9oelM
Copy link
Member Author

9oelM commented Sep 16, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant