README improvements, new release

This commit is contained in:
Print3M
2025-08-23 14:56:45 +02:00
parent 1c64b0788c
commit 0d6b7c2a10
3 changed files with 58 additions and 35 deletions
+7 -7
View File
@@ -47,7 +47,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release delete 1.0.5 --cleanup-tag --yes || echo "No release or tag found for 1.0.5"
gh release delete 1.1.0 --cleanup-tag --yes || echo "No release or tag found for 1.1.0"
- name: Create Release
id: create_release
@@ -55,13 +55,13 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: 1.0.5
release_name: DllShimmer 1.0.5
tag_name: 1.1.0
release_name: DllShimmer 1.1.0
body: |
DllShimmer Weaponize DLL hijacking easily. Backdoor any function in any DLL.
- [x] GitHub Actions workflow improvements
- [x] Windows build improvements
- [x] Dynamic linking is now cached (both LoadLibraryA and GetProcAddress). Performance improved.
- [x] Better debug log format: timestamp added.
- [x] New parameter: `--debug-file`. Save debug logs to file.
- [x] README updated.
draft: false
prerelease: false
+11 -1
View File
@@ -71,10 +71,14 @@ Default: DllShimmer always uses dynamic linking with the `LoadLibraryA()` and `G
**`--debug-file <path>`** [optional]
Save debug logs to a file. Logs are written to a file on an ongoing basis while the program is running.
Save debug logs to a file. Logs are written to a file on an ongoing basis while the program is running. If selected, logs are not printed to STDOUT.
Default: DllShimmer always writes debug logs to STDOUT.
Example debug output:
![Example debug output](_img/img-2.png)
## Limitations
- Only x86-64 / AMD64 architecture is supported.
@@ -84,6 +88,12 @@ Default: DllShimmer always writes debug logs to STDOUT.
## Troubleshooting
Before you start troubleshooting:
1. Read "Limitations".
2. Make sure you don't use static linking (`--static`). It's easier to debug with dynamic linking (default).
3. Save debug output to file (`--debug-file`).
### _In the generated `.cpp` file, I don't see all the exported functions from the original DLL._
Functions defined in the original DLL as “forwarded” are not included in the `.cpp` file. However, they are visible in the `.def` file. They will also be exported after compilation, exactly as in the original DLL.
+40 -27
View File
@@ -8,27 +8,31 @@
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <unordered_map>
#include <string>
#define T UINT64
#define PARAMS \
T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, T a10, T a11, T a12
#define PARAMS T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, T a10, T a11, T a12
#define ARGS a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12
typedef T (*FuncPtr)(PARAMS);
typedef struct {
FILE *dbgOut;
HMODULE module;
std::unordered_map<std::string, FuncPtr> functions;
} Ctx;
Ctx CTX = {.dbgOut = NULL };
Ctx gCtx = { .dbgOut = NULL, .module = NULL };
void initDbg() {
if (CTX.dbgOut != NULL) return;
if (gCtx.dbgOut != NULL) return;
{{- if gt (len .DebugFile) 0 }}
CTX.dbgOut = fopen("{{.DebugFile}}", "w");
if (!CTX.dbgOut) {
gCtx.dbgOut = fopen("{{.DebugFile}}", "w");
if (!gCtx.dbgOut) {
MessageBoxA(
NULL,
"fopen({{.DebugFile}}) failed",
@@ -39,43 +43,39 @@ void initDbg() {
{{- else }}
CTX.dbgOut = stdout;
gCtx.dbgOut = stdout;
{{- end }}
}
char TIME_BUF[9]; // "HH:MM:SS" + null
char gTimeBuf[9]; // "HH:MM:SS" + null
char *getCurrentTime() {
time_t t = time(NULL);
struct tm lt;
localtime_s(&lt, &t);
strftime(TIME_BUF, sizeof(TIME_BUF), "%H:%M:%S", &lt);
strftime(gTimeBuf, sizeof(gTimeBuf), "%H:%M:%S", &lt);
return TIME_BUF;
return gTimeBuf;
}
void dbgf(const char *fmt, ...) {
if (CTX.dbgOut == NULL) {
if (gCtx.dbgOut == NULL) {
initDbg();
}
va_list ap;
va_start(ap, fmt);
fprintf(CTX.dbgOut, "[DBG] {{.DllName}} | %s | ", getCurrentTime());
vfprintf(CTX.dbgOut, fmt, ap);
fprintf(CTX.dbgOut, "\n");
fflush(CTX.dbgOut);
fprintf(gCtx.dbgOut, "[DBG] {{.DllName}} | %s | ", getCurrentTime());
vfprintf(gCtx.dbgOut, fmt, ap);
fprintf(gCtx.dbgOut, "\n");
fflush(gCtx.dbgOut);
va_end(ap);
}
void InitCache() {
}
void dbgCurrentDirectory() {
char buf[MAX_PATH];
DWORD len = GetCurrentDirectoryA(MAX_PATH, buf);
@@ -87,20 +87,35 @@ void dbgCurrentDirectory() {
dbgf("\tCurrent directory: '%s'", buf);
}
FuncPtr getProxyFunc(const char *funcName) {
HMODULE hModule = LoadLibraryA("{{.Original}}");
if (hModule == NULL) {
dbgf("LoadLibraryA({{.Original}}) failed");
dbgf("\tError code: %lu", GetLastError());
dbgCurrentDirectory();
// Module pointer is cached
if (gCtx.module == NULL) {
gCtx.module = LoadLibraryA("{{.Original}}");
if (gCtx.module == NULL) {
dbgf("LoadLibraryA({{.Original}}) failed");
dbgf("\tError code: %lu", GetLastError());
dbgCurrentDirectory();
return NULL;
}
}
FuncPtr pFunc = (FuncPtr)GetProcAddress(hModule, funcName);
std::string strFuncName(funcName);
// Function pointer is cached
if (gCtx.functions.find(strFuncName) != gCtx.functions.end()) {
return gCtx.functions[strFuncName];
}
FuncPtr pFunc = (FuncPtr)GetProcAddress(gCtx.module, funcName);
if (pFunc == NULL) {
dbgf("GetProcAddress(%s, {{.Original}}) failed", funcName);
dbgf("\tError code: %lu", GetLastError());
}
gCtx.functions[strFuncName] = pFunc;
return pFunc;
}
@@ -108,5 +123,3 @@ FuncPtr getProxyFunc(const char *funcName) {
(CreateMutexA(NULL, TRUE, name) && GetLastError() != ERROR_ALREADY_EXISTS)
#define PROXY_FUNCTION(funcName) getProxyFunc(funcName)(ARGS);
// TODO: Cache LoadLibraryA() and GetProcAddress() result