-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from devlights/add-dlopen-example
Add 16.C_dlopen_dlsym
- Loading branch information
Showing
10 changed files
with
155 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
capp | ||
libgolib.so | ||
libgolib.h | ||
main.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# これは何? | ||
|
||
cgoとdlopen関数を使って、既に存在している共有ライブラリ内の既存関数と全く同じ関数書式を持つ関数をcgo側で定義して、呼び出しをフックするサンプルです。 | ||
|
||
実行すると以下のようになります。 | ||
|
||
```sh | ||
$ task | ||
task: [build-clib] gcc -fPIC -shared -o libclib.so lib.c | ||
task: [build-golib] go build -o libgolib.so -buildmode=c-shared *.go | ||
task: [build-cprg] gcc -c -o main.o main.c | ||
task: [build-cprg] gcc -o capp main.o -L. -lgolib | ||
task: [default] LD_LIBRARY_PATH=. ./capp | ||
2024/03/25 02:36:06 [Go][インターセプト][my_strlen] result=10 | ||
my_strlen=10 | ||
task: [build-cprg-original] gcc -o capp main.o -Lclib -lclib | ||
task: [default] LD_LIBRARY_PATH=clib ./capp | ||
my_strlen=10 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# https://taskfile.dev | ||
|
||
version: '3' | ||
|
||
vars: | ||
CAPP_NAME: capp | ||
|
||
tasks: | ||
default: | ||
cmds: | ||
- task: build-clib | ||
- task: build-golib | ||
- task: build-cprg | ||
- LD_LIBRARY_PATH=. ./{{.CAPP_NAME}} | ||
- task: build-cprg-original | ||
- LD_LIBRARY_PATH=clib ./{{.CAPP_NAME}} | ||
build-clib: | ||
dir: clib | ||
cmds: | ||
- gcc -fPIC -shared -o libclib.so lib.c | ||
build-golib: | ||
cmds: | ||
- go build -o libgolib.so -buildmode=c-shared *.go | ||
build-cprg: | ||
cmds: | ||
- gcc -c -o main.o main.c | ||
- gcc -o {{.CAPP_NAME}} main.o -L. -lgolib | ||
build-cprg-original: | ||
cmds: | ||
- gcc -o {{.CAPP_NAME}} main.o -Lclib -lclib |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package main | ||
|
||
/* | ||
size_t call_my_strlen(void *fn, const char *s) { | ||
size_t (*my_strlen_fn)(const char *); | ||
my_strlen_fn = (size_t (*)(const char *))fn; | ||
return my_strlen_fn(s); | ||
} | ||
*/ | ||
import "C" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#include <string.h> | ||
|
||
size_t my_strlen(const char *s) { | ||
return strlen(s); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
extern size_t my_strlen(const char *s); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package dlopen | ||
|
||
/* | ||
#cgo LDFLAGS: -ldl | ||
#include <dlfcn.h> | ||
#include <stdlib.h> | ||
*/ | ||
import "C" | ||
import ( | ||
"unsafe" | ||
) | ||
|
||
func OpenLib(path string) unsafe.Pointer { | ||
var ( | ||
cPath = C.CString(path) | ||
cPathPtr = unsafe.Pointer(cPath) | ||
handle unsafe.Pointer | ||
) | ||
defer C.free(cPathPtr) | ||
|
||
handle = C.dlopen(cPath, C.RTLD_LAZY) | ||
return handle | ||
} | ||
|
||
func GetSym(handle unsafe.Pointer, symbol string) unsafe.Pointer { | ||
var ( | ||
cSymbol = C.CString(symbol) | ||
cSymbolPtr = unsafe.Pointer(cSymbol) | ||
funcPtr unsafe.Pointer | ||
) | ||
defer C.free(cSymbolPtr) | ||
|
||
// 本来、dlsym()を呼び出す前に dlerror() を呼び出し、エラー状態をクリアしてから | ||
// dlsym()を呼び出す。その後に、dlerror() でエラーを確認するのが正当な流れであるが割愛 | ||
|
||
funcPtr = C.dlsym(handle, cSymbol) | ||
return funcPtr | ||
} | ||
|
||
func CloseLib(handle unsafe.Pointer) { | ||
// 本来、dlclose()を呼び出す前に dlerror() を呼び出し、エラー状態をクリアしてから | ||
// dlclose()を呼び出す。その後に、dlerror() でエラーを確認するのが正当な流れであるが割愛 | ||
C.dlclose(handle) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package main | ||
|
||
/* | ||
extern size_t call_my_strlen(void *fn, const char *s); | ||
*/ | ||
import "C" | ||
import ( | ||
"log" | ||
"unsafe" | ||
|
||
"github.com/devlights/try-golang-cgo/16.C_dlopen_dlsym/dlopen" | ||
) | ||
|
||
//export my_strlen | ||
func my_strlen(cStr *C.char) C.size_t { | ||
var ( | ||
handle unsafe.Pointer | ||
symbol unsafe.Pointer | ||
result C.size_t | ||
) | ||
|
||
handle = dlopen.OpenLib("clib/libclib.so") | ||
defer dlopen.CloseLib(handle) | ||
|
||
symbol = dlopen.GetSym(handle, "my_strlen") | ||
result = C.call_my_strlen(symbol, cStr) | ||
|
||
log.Printf("[Go][インターセプト][my_strlen] result=%v", result) | ||
|
||
return result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include <stdio.h> | ||
#include "clib/lib.h" | ||
|
||
int main() { | ||
printf("my_strlen=%zu\n", my_strlen("helloworld")); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package main | ||
|
||
func main() {} |