mirror of
https://github.com/decompals/wibo.git
synced 2025-12-17 00:47:18 +00:00
LoadLibraryA: Skip import resolution & DllMain for EXEs
This commit is contained in:
@@ -196,6 +196,7 @@ add_executable(wibo
|
|||||||
dll/user32.cpp
|
dll/user32.cpp
|
||||||
dll/vcruntime.cpp
|
dll/vcruntime.cpp
|
||||||
dll/version.cpp
|
dll/version.cpp
|
||||||
|
dll/ws2.cpp
|
||||||
src/access.cpp
|
src/access.cpp
|
||||||
src/async_io.cpp
|
src/async_io.cpp
|
||||||
src/errors.cpp
|
src/errors.cpp
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ DWORD WINAPI GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
|
|||||||
|
|
||||||
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR lpName, LPCSTR lpType) {
|
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR lpName, LPCSTR lpType) {
|
||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("FindResourceA %p %p %p\n", hModule, lpName, lpType);
|
DEBUG_LOG("FindResourceA(%p, %s, %s)\n", hModule, lpName, lpType);
|
||||||
auto type = wibo::resourceIdentifierFromAnsi(lpType);
|
auto type = wibo::resourceIdentifierFromAnsi(lpType);
|
||||||
auto name = wibo::resourceIdentifierFromAnsi(lpName);
|
auto name = wibo::resourceIdentifierFromAnsi(lpName);
|
||||||
return findResourceInternal(hModule, type, name, std::nullopt);
|
return findResourceInternal(hModule, type, name, std::nullopt);
|
||||||
@@ -161,7 +161,7 @@ HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR lpName, LPCSTR lpType) {
|
|||||||
|
|
||||||
HRSRC WINAPI FindResourceExA(HMODULE hModule, LPCSTR lpType, LPCSTR lpName, WORD wLanguage) {
|
HRSRC WINAPI FindResourceExA(HMODULE hModule, LPCSTR lpType, LPCSTR lpName, WORD wLanguage) {
|
||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("FindResourceExA %p %p %p %u\n", hModule, lpName, lpType, wLanguage);
|
DEBUG_LOG("FindResourceExA(%p, %s, %s, %u)\n", hModule, lpName, lpType, wLanguage);
|
||||||
auto type = wibo::resourceIdentifierFromAnsi(lpType);
|
auto type = wibo::resourceIdentifierFromAnsi(lpType);
|
||||||
auto name = wibo::resourceIdentifierFromAnsi(lpName);
|
auto name = wibo::resourceIdentifierFromAnsi(lpName);
|
||||||
return findResourceInternal(hModule, type, name, wLanguage);
|
return findResourceInternal(hModule, type, name, wLanguage);
|
||||||
@@ -169,7 +169,7 @@ HRSRC WINAPI FindResourceExA(HMODULE hModule, LPCSTR lpType, LPCSTR lpName, WORD
|
|||||||
|
|
||||||
HRSRC WINAPI FindResourceW(HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType) {
|
HRSRC WINAPI FindResourceW(HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType) {
|
||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("FindResourceW %p\n", hModule);
|
DEBUG_LOG("FindResourceW(%p, %p, %p)\n", hModule, lpName, lpType);
|
||||||
auto type = wibo::resourceIdentifierFromWide(lpType);
|
auto type = wibo::resourceIdentifierFromWide(lpType);
|
||||||
auto name = wibo::resourceIdentifierFromWide(lpName);
|
auto name = wibo::resourceIdentifierFromWide(lpName);
|
||||||
return findResourceInternal(hModule, type, name, std::nullopt);
|
return findResourceInternal(hModule, type, name, std::nullopt);
|
||||||
@@ -177,7 +177,7 @@ HRSRC WINAPI FindResourceW(HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType) {
|
|||||||
|
|
||||||
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage) {
|
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage) {
|
||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("FindResourceExW %p %u\n", hModule, wLanguage);
|
DEBUG_LOG("FindResourceExW(%p, %p, %p, %u)\n", hModule, lpName, lpType, wLanguage);
|
||||||
auto type = wibo::resourceIdentifierFromWide(lpType);
|
auto type = wibo::resourceIdentifierFromWide(lpType);
|
||||||
auto name = wibo::resourceIdentifierFromWide(lpName);
|
auto name = wibo::resourceIdentifierFromWide(lpName);
|
||||||
return findResourceInternal(hModule, type, name, wLanguage);
|
return findResourceInternal(hModule, type, name, wLanguage);
|
||||||
@@ -185,7 +185,7 @@ HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WO
|
|||||||
|
|
||||||
HGLOBAL WINAPI LoadResource(HMODULE hModule, HRSRC hResInfo) {
|
HGLOBAL WINAPI LoadResource(HMODULE hModule, HRSRC hResInfo) {
|
||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("LoadResource %p %p\n", hModule, hResInfo);
|
DEBUG_LOG("LoadResource(%p, %p)\n", hModule, hResInfo);
|
||||||
if (!hResInfo) {
|
if (!hResInfo) {
|
||||||
setLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
|
setLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
|
||||||
return GUEST_NULL;
|
return GUEST_NULL;
|
||||||
|
|||||||
@@ -1125,10 +1125,12 @@ BOOL WINAPI InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL
|
|||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("InitOnceBeginInitialize(%p, %u, %p, %p)\n", lpInitOnce, dwFlags, fPending, lpContext);
|
DEBUG_LOG("InitOnceBeginInitialize(%p, %u, %p, %p)\n", lpInitOnce, dwFlags, fPending, lpContext);
|
||||||
if (!lpInitOnce) {
|
if (!lpInitOnce) {
|
||||||
|
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
setLastError(ERROR_INVALID_PARAMETER);
|
setLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (dwFlags & ~(INIT_ONCE_CHECK_ONLY | INIT_ONCE_ASYNC)) {
|
if (dwFlags & ~(INIT_ONCE_CHECK_ONLY | INIT_ONCE_ASYNC)) {
|
||||||
|
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
setLastError(ERROR_INVALID_PARAMETER);
|
setLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1137,6 +1139,7 @@ BOOL WINAPI InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL
|
|||||||
|
|
||||||
if (dwFlags & INIT_ONCE_CHECK_ONLY) {
|
if (dwFlags & INIT_ONCE_CHECK_ONLY) {
|
||||||
if (dwFlags & INIT_ONCE_ASYNC) {
|
if (dwFlags & INIT_ONCE_ASYNC) {
|
||||||
|
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
setLastError(ERROR_INVALID_PARAMETER);
|
setLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1145,6 +1148,7 @@ BOOL WINAPI InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL
|
|||||||
if (fPending) {
|
if (fPending) {
|
||||||
*fPending = TRUE;
|
*fPending = TRUE;
|
||||||
}
|
}
|
||||||
|
DEBUG_LOG("-> ERROR_GEN_FAILURE\n");
|
||||||
setLastError(ERROR_GEN_FAILURE);
|
setLastError(ERROR_GEN_FAILURE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1186,6 +1190,7 @@ BOOL WINAPI InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL
|
|||||||
}
|
}
|
||||||
case 1: { // synchronous initialization in progress
|
case 1: { // synchronous initialization in progress
|
||||||
if (dwFlags & INIT_ONCE_ASYNC) {
|
if (dwFlags & INIT_ONCE_ASYNC) {
|
||||||
|
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
setLastError(ERROR_INVALID_PARAMETER);
|
setLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1222,6 +1227,7 @@ BOOL WINAPI InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL
|
|||||||
}
|
}
|
||||||
case 3: { // async pending
|
case 3: { // async pending
|
||||||
if (!(dwFlags & INIT_ONCE_ASYNC)) {
|
if (!(dwFlags & INIT_ONCE_ASYNC)) {
|
||||||
|
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
setLastError(ERROR_INVALID_PARAMETER);
|
setLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1240,20 +1246,24 @@ BOOL WINAPI InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpCon
|
|||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("InitOnceComplete(%p, %u, %p)\n", lpInitOnce, dwFlags, lpContext);
|
DEBUG_LOG("InitOnceComplete(%p, %u, %p)\n", lpInitOnce, dwFlags, lpContext);
|
||||||
if (!lpInitOnce) {
|
if (!lpInitOnce) {
|
||||||
|
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
setLastError(ERROR_INVALID_PARAMETER);
|
setLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (dwFlags & ~(INIT_ONCE_ASYNC | INIT_ONCE_INIT_FAILED)) {
|
if (dwFlags & ~(INIT_ONCE_ASYNC | INIT_ONCE_INIT_FAILED)) {
|
||||||
|
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
setLastError(ERROR_INVALID_PARAMETER);
|
setLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
const bool markFailed = (dwFlags & INIT_ONCE_INIT_FAILED) != 0;
|
const bool markFailed = (dwFlags & INIT_ONCE_INIT_FAILED) != 0;
|
||||||
if (markFailed) {
|
if (markFailed) {
|
||||||
if (lpContext) {
|
if (lpContext) {
|
||||||
|
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
setLastError(ERROR_INVALID_PARAMETER);
|
setLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (dwFlags & INIT_ONCE_ASYNC) {
|
if (dwFlags & INIT_ONCE_ASYNC) {
|
||||||
|
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
setLastError(ERROR_INVALID_PARAMETER);
|
setLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1261,6 +1271,7 @@ BOOL WINAPI InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpCon
|
|||||||
|
|
||||||
const GUEST_PTR contextValue = static_cast<GUEST_PTR>(reinterpret_cast<uintptr_t>(lpContext));
|
const GUEST_PTR contextValue = static_cast<GUEST_PTR>(reinterpret_cast<uintptr_t>(lpContext));
|
||||||
if (!markFailed && (contextValue & kInitOnceReservedMask)) {
|
if (!markFailed && (contextValue & kInitOnceReservedMask)) {
|
||||||
|
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
setLastError(ERROR_INVALID_PARAMETER);
|
setLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1274,6 +1285,7 @@ BOOL WINAPI InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpCon
|
|||||||
case 1: {
|
case 1: {
|
||||||
auto syncState = getInitOnceState(lpInitOnce);
|
auto syncState = getInitOnceState(lpInitOnce);
|
||||||
if (!syncState) {
|
if (!syncState) {
|
||||||
|
DEBUG_LOG("-> ERROR_GEN_FAILURE\n");
|
||||||
setLastError(ERROR_GEN_FAILURE);
|
setLastError(ERROR_GEN_FAILURE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1292,6 +1304,7 @@ BOOL WINAPI InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpCon
|
|||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
if (!(dwFlags & INIT_ONCE_ASYNC)) {
|
if (!(dwFlags & INIT_ONCE_ASYNC)) {
|
||||||
|
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
setLastError(ERROR_INVALID_PARAMETER);
|
setLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1300,6 +1313,7 @@ BOOL WINAPI InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpCon
|
|||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
default:
|
default:
|
||||||
|
DEBUG_LOG("-> ERROR_GEN_FAILURE\n");
|
||||||
setLastError(ERROR_GEN_FAILURE);
|
setLastError(ERROR_GEN_FAILURE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
10
dll/ws2.cpp
Normal file
10
dll/ws2.cpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include "modules.h"
|
||||||
|
|
||||||
|
extern const wibo::ModuleStub lib_ws2 = {
|
||||||
|
(const char *[]){
|
||||||
|
"WS2_32",
|
||||||
|
nullptr,
|
||||||
|
},
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
};
|
||||||
@@ -19,6 +19,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
constexpr uint16_t IMAGE_FILE_DLL = 0x2000;
|
||||||
|
|
||||||
struct PEHeader {
|
struct PEHeader {
|
||||||
uint8_t magic[4]; // "PE\0\0"
|
uint8_t magic[4]; // "PE\0\0"
|
||||||
uint16_t machine;
|
uint16_t machine;
|
||||||
@@ -372,6 +374,7 @@ bool loadPEFromSource(wibo::Executable &executable, const PeInputView &source, b
|
|||||||
DEBUG_LOG("loadPE: unreasonable section count %u\n", header.numberOfSections);
|
DEBUG_LOG("loadPE: unreasonable section count %u\n", header.numberOfSections);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
executable.isDll = !!(header.characteristics & IMAGE_FILE_DLL);
|
||||||
|
|
||||||
constexpr size_t kOptionalHeaderMinimumSize = offsetof(PE32Header, reserved) + sizeof(PEImageDataDirectory);
|
constexpr size_t kOptionalHeaderMinimumSize = offsetof(PE32Header, reserved) + sizeof(PEImageDataDirectory);
|
||||||
if (header.sizeOfOptionalHeader < kOptionalHeaderMinimumSize) {
|
if (header.sizeOfOptionalHeader < kOptionalHeaderMinimumSize) {
|
||||||
@@ -440,9 +443,10 @@ bool loadPEFromSource(wibo::Executable &executable, const PeInputView &source, b
|
|||||||
initialProtect, MEM_IMAGE);
|
initialProtect, MEM_IMAGE);
|
||||||
}
|
}
|
||||||
if (allocStatus != wibo::heap::VmStatus::Success) {
|
if (allocStatus != wibo::heap::VmStatus::Success) {
|
||||||
DEBUG_LOG("Image mapping failed (status=%u)\n", static_cast<unsigned>(allocStatus));
|
DEBUG_LOG("loadPE: mapping failed (status=%u)\n", static_cast<unsigned>(allocStatus));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
DEBUG_LOG("loadPE: mapping succeeded (base=%p, size=%zu)\n", allocatedBase, allocationSize);
|
||||||
|
|
||||||
std::unique_ptr<void, ImageMemoryDeleter> imageGuard(allocatedBase);
|
std::unique_ptr<void, ImageMemoryDeleter> imageGuard(allocatedBase);
|
||||||
executable.imageBase = allocatedBase;
|
executable.imageBase = allocatedBase;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ extern const wibo::ModuleStub lib_ole32;
|
|||||||
extern const wibo::ModuleStub lib_user32;
|
extern const wibo::ModuleStub lib_user32;
|
||||||
extern const wibo::ModuleStub lib_vcruntime;
|
extern const wibo::ModuleStub lib_vcruntime;
|
||||||
extern const wibo::ModuleStub lib_version;
|
extern const wibo::ModuleStub lib_version;
|
||||||
|
extern const wibo::ModuleStub lib_ws2;
|
||||||
|
|
||||||
// setup.S
|
// setup.S
|
||||||
template <size_t Index> void stubThunk();
|
template <size_t Index> void stubThunk();
|
||||||
@@ -186,7 +187,7 @@ LockedRegistry registry() {
|
|||||||
reg.initialized = true;
|
reg.initialized = true;
|
||||||
const wibo::ModuleStub *builtins[] = {
|
const wibo::ModuleStub *builtins[] = {
|
||||||
&lib_advapi32, &lib_bcrypt, &lib_kernel32, &lib_lmgr, &lib_mscoree, &lib_ntdll,
|
&lib_advapi32, &lib_bcrypt, &lib_kernel32, &lib_lmgr, &lib_mscoree, &lib_ntdll,
|
||||||
&lib_ole32, &lib_rpcrt4, &lib_user32, &lib_vcruntime, &lib_version,
|
&lib_ole32, &lib_rpcrt4, &lib_user32, &lib_vcruntime, &lib_version, &lib_ws2,
|
||||||
#if WIBO_HAS_MSVCRT
|
#if WIBO_HAS_MSVCRT
|
||||||
&lib_msvcrt,
|
&lib_msvcrt,
|
||||||
#endif
|
#endif
|
||||||
@@ -1173,6 +1174,7 @@ static ModuleInfo *loadModuleInternal(const std::string &dllName) {
|
|||||||
ModuleInfo *raw = info.get();
|
ModuleInfo *raw = info.get();
|
||||||
reg->modulesByKey[key] = std::move(info);
|
reg->modulesByKey[key] = std::move(info);
|
||||||
registerExternalModuleAliases(*reg, dllName, raw->resolvedPath, raw);
|
registerExternalModuleAliases(*reg, dllName, raw->resolvedPath, raw);
|
||||||
|
if (raw->executable->isDll) {
|
||||||
reg.lock.unlock();
|
reg.lock.unlock();
|
||||||
ensureExportsInitialized(*raw);
|
ensureExportsInitialized(*raw);
|
||||||
if (!raw->executable->resolveImports()) {
|
if (!raw->executable->resolveImports()) {
|
||||||
@@ -1207,6 +1209,7 @@ static ModuleInfo *loadModuleInternal(const std::string &dllName) {
|
|||||||
kernel32::setLastError(ERROR_DLL_INIT_FAILED);
|
kernel32::setLastError(ERROR_DLL_INIT_FAILED);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return raw;
|
return raw;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ class Executable {
|
|||||||
bool importsResolved = false;
|
bool importsResolved = false;
|
||||||
bool importsResolving = false;
|
bool importsResolving = false;
|
||||||
bool sectionsProtected = false;
|
bool sectionsProtected = false;
|
||||||
|
bool isDll = false;
|
||||||
std::vector<SectionInfo> sections;
|
std::vector<SectionInfo> sections;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user