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