This commit is contained in:
Print3M
2025-08-15 18:10:11 +02:00
commit ceae65b444
13 changed files with 832 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
{
"files.associations": {
"algorithm": "cpp",
"*.template": "c",
"cstdarg": "cpp",
"typeinfo": "c",
"functional": "cpp"
}
}
+30
View File
@@ -0,0 +1,30 @@
# DllShimmer
Compile everything:
```bash
x86_64-w64-mingw32-g++ -shared -o version.dll-shim shim.cpp version.def -static-libstdc++ -static-libgcc
```
Features:
- All functions implemented in the original DLL can be backdoored.
- Backdoored functions work as original, program doesn't crash.
- Forwarded functions are forwarded as original.
- Both MSVC (`#pragma comment`) and GCC forwarding (`.def file`) are supported.
Caveats:
1. Probably it doesn't work with floating-point parameters because they require different registers from va_list.
2. Original ordinal numbers of exported and forwarded functions are not preserved
3. There are some huge obfuscated DLLs with weird name mangling and tricks (e.g. Qt framework DLL). I don't recommend to use them as a backdoor base. Just use some normal DLL with 10-30 exported functions and it's going to work perfectly.
## Nowa architektura
Najlepiej by było, gdyby original.dll lądował w IAT backdoor.dll ze wszystkimi funkcjami. Wtedy mamy wszystko dostępne od razu, bez dodatkowego używania WinAPI.
Pojawia się wtedy problem, że nie można importować i eksportować tych samych symboli.
- Importuj oryginalne
Executable
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -ueo pipefail
go run main.go -i '7z.dll' -p '7z2.dll' --def 'dll.def' -m > shim.cpp
x86_64-w64-mingw32-g++ -shared shim.cpp dll.def -o 7z.dll-shim -static-libstdc++ -static-libgcc -D DEBUG=1
mv 7z.dll-shim ~/vm/Windows\ 11/shared/7z.dll
+53
View File
@@ -0,0 +1,53 @@
package cli
import (
"flag"
"fmt"
"os"
)
type CliFlags struct {
Input string
Proxy string
Mutex bool
}
func ParseCli() *CliFlags {
var flags CliFlags
flag.StringVar(&flags.Input, "i", "", "")
flag.StringVar(&flags.Input, "input", "", "")
flag.StringVar(&flags.Proxy, "p", "", "")
flag.StringVar(&flags.Proxy, "proxy", "", "")
flag.BoolVar(&flags.Mutex, "m", false, "")
flag.BoolVar(&flags.Mutex, "mutex", false, "")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: DllShimmer -i <path> -o <path> -p <path>\n")
fmt.Println()
fmt.Println("Usage:")
fmt.Println()
fmt.Printf(" %-24s %s\n", "-i, --input <path>", "Input DLL file (required)")
fmt.Printf(" %-24s %s\n", "-p, --proxy <path>", "Path to original DLL on target (required)")
fmt.Printf(" %-24s %s\n", "-m, --mutex", "Multiple execution prevention (default: false)")
fmt.Printf(" %-24s %s\n", "-h, --help", "Show this help")
fmt.Println()
fmt.Println("Example:")
fmt.Println()
fmt.Println(" DllShimmer -i version.dll -o shim.c -p 'C:\\Windows\\System32\\version.dll' -m")
fmt.Println()
fmt.Println("Created by Print3M (print3m.github.io)")
fmt.Println()
}
flag.Parse()
if flags.Input == "" || flags.Proxy == "" {
flag.Usage()
os.Exit(1)
}
return &flags
}
+68
View File
@@ -0,0 +1,68 @@
package def
import (
"log"
"os"
)
type exportedFunction struct {
OriginalName string
Rename string
Forwarder string
}
type DefFile struct {
DllName string
Path string
exportedFunctions []exportedFunction
}
func (d *DefFile) AddExportedFunction(name string) {
d.exportedFunctions = append(d.exportedFunctions, exportedFunction{
OriginalName: name,
})
}
func (d *DefFile) AddRenamedFunction(originalName string, rename string) {
d.exportedFunctions = append(d.exportedFunctions, exportedFunction{
OriginalName: originalName,
Rename: rename,
})
}
func (d *DefFile) AddForwardedFunction(originalName string, forwarder string) {
d.exportedFunctions = append(d.exportedFunctions, exportedFunction{
OriginalName: originalName,
Forwarder: forwarder,
})
}
func (d *DefFile) SaveFile() {
var content string
content += "LIBRARY \"" + d.DllName + "\"\n"
content += "EXPORTS\n"
for _, function := range d.exportedFunctions {
if function.Forwarder != "" {
// Forwarded functions
content += "\t" + function.OriginalName + "=" + function.Forwarder + "\n"
continue
}
if function.Rename != "" {
// Exported-renamed functions
content += "\t" + function.Rename + "=" + function.OriginalName + "\n"
continue
}
content += "\t" + function.OriginalName + "\n"
}
content += "\n"
err := os.WriteFile(d.Path, []byte(content), 0644)
if err != nil {
log.Fatalf("[!] Error while creating .def file: %v", err)
}
}
+43
View File
@@ -0,0 +1,43 @@
package dll
import (
"log"
"path/filepath"
peparser "github.com/saferwall/pe"
)
type ExportedFunction struct {
Name string
Forwarder string
}
type Dll struct {
Name string
ExportedFunctions []ExportedFunction
}
func ParseDll(dllPath string) *Dll {
var dll Dll
dll.Name = filepath.Base(dllPath)
pe, err := peparser.New(dllPath, &peparser.Options{})
if err != nil {
log.Fatalf("[!] Error while opening file: %s, reason: %v", dllPath, err)
}
err = pe.Parse()
if err != nil {
log.Fatalf("[!] Error while parsing file: %s, reason: %v", dllPath, err)
}
for _, function := range pe.Export.Functions {
dll.ExportedFunctions = append(dll.ExportedFunctions, ExportedFunction{
Name: function.Name,
Forwarder: function.Forwarder,
})
}
return &dll
}
+11
View File
@@ -0,0 +1,11 @@
module dllshimmer
go 1.23.1
require (
github.com/edsrzf/mmap-go v1.2.0 // indirect
github.com/saferwall/pe v1.5.7 // indirect
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.28.0 // indirect
)
+39
View File
@@ -0,0 +1,39 @@
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
github.com/edsrzf/mmap-go v1.2.0 h1:hXLYlkbaPzt1SaQk+anYwKSRNhufIDCchSPkUD6dD84=
github.com/edsrzf/mmap-go v1.2.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
github.com/saferwall/pe v1.5.7 h1:fxlRLvhyr+3cIs1yturWhWmgACIu147o+xSEYFlUAyA=
github.com/saferwall/pe v1.5.7/go.mod h1:mJx+PuptmNpoPFBNhWs/uDMFL/kTHVZIkg0d4OUJFbQ=
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d h1:RQqyEogx5J6wPdoxqL132b100j8KjcVHO1c0KLRoIhc=
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d/go.mod h1:PegD7EVqlN88z7TpCqH92hHP+GBpfomGCCnw1PFtNOA=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+63
View File
@@ -0,0 +1,63 @@
package main
import (
"dllshimmer/cli"
"dllshimmer/def"
"dllshimmer/dll"
"dllshimmer/tmpl"
"os/exec"
"path/filepath"
)
func main() {
flags := cli.ParseCli()
dll := dll.ParseDll(flags.Input)
var params tmpl.TemplateParams
params.Functions = dll.ExportedFunctions
params.ProxyDll = flags.Proxy
params.DllName = filepath.Base(flags.Input)
params.Mutex = flags.Mutex
tmpl.CreateShimCode(params)
// 1. Create temp .def based on original file
func() {
var def def.DefFile
def.DllName = params.DllName
def.Path = "tmp.def"
for _, function := range dll.ExportedFunctions {
if function.Forwarder == "" {
def.AddExportedFunction(function.Name)
} else {
def.AddForwardedFunction(function.Name, function.Forwarder)
}
}
def.SaveFile()
cmd := exec.Command("x86_64-w64-mingw32-dlltool", "-d", "tmp.def", "-l", "tmp.lib")
}()
// 2. Create new .def based on generated code
func() {
var def def.DefFile
def.DllName = params.DllName
def.Path = "exported.def"
for _, function := range dll.ExportedFunctions {
if function.Forwarder == "" {
def.AddRenamedFunction(function.Name, function.Name+"Fwd")
} else {
def.AddForwardedFunction(function.Name, function.Forwarder)
}
}
def.SaveFile()
}()
}
// DllShimmer -i version.dll -o "C:/Windows/System32/version.dll" -p ~/project -m
+271
View File
@@ -0,0 +1,271 @@
#include <stdio.h>
#include <iostream>
// Put your imports here...
// #------------------------------------------------------------------#
// | "DON'T TOUCH" ZONE |
// | (auto generated) |
// #------------------------------------------------------------------#
#define CreateDecoder CreateDecoderOriginal
#define CreateEncoder CreateEncoderOriginal
#define CreateObject CreateObjectOriginal
#define GetHandlerProperty GetHandlerPropertyOriginal
#define GetHandlerProperty2 GetHandlerProperty2Original
#define GetHashers GetHashersOriginal
#define GetIsArc GetIsArcOriginal
#define GetMethodProperty GetMethodPropertyOriginal
#define GetModuleProp GetModulePropOriginal
#define GetNumberOfFormats GetNumberOfFormatsOriginal
#define GetNumberOfMethods GetNumberOfMethodsOriginal
#define SetCaseSensitive SetCaseSensitiveOriginal
#define SetCodecs SetCodecsOriginal
#define SetLargePageMode SetLargePageModeOriginal
#include <windows.h>
#undef CreateDecoder
#undef CreateEncoder
#undef CreateObject
#undef GetHandlerProperty
#undef GetHandlerProperty2
#undef GetHashers
#undef GetIsArc
#undef GetMethodProperty
#undef GetModuleProp
#undef GetNumberOfFormats
#undef GetNumberOfMethods
#undef SetCaseSensitive
#undef SetCodecs
#undef SetLargePageMode
#define MUTEX(name) \
(CreateMutexA(NULL, TRUE, name) && GetLastError() != ERROR_ALREADY_EXISTS)
#define ARGS_COUNT 12
typedef uint64_t (*Func12)(
uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t, uint64_t, uint64_t
);
#define PROXY_FUNCTION(function) \
va_list ap; \
va_start(ap, arg1); \
uint64_t args[ARGS_COUNT]; \
args[0] = arg1; \
\
for (int i = 1; i < ARGS_COUNT ; i++) { \
args[i] = va_arg(ap, uint64_t); \
} \
\
va_end(ap); \
\
HMODULE hModule = LoadLibraryA("7z2.dll"); \
if (hModule == NULL) { \
printf("[!] 7z.dll: LoadLibraryA(7z2.dll) failed\n"); \
printf("\tError code: %lu\n", GetLastError()); \
} \
\
Func12 pFunction = (Func12) GetProcAddress(hModule, function); \
if (pFunction == NULL) { \
printf( \
"[!] 7z.dll: GetProcAddress(%s, 7z2.dll) failed\n", \
function ); \
printf("\tError code: %lu\n", GetLastError()); \
\
} \
\
return pFunction(args[0], args[1], args[2], args[3], args[4], args[5], \
args[6], args[7], args[8], args[9], args[10], args[11]); \
// ---- Forwarded functions ------------------------------------------
// #------------------------------------------------------------------#
// | END OF "DON'T TOUCH" ZONE |
// #------------------------------------------------------------------#
extern "C" __declspec(dllexport) UINT64 CreateDecoder(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: CreateDecoder called\n");
#endif
if (MUTEX("Global\\CreateDecoder__0")) {
// Put your code here...
}
PROXY_FUNCTION("CreateDecoder");
}
extern "C" __declspec(dllexport) UINT64 CreateEncoder(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: CreateEncoder called\n");
#endif
if (MUTEX("Global\\CreateEncoder__1")) {
// Put your code here...
}
PROXY_FUNCTION("CreateEncoder");
}
extern "C" __declspec(dllexport) UINT64 CreateObject(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: CreateObject called\n");
#endif
if (MUTEX("Global\\CreateObject__2")) {
// Put your code here...
}
PROXY_FUNCTION("CreateObject");
}
extern "C" __declspec(dllexport) UINT64 GetHandlerProperty(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: GetHandlerProperty called\n");
#endif
if (MUTEX("Global\\GetHandlerProperty__3")) {
// Put your code here...
}
PROXY_FUNCTION("GetHandlerProperty");
}
extern "C" __declspec(dllexport) UINT64 GetHandlerProperty2(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: GetHandlerProperty2 called\n");
#endif
if (MUTEX("Global\\GetHandlerProperty2__4")) {
// Put your code here...
}
PROXY_FUNCTION("GetHandlerProperty2");
}
extern "C" __declspec(dllexport) UINT64 GetHashers(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: GetHashers called\n");
#endif
if (MUTEX("Global\\GetHashers__5")) {
// Put your code here...
}
PROXY_FUNCTION("GetHashers");
}
extern "C" __declspec(dllexport) UINT64 GetIsArc(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: GetIsArc called\n");
#endif
if (MUTEX("Global\\GetIsArc__6")) {
// Put your code here...
}
PROXY_FUNCTION("GetIsArc");
}
extern "C" __declspec(dllexport) UINT64 GetMethodProperty(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: GetMethodProperty called\n");
#endif
if (MUTEX("Global\\GetMethodProperty__7")) {
// Put your code here...
}
PROXY_FUNCTION("GetMethodProperty");
}
extern "C" __declspec(dllexport) UINT64 GetModuleProp(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: GetModuleProp called\n");
#endif
if (MUTEX("Global\\GetModuleProp__8")) {
// Put your code here...
}
PROXY_FUNCTION("GetModuleProp");
}
extern "C" __declspec(dllexport) UINT64 GetNumberOfFormats(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: GetNumberOfFormats called\n");
#endif
if (MUTEX("Global\\GetNumberOfFormats__9")) {
// Put your code here...
}
PROXY_FUNCTION("GetNumberOfFormats");
}
extern "C" __declspec(dllexport) UINT64 GetNumberOfMethods(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: GetNumberOfMethods called\n");
#endif
if (MUTEX("Global\\GetNumberOfMethods__10")) {
// Put your code here...
}
PROXY_FUNCTION("GetNumberOfMethods");
}
extern "C" __declspec(dllexport) UINT64 SetCaseSensitive(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: SetCaseSensitive called\n");
#endif
if (MUTEX("Global\\SetCaseSensitive__11")) {
// Put your code here...
}
PROXY_FUNCTION("SetCaseSensitive");
}
extern "C" __declspec(dllexport) UINT64 SetCodecs(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: SetCodecs called\n");
#endif
if (MUTEX("Global\\SetCodecs__12")) {
// Put your code here...
}
PROXY_FUNCTION("SetCodecs");
}
extern "C" __declspec(dllexport) UINT64 SetLargePageMode(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] 7z.dll: SetLargePageMode called\n");
#endif
if (MUTEX("Global\\SetLargePageMode__13")) {
// Put your code here...
}
PROXY_FUNCTION("SetLargePageMode");
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH: {
#ifdef DEBUG
printf("[+] 7z.dll: DLL_PROCESS_ATTACH event\n");
#endif
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
+103
View File
@@ -0,0 +1,103 @@
#include <stdio.h>
#include <iostream>
// Put your imports here...
// #------------------------------------------------------------------#
// | "DON'T TOUCH" ZONE |
// | (auto generated) |
// #------------------------------------------------------------------#
{{- range .Functions}}
#define {{.Name}} {{.Name}}Original
{{- end}}
#include <windows.h>
{{- range .Functions}}
#undef {{.Name}}
{{- end}}
{{ $r := . }}
#define MUTEX(name) \
(CreateMutexA(NULL, TRUE, name) && GetLastError() != ERROR_ALREADY_EXISTS)
#define ARGS_COUNT 12
typedef uint64_t (*Func12)(
uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t, uint64_t, uint64_t
);
#define PROXY_FUNCTION(function) \
va_list ap; \
va_start(ap, arg1); \
uint64_t args[ARGS_COUNT]; \
args[0] = arg1; \
\
for (int i = 1; i < ARGS_COUNT ; i++) { \
args[i] = va_arg(ap, uint64_t); \
} \
\
va_end(ap); \
\
HMODULE hModule = LoadLibraryA("{{.ProxyDll}}"); \
if (hModule == NULL) { \
printf("[!] {{.DllName}}: LoadLibraryA({{.ProxyDll}}) failed\n"); \
printf("\tError code: %lu\n", GetLastError()); \
} \
\
Func12 pFunction = (Func12) GetProcAddress(hModule, function); \
if (pFunction == NULL) { \
printf( \
"[!] {{.DllName}}: GetProcAddress(%s, {{.ProxyDll}}) failed\n", \
function ); \
printf("\tError code: %lu\n", GetLastError()); \
\
} \
\
return pFunction(args[0], args[1], args[2], args[3], args[4], args[5], \
args[6], args[7], args[8], args[9], args[10], args[11]); \
// #------------------------------------------------------------------#
// | END OF "DON'T TOUCH" ZONE |
// #------------------------------------------------------------------#
{{- range $i, $v := .Functions }}
{{- if eq (len $v.Forwarder) 0 }}
__declspec(dllimport) UINT64 {{$v.Name}}(UINT64 arg1, ...);
extern "C" __declspec(dllexport) UINT64 {{$v.Name}}Fwd(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] {{$r.DllName}}: {{$v.Name}} called\n");
#endif
{{ if $r.Mutex }}
if (MUTEX("Global\\{{$v.Name}}__{{$i}}")) {
// Put your code here...
}
{{- else }}
// Put your code here...
{{- end }}
PROXY_FUNCTION("{{$v.Name}}");
}
{{- end }}
{{- end }}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH: {
#ifdef DEBUG
printf("[+] {{.DllName}}: DLL_PROCESS_ATTACH event\n");
#endif
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
+109
View File
@@ -0,0 +1,109 @@
#include <stdio.h>
#include <iostream>
// Put your imports here...
// #------------------------------------------------------------------#
// | "DON'T TOUCH" ZONE |
// | (auto generated) |
// #------------------------------------------------------------------#
{{- range .Functions}}
#define {{.Name}} {{.Name}}Original
{{- end}}
#include <windows.h>
{{- range .Functions}}
#undef {{.Name}}
{{- end}}
{{ $r := . }}
#define MUTEX(name) \
(CreateMutexA(NULL, TRUE, name) && GetLastError() != ERROR_ALREADY_EXISTS)
#define ARGS_COUNT 12
typedef uint64_t (*Func12)(
uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t, uint64_t, uint64_t
);
#define PROXY_FUNCTION(function) \
va_list ap; \
va_start(ap, arg1); \
uint64_t args[ARGS_COUNT]; \
args[0] = arg1; \
\
for (int i = 1; i < ARGS_COUNT ; i++) { \
args[i] = va_arg(ap, uint64_t); \
} \
\
va_end(ap); \
\
HMODULE hModule = LoadLibraryA("{{.ProxyDll}}"); \
if (hModule == NULL) { \
printf("[!] {{.DllName}}: LoadLibraryA({{.ProxyDll}}) failed\n"); \
printf("\tError code: %lu\n", GetLastError()); \
} \
\
Func12 pFunction = (Func12) GetProcAddress(hModule, function); \
if (pFunction == NULL) { \
printf( \
"[!] {{.DllName}}: GetProcAddress(%s, {{.ProxyDll}}) failed\n", \
function ); \
printf("\tError code: %lu\n", GetLastError()); \
\
} \
\
return pFunction(args[0], args[1], args[2], args[3], args[4], args[5], \
args[6], args[7], args[8], args[9], args[10], args[11]); \
// ---- Forwarded functions ------------------------------------------
{{- range .Functions }}
{{- if .Forwarder }}
#pragma comment(linker, "/EXPORT:{{.Name}}={{.Forwarder}}")
{{- end }}
{{- end }}
// #------------------------------------------------------------------#
// | END OF "DON'T TOUCH" ZONE |
// #------------------------------------------------------------------#
{{- range $i, $v := .Functions }}
{{- if eq (len $v.Forwarder) 0 }}
extern "C" __declspec(dllexport) UINT64 {{$v.Name}}(UINT64 arg1, ...) {
#ifdef DEBUG
printf("[+] {{$r.DllName}}: {{$v.Name}} called\n");
#endif
{{ if $r.Mutex }}
if (MUTEX("Global\\{{$v.Name}}__{{$i}}")) {
// Put your code here...
}
{{- else }}
// Put your code here...
{{- end }}
PROXY_FUNCTION("{{$v.Name}}");
}
{{- end }}
{{- end }}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH: {
#ifdef DEBUG
printf("[+] {{.DllName}}: DLL_PROCESS_ATTACH event\n");
#endif
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
+24
View File
@@ -0,0 +1,24 @@
package tmpl
import (
"dllshimmer/dll"
"log"
"os"
"text/template"
)
type TemplateParams struct {
Functions []dll.ExportedFunction
ProxyDll string
DllName string
Mutex bool
}
func CreateShimCode(params TemplateParams) {
tmpl := template.Must(template.ParseFiles("templates/shim.c.template"))
err := tmpl.Execute(os.Stdout, params)
if err != nil {
log.Fatalf("[!] Error of template engine: %v", err)
}
}