프로세스에 c-dll을 주입하고 싶습니다. c-dll에서 golang으로 작성된 다른 dll을로드합니다. 내 C 코드는 다음과 같습니다.
loader.dll이로드되면 golang으로 작성된 worker.dll을 자동으로로드합니다.
// loader.c
#include <windows.h>
#include <stdio.h>
#include <memory.h>
typedef void (*StartWorker)();
HMODULE hWorker = NULL;
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
hWorker = LoadLibrary("D:\\code\\toys\\worker.dll");
if (hWorker == NULL)
{
exit(1);
}
StartWorker startWorker = (StartWorker)GetProcAddress(hWorker, "StartWorker");
MessageBox(NULL, "worker starting", TEXT("Warning:"), MB_OK);
if (startWorker == NULL)
{
MessageBox(NULL, "error", TEXT("Warning:"), MB_OK);
exit(1);
}
startWorker();
MessageBox(NULL, "worker started", TEXT("Warning:"), MB_OK);
FreeLibrary(hWorker);
break;
}
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
default:
break;
}
return TRUE;
}
이동 코드는 다음과 같습니다.
// worker.go
package main
/*
#include <stdlib.h>
#include <windows.h>
*/
import "C"
//export StartWorker
func StartWorker {
C.MessageBox(nil, C.CString("Hello Worker"), C.CString("Warning:"), 0)
}
func main() {
}
나는 그들을 MinGW-w64
. loader.dll이 worker.dll에서 호출하려고 할 때 StartWorker()
프로세스가 MessageBox를 표시하지 않았습니다. c에서 worker.dll을 다시 작성하면 모든 것이 잘 작동합니다. 그리고 StartWorker()
다음 코드로 호출해도 괜찮습니다 .
#include <windows.h>
#include <stdio.h>
#include <memory.h>
typedef void (*StartWorker)();
int main()
{
char *dllPath = "D:\\code\\toys\\loader.dll";
HMODULE hWorker = NULL;
hWorker = LoadLibrary(dllPath);
StartWorker startWorker = (StartWorker)GetProcAddress(hWorker, "StartWorker");
if (startWorker == NULL)
{
MessageBox(NULL, "dllPath", TEXT("Warning:"), MB_OK);
exit(1);
}
startWorker();
MessageBox(NULL, "target", TEXT("Warning:"), MB_OK);
FreeLibrary(hWorker);
return 0;
}
go-runtime과 충돌이 있는지 궁금합니다.
그 질문에 관심있는 모든 사람에게 감사드립니다. 함수를 구현하는 방법을 찾은 것 같습니다. 다음과 같이 새 코드를 작성합니다. 그들은 이제 잘 작동하고 있습니다.
package main
import "C"
import (
"fmt"
"net/http"
)
func sayHello(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("Hello World!"))
}
//export StartHttp
func StartHttp() {
http.HandleFunc("/", sayHello)
err := http.ListenAndServe("127.0.0.1:9999", nil)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Listening: http://127.0.0.1:9000")
}
func main() {
// StartHttp();
}
#include <windows.h>
#include <stdio.h>
// https://forum.pellesc.de/index.php?topic=4725.0
#ifdef __GNUC__
HANDLE k __attribute__((section(".shared"), shared)) = NULL;
#endif
#ifdef _MSC_VER
#pragma data_seg(".shared")
HANDLE k = NULL;
#pragma data_seg()
#pragma comment(linker, "/section:.shared,RWS")
#endif
typedef void (*StartHttp)();
HMODULE hHttp = NULL;
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
hHttp = LoadLibrary("http.dll");
StartHttp startWorker = (StartHttp)GetProcAddress(hHttp, "StartHttp");
k = startWorker;
// do not execute the function here!
break;
}
case DLL_PROCESS_DETACH:
{
FreeLibrary(hHttp);
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
default:
break;
}
return TRUE;
}
HANDLE GetHttpStarter()
{
return k;
}
#include <windows.h>
#include <stdio.h>
#include <memory.h>
typedef void (*StartHttp)();
typedef HMODULE (*GetHttpStarter)();
int main()
{
HMODULE hLoader = NULL;
hLoader = LoadLibrary("loader.dll");
GetHttpStarter getHttpStarter = (GetHttpStarter)GetProcAddress(hLoader, "GetHttpStarter");
StartHttp startHttp = (StartHttp)getHttpStarter();
startHttp();
printf("^^\n");
FreeLibrary(hLoader);
return 0;
}
> go build -buildmode=c-shared -o http.dll .\http.go
> gcc .\loader.c -shared -o loader.dll
> gcc .\client.c -o client.exe
> .\client.exe
내가 수정 한 가장 중요한 것은 단지로드이다 http.dll(go)
에서 loader.dll(c)
의 DllMain()
실행없이 http.dll(go)
의 기능 ', 그리고 공유 메모리에 이러한 기능에게 주소를 저장한다. 그래서 나는 http.dll(go)
의 내보내기 기능 GetHttpStarter()
을 호출하여 의 함수 주소를 얻을 수 있습니다 loader.dll(c)
. 복잡해 보이지만 작동합니다. :)
또한 dll injetion을 테스트 했으므로 결과적으로 http 서비스를 notepad.exe
지금 호스팅 할 수 있습니다 .D
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다