Last active
March 15, 2024 16:35
-
-
Save NaniteFactory/7a82b68e822b7d2de44037d6e7511734 to your computer and use it in GitHub Desktop.
An implementation example of DllMain() entrypoint with Golang. $ go build --buildmode=c-shared -o my.dll && rundll32.exe my.dll Test
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
package main | |
//#include "dllmain.h" | |
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
#include <windows.h> | |
void OnProcessAttach(HINSTANCE, DWORD, LPVOID); | |
typedef struct { | |
HINSTANCE hinstDLL; // handle to DLL module | |
DWORD fdwReason; // reason for calling function // reserved | |
LPVOID lpReserved; // reserved | |
} MyThreadParams; | |
DWORD WINAPI MyThreadFunction(LPVOID lpParam) { | |
MyThreadParams params = *((MyThreadParams*)lpParam); | |
OnProcessAttach(params.hinstDLL, params.fdwReason, params.lpReserved); | |
free(lpParam); | |
return 0; | |
} | |
BOOL WINAPI DllMain( | |
HINSTANCE _hinstDLL, // handle to DLL module | |
DWORD _fdwReason, // reason for calling function | |
LPVOID _lpReserved) // reserved | |
{ | |
switch (_fdwReason) { | |
case DLL_PROCESS_ATTACH: | |
// Initialize once for each new process. | |
// Return FALSE to fail DLL load. | |
{ | |
MyThreadParams* lpThrdParam = (MyThreadParams*)malloc(sizeof(MyThreadParams)); | |
lpThrdParam->hinstDLL = _hinstDLL; | |
lpThrdParam->fdwReason = _fdwReason; | |
lpThrdParam->lpReserved = _lpReserved; | |
HANDLE hThread = CreateThread(NULL, 0, MyThreadFunction, lpThrdParam, 0, NULL); | |
// CreateThread() because otherwise DllMain() is highly likely to deadlock. | |
} | |
break; | |
case DLL_PROCESS_DETACH: | |
// Perform any necessary cleanup. | |
break; | |
case DLL_THREAD_DETACH: | |
// Do thread-specific cleanup. | |
break; | |
case DLL_THREAD_ATTACH: | |
// Do thread-specific initialization. | |
break; | |
} | |
return TRUE; // Successful. | |
} |
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
package main | |
import "C" | |
import ( | |
"unsafe" | |
"github.com/nanitefactory/winmb" | |
) | |
//export Test | |
func Test() { | |
winmb.MessageBoxPlain("export Test", "export Test") | |
} | |
// OnProcessAttach is an async callback (hook). | |
//export OnProcessAttach | |
func OnProcessAttach( | |
hinstDLL unsafe.Pointer, // handle to DLL module | |
fdwReason uint32, // reason for calling function | |
lpReserved unsafe.Pointer, // reserved | |
) { | |
winmb.MessageBoxPlain("DLL_PROCESS_ATTACH", "DLL_PROCESS_ATTACH") | |
} | |
func main() { | |
// nothing really. xD | |
} |
golang can even be used to make internal game cheats... wow.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
function exported by golang a.k.a OnProcessAttach translates in uint32 in x64 systems to unsigned int, while uint64 translates to long long unsigned int, giving trouble because DWORD is long unsigned int, any clue?