Update ---> I ended up putting all the initialization of import in the osinit() function in os_windows.go. So in osinit() I have something like
``` func osinit () { _AddVectoredContinueHandler = stdFunction(unsafe.Pointer(GetProcAddressReplacement(GetModuleHandleReplacement("ntdll.dll"), "RtlAddVectoredContinueHandler"))) _AddVectoredExceptionHandler = stdFunction(unsafe.Pointer(GetProcAddressReplacement(GetModuleHandleReplacement("ntdll.dll"), "RtlAddVectoredExceptionHandler"))) _CloseHandle = stdFunction(unsafe.Pointer(GetProcAddressReplacement(GetModuleHandleReplacement("kernel32.dll"), "CloseHandle"))) ... ``` With that I was able to delete all the cgo_import_dynamic ... ALL EXCEPT the tlsAlloc one !!!!! It is driving me crazy !!!!! It seems I cannot get rid of //go:cgo_import_dynamic of TlsAlloc, even if I initialise in osinit() like the others !!!! I noticed that TlsAlloc is called by wintls that is called by rt0_go if the GOOS is windows. I tried to create a function ``` func initTls() { _tlsAlloc = stdFunction(unsafe.Pointer(GetProcAddressReplacement(GetModuleHandleReplacement("kernel32.dll"), "tlsAlloc"))) } ``` Then just before wintls in rt0_go add ``` CALL runtime.initTls(SB) ``` This compile but initTls is never executed. My guess is that TlsAlloc is used to allocate memory for the function in runtime package to run ... So I cannot run any go code before doing TlsAlloc, which in turn make my GetProcAddressReplacement(GetModuleHandleReplacement("kernel32.dll"), "tlsAlloc")) not valid because no memory is allocated for them to run in the thread ... So yeah, in the end it is a shame that I was able to get rid of the IAT except for TlsAlloc :( Le dimanche 20 octobre 2024 à 09:57:32 UTC+2, rudeus greyrat a écrit : > Why do you want that? ---> Lots of reasons > > - Less AV detection for exe compiled by Go from Virustotal > > > - More control on the IAT in exe (I can fine tune detection) > > > - Combined with -buildmode=pie I am closer on getting a shellcode > > > About the last point, I am studying if it is possible to compile a go exe > --> extract .text ---> run the thing in memory. Basically I know it will be > impossible unless I really modify the toolchain to have > > 1. no pdata ---> still haven't done it > 2. no .data ---> still haven't done it > 3. no IAT ---> doing now > 4. pie code ---> already done with buildmode > > Basically what I am trying to simulate is something like the donut project > but in native go ... > It is all for educational purposes and fun and learn how go works ofc. > > > > > Anyways for my problem above , I found a solution that works. > > I just declared a function in os_windows.go > ``` > func InitalizeImports() { > println("Started Init") > _AddVectoredContinueHandler = > stdFunction(unsafe.Pointer(GetProcAddressReplacement(GetModuleHandleReplacement("ntdll.dll"), > > "RtlAddVectoredContinueHandler"))) > _AddVectoredExceptionHandler = > stdFunction(unsafe.Pointer(GetProcAddressReplacement(GetModuleHandleReplacement("ntdll.dll"), > > "RtlAddVectoredExceptionHandler"))) > _CloseHandle = > stdFunction(unsafe.Pointer(GetProcAddressReplacement(GetModuleHandleReplacement("kernel32.dll"), > > "CloseHandle"))) > _CreateEventA = > stdFunction(unsafe.Pointer(GetProcAddressReplacement(GetModuleHandleReplacement("kernel32.dll"), > > "CreateEventA"))) > } > ``` > > That I call in signal_windows.go (seems the first place where winapi call > are needed for now) > ``` > func initExceptionHandler() { > InitalizeImports() > stdcall2(_AddVectoredExceptionHandler, 1, abi.FuncPCABI0(exceptiontramp)) > if GOARCH == "386" { > // use SetUnhandledExceptionFilter for windows-386. > // note: SetUnhandledExceptionFilter handler won't be called, if debugging. > stdcall1(_SetUnhandledExceptionFilter, abi.FuncPCABI0(lastcontinuetramp)) > } else { > stdcall2(_AddVectoredContinueHandler, 1, > abi.FuncPCABI0(firstcontinuetramp)) > stdcall2(_AddVectoredContinueHandler, 0, abi.FuncPCABI0(lastcontinuetramp)) > } > } > ``` > > Then I can delete the cgo_import_dynamic of the defined api call, and all > the exe compiled with the new toolchain are working and does not contain > _AddVectoredContinueHandler, > _AddVectoredExceptionHandler, _CloseHandle, _CreateEventA in the IAT. > > Thanks > Rudeus Greyrat > > > > > Le dimanche 20 octobre 2024 à 05:27:14 UTC+2, Ian Lance Taylor a écrit : > >> On Sat, Oct 19, 2024 at 8:11 PM rudeus greyrat >> <rudeusqu...@gmail.com> wrote: >> > >> > I want to have an empty IAT when I compile go exe. >> >> Why do you want that? >> >> >> > I noticed that all the imports in the IAT are because of a file in go >> runtime package called >> https://github.com/golang/go/blob/master/src/runtime/os_windows.go >> > >> > So having ```//go:cgo_import_dynamic runtime._CloseHandle CloseHandle%1 >> "kernel32.dll"``` will result in the address of CloseHandle winapi being in >> the local variable _CloseHandle and resulting in CloseHandle appearing in >> the import table. >> > >> > I was not able to understand what cgo_import_dynamic really does (nor >> find the code behind it). >> >> The //go:cgo_import_dynamic directive is documented in the long >> "implementation details" comment in cmd/cgo/doc.go. >> >> Ian >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/77bcdeb7-6453-43eb-8f5d-4064ff6db62en%40googlegroups.com.