mirror of
https://github.com/luanslimadev/Wand-Enhancer.git
synced 2026-08-28 17:01:05 +00:00
feat: add asar bypass core library
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
# Build directories
|
||||
/build/
|
||||
/build-debug/
|
||||
/build-release/
|
||||
/out/
|
||||
|
||||
# CMake generated files
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
CTestTestfile.cmake
|
||||
Makefile
|
||||
install_manifest.txt
|
||||
|
||||
# Compiled binaries
|
||||
*.o
|
||||
*.obj
|
||||
*.lo
|
||||
*.la
|
||||
*.a
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
*.dll
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Debug files
|
||||
*.pch
|
||||
*.pdb
|
||||
*.mod
|
||||
*.map
|
||||
|
||||
# Generated configuration headers
|
||||
config.h
|
||||
config.hpp
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# IDE files
|
||||
# VS Code
|
||||
.vscode/
|
||||
*.code-workspace
|
||||
|
||||
# CLion
|
||||
.idea/
|
||||
|
||||
# Visual Studio
|
||||
*.user
|
||||
*.suo
|
||||
*.vcxproj.user
|
||||
*.vcxproj.*
|
||||
*.sln
|
||||
|
||||
# Xcode
|
||||
*.pbxuser
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.perspectivev3
|
||||
*.xcworkspace/
|
||||
xcuserdata/
|
||||
|
||||
# OS junk
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# Windows
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Backup files
|
||||
*~
|
||||
*.swp
|
||||
*.tmp
|
||||
@@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(asar_fuses_bypass C)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
#[[
|
||||
add_executable(asar_fuses_bypass main.c)
|
||||
]]
|
||||
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||
set(CMAKE_STATIC_LIBRARY_PREFIX "")
|
||||
|
||||
add_link_options(-static -static-libgcc -static-libstdc++)
|
||||
|
||||
add_library(version SHARED library.c library.def fuses.c)
|
||||
@@ -0,0 +1,190 @@
|
||||
//
|
||||
// Created by kitbyte on 30.11.2025.
|
||||
//
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#define ENABLE_LOGGING 0
|
||||
|
||||
#ifndef _DEBUG
|
||||
#undef ENABLE_LOGGING
|
||||
#define ENABLE_LOGGING 0
|
||||
#endif
|
||||
|
||||
#define FUSE_SENTINEL_LENGTH 32
|
||||
#define FUSE_VERSION_SUPPORTED 1
|
||||
#define FUSE_MIN_WIRE_LENGTH 5
|
||||
|
||||
#define ALIGN8(ptr, mod) ((((ULONG_PTR)(ptr) + 7) & ~7) + ((mod) * 8))
|
||||
|
||||
#if defined(_WIN64)
|
||||
#define SENTINEL_PART1 0x6E64474B70374C64ULL
|
||||
#define SENTINEL_PART2 0x6262503639377A4EULL
|
||||
#define SENTINEL_PART3 0x58486D4B4E57516AULL
|
||||
#define SENTINEL_PART4 0x5873743942615A42ULL
|
||||
#else
|
||||
static const DWORD SENTINEL_PARTS[8] = {
|
||||
0x70374C64, 0x6E64474B,
|
||||
0x39377A4E, 0x62625036,
|
||||
0x4E57516A, 0x58486D4B,
|
||||
0x42615A42, 0x58737439
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
FUSE_RUN_AS_NODE = 0,
|
||||
FUSE_COOKIE_ENCRYPTION = 1,
|
||||
FUSE_NODE_OPTIONS = 2,
|
||||
FUSE_NODE_CLI_INSPECT = 3,
|
||||
FUSE_ASAR_INTEGRITY_VALIDATION = 4,
|
||||
FUSE_ONLY_LOAD_APP_FROM_ASAR = 5,
|
||||
FUSE_LOAD_BROWSER_V8_SNAPSHOT = 6,
|
||||
FUSE_GRANT_FILE_PROTOCOL = 7
|
||||
} ElectronFuseIndex;
|
||||
|
||||
typedef enum {
|
||||
FUSE_STATE_DISABLED = '0',
|
||||
FUSE_STATE_ENABLED = '1',
|
||||
FUSE_STATE_REMOVED = 'r'
|
||||
} FuseState;
|
||||
|
||||
typedef struct {
|
||||
char sentinel[FUSE_SENTINEL_LENGTH];
|
||||
unsigned char version;
|
||||
unsigned char wire_length;
|
||||
unsigned char fuses[];
|
||||
} FuseWire;
|
||||
|
||||
#if ENABLE_LOGGING
|
||||
|
||||
static FILE* g_logFile = NULL;
|
||||
|
||||
static void log_init(void) {
|
||||
char path[MAX_PATH];
|
||||
GetModuleFileNameA(NULL, path, MAX_PATH);
|
||||
char* dot = strrchr(path, '.');
|
||||
if (dot) strcpy(dot, ".log");
|
||||
else strcat(path, ". log");
|
||||
|
||||
g_logFile = fopen(path, "a");
|
||||
if (g_logFile) {
|
||||
time_t now = time(NULL);
|
||||
fprintf(g_logFile, "\n=== Session: %s", ctime(&now));
|
||||
fflush(g_logFile);
|
||||
}
|
||||
}
|
||||
|
||||
static void log_close(void) {
|
||||
if (g_logFile) {
|
||||
fclose(g_logFile);
|
||||
g_logFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void log_msg(const char* fmt, .. .) {
|
||||
if (!g_logFile) return;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(g_logFile, fmt, args);
|
||||
va_end(args);
|
||||
fflush(g_logFile);
|
||||
}
|
||||
|
||||
#else
|
||||
#define log_init() ((void)0)
|
||||
#define log_close() ((void)0)
|
||||
#define log_msg(...) ((void)0)
|
||||
#endif
|
||||
|
||||
static FuseWire* find_fuse_wire(int offset) {
|
||||
char* base = (char*)GetModuleHandleA(NULL);
|
||||
if (!base) return NULL;
|
||||
|
||||
IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)base;
|
||||
if (dos->e_magic != IMAGE_DOS_SIGNATURE) return NULL;
|
||||
|
||||
IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)(base + dos->e_lfanew);
|
||||
if (nt->Signature != IMAGE_NT_SIGNATURE) return NULL;
|
||||
|
||||
DWORD size = nt->OptionalHeader.SizeOfImage;
|
||||
char* start = (char*)ALIGN8(base, 1) + offset;
|
||||
char* end = (char*)ALIGN8(base + size - FUSE_SENTINEL_LENGTH, -1) - offset;
|
||||
|
||||
#if defined(_WIN64)
|
||||
for (DWORD64* p = (DWORD64*)start; p < (DWORD64*)end; p++) {
|
||||
if (p[0] == SENTINEL_PART1 && p[1] == SENTINEL_PART2 &&
|
||||
p[2] == SENTINEL_PART3 && p[3] == SENTINEL_PART4) {
|
||||
log_msg("[+] Sentinel at: %p\n", p);
|
||||
return (FuseWire*)p;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (DWORD* p = (DWORD*)start; p < (DWORD*)end; p += 2) {
|
||||
if (p[0] == SENTINEL_PARTS[0] && p[1] == SENTINEL_PARTS[1] &&
|
||||
p[2] == SENTINEL_PARTS[2] && p[3] == SENTINEL_PARTS[3] &&
|
||||
p[4] == SENTINEL_PARTS[4] && p[5] == SENTINEL_PARTS[5] &&
|
||||
p[6] == SENTINEL_PARTS[6] && p[7] == SENTINEL_PARTS[7]) {
|
||||
log_msg("[+] Sentinel at: %p\n", p);
|
||||
return (FuseWire*)p;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL patch_fuse(unsigned char* fuse) {
|
||||
DWORD prot;
|
||||
if (!VirtualProtect(fuse, 1, PAGE_READWRITE, &prot)) {
|
||||
log_msg("[-] VirtualProtect failed: %lu\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
*fuse = FUSE_STATE_REMOVED;
|
||||
VirtualProtect(fuse, 1, prot, &prot);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL disable_asar_integrity(void) {
|
||||
log_init();
|
||||
|
||||
FuseWire* wire = find_fuse_wire(0);
|
||||
if (! wire) wire = find_fuse_wire(4);
|
||||
|
||||
if (! wire) {
|
||||
log_msg("[-] Fuse wire not found\n");
|
||||
log_close();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
log_msg("[+] Wire at %p, ver=%d, len=%d\n", wire, wire->version, wire->wire_length);
|
||||
|
||||
if (wire->version != FUSE_VERSION_SUPPORTED) {
|
||||
log_msg("[-] Unsupported version: %d\n", wire->version);
|
||||
log_close();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (wire->wire_length < FUSE_MIN_WIRE_LENGTH) {
|
||||
log_msg("[*] Wire too short, skip\n");
|
||||
log_close();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
unsigned char* target = &wire->fuses[FUSE_ASAR_INTEGRITY_VALIDATION];
|
||||
|
||||
if (*target == FUSE_STATE_REMOVED) {
|
||||
log_msg("[*] Already patched\n");
|
||||
log_close();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
log_msg("[*] Patching fuse[%d]: 0x%02X -> 0x%02X\n",
|
||||
FUSE_ASAR_INTEGRITY_VALIDATION, *target, FUSE_STATE_REMOVED);
|
||||
|
||||
BOOL result = patch_fuse(target);
|
||||
log_msg(result ? "[+] Success\n" : "[-] Failed\n");
|
||||
|
||||
log_close();
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// Created by kitbyte on 30.11.2025.
|
||||
//
|
||||
#include <Windows.h>
|
||||
|
||||
extern BOOL disable_asar_integrity(void);
|
||||
|
||||
#ifdef _WIN64
|
||||
#define WRAPPER_GENFUNC(name) \
|
||||
FARPROC orig_##name; \
|
||||
void _##name(); \
|
||||
__asm__( \
|
||||
".global _" #name "\n" \
|
||||
"_" #name ":\n" \
|
||||
" movq orig_" #name "(%rip), %rax\n" \
|
||||
" jmp *%rax\n" \
|
||||
);
|
||||
#else
|
||||
#define WRAPPER_GENFUNC(name) \
|
||||
FARPROC orig_##name; \
|
||||
__declspec(naked) void _##name() \
|
||||
{ \
|
||||
asm("jmp *_orig_"#name); \
|
||||
}
|
||||
#endif
|
||||
|
||||
WRAPPER_GENFUNC(GetFileVersionInfoA)
|
||||
WRAPPER_GENFUNC(GetFileVersionInfoByHandle)
|
||||
WRAPPER_GENFUNC(GetFileVersionInfoExW)
|
||||
WRAPPER_GENFUNC(GetFileVersionInfoExA)
|
||||
WRAPPER_GENFUNC(GetFileVersionInfoSizeA)
|
||||
WRAPPER_GENFUNC(GetFileVersionInfoSizeExA)
|
||||
WRAPPER_GENFUNC(GetFileVersionInfoSizeExW)
|
||||
WRAPPER_GENFUNC(GetFileVersionInfoSizeW)
|
||||
WRAPPER_GENFUNC(GetFileVersionInfoW)
|
||||
WRAPPER_GENFUNC(VerFindFileA)
|
||||
WRAPPER_GENFUNC(VerFindFileW)
|
||||
WRAPPER_GENFUNC(VerInstallFileA)
|
||||
WRAPPER_GENFUNC(VerInstallFileW)
|
||||
WRAPPER_GENFUNC(VerLanguageNameA)
|
||||
WRAPPER_GENFUNC(VerLanguageNameW)
|
||||
WRAPPER_GENFUNC(VerQueryValueA)
|
||||
WRAPPER_GENFUNC(VerQueryValueW)
|
||||
|
||||
#define WRAPPER_FUNC(name) orig_##name = GetProcAddress(hOriginalDll, #name);
|
||||
|
||||
void SourceInit()
|
||||
{
|
||||
TCHAR source[MAX_PATH];
|
||||
GetSystemDirectory(source, MAX_PATH);
|
||||
strcat_s(source, sizeof source, "\\version.dll");
|
||||
HMODULE hOriginalDll = LoadLibrary(source);
|
||||
|
||||
WRAPPER_FUNC(GetFileVersionInfoA);
|
||||
WRAPPER_FUNC(GetFileVersionInfoByHandle);
|
||||
WRAPPER_FUNC(GetFileVersionInfoExW);
|
||||
WRAPPER_FUNC(GetFileVersionInfoExA);
|
||||
WRAPPER_FUNC(GetFileVersionInfoSizeA);
|
||||
WRAPPER_FUNC(GetFileVersionInfoSizeExW);
|
||||
WRAPPER_FUNC(GetFileVersionInfoSizeExA);
|
||||
WRAPPER_FUNC(GetFileVersionInfoSizeW);
|
||||
WRAPPER_FUNC(GetFileVersionInfoW);
|
||||
WRAPPER_FUNC(VerFindFileA);
|
||||
WRAPPER_FUNC(VerFindFileW);
|
||||
WRAPPER_FUNC(VerInstallFileA);
|
||||
WRAPPER_FUNC(VerInstallFileW);
|
||||
WRAPPER_FUNC(VerLanguageNameA);
|
||||
WRAPPER_FUNC(VerLanguageNameW);
|
||||
WRAPPER_FUNC(VerQueryValueA);
|
||||
WRAPPER_FUNC(VerQueryValueW);
|
||||
}
|
||||
|
||||
|
||||
void Payload()
|
||||
{
|
||||
disable_asar_integrity();
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HMODULE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
if (fdwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
SourceInit();
|
||||
Payload();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
LIBRARY "VERSION"
|
||||
EXPORTS
|
||||
|
||||
GetFileVersionInfoA = _GetFileVersionInfoA
|
||||
GetFileVersionInfoByHandle = _GetFileVersionInfoByHandle
|
||||
GetFileVersionInfoExA = _GetFileVersionInfoExA
|
||||
GetFileVersionInfoExW = _GetFileVersionInfoExW
|
||||
GetFileVersionInfoSizeA = _GetFileVersionInfoSizeA
|
||||
GetFileVersionInfoSizeExA = _GetFileVersionInfoSizeExA
|
||||
GetFileVersionInfoSizeExW = _GetFileVersionInfoSizeExW
|
||||
GetFileVersionInfoSizeW = _GetFileVersionInfoSizeW
|
||||
GetFileVersionInfoW = _GetFileVersionInfoW
|
||||
VerFindFileA = _VerFindFileA
|
||||
VerFindFileW = _VerFindFileW
|
||||
VerInstallFileA = _VerInstallFileA
|
||||
VerInstallFileW = _VerInstallFileW
|
||||
VerLanguageNameA = _VerLanguageNameA
|
||||
VerLanguageNameW = _VerLanguageNameW
|
||||
VerQueryValueA = _VerQueryValueA
|
||||
VerQueryValueW = _VerQueryValueW
|
||||
Reference in New Issue
Block a user