Why can't the entry point of a dll be found within my program? PE file - c++

I'm trying to create a mod loader for an 18 year old game to help me get better at c++. Right now I'm just trying to inject a dll into the same process of the mod loader. The sample dll just prints some text to the command window but doesn't. I think that the code that I have loading the entry point of the dll is not working because everything works up until I call the entry point function of my sample dll within my ModLoader.exe, and Visual Studio just throws an Access Violation. I poked through the memory viewer in debug mode within visual studio to try and see where my ModLoader program thinks the dll entry point is located within the dll but the address just points to a bunch of zeros. I recently learned the PE file format and tried to understand all the code that I wrote when I was following a tutorial on Youtube on how to do this, so forgive me for my inexperience I'm just trying to learn. The other code that I do not show is me locating and finding the target process, reading the dll binary, getting the headers from the dll, me allocating space on the target process for the dll, and finally me writing all of the section header data into the target process. I can provide any other code that y'all would like to see!
Injector.h
using ModLoader_LoadLibrary = HINSTANCE(WINAPI*)(const char* filename);
using ModLoader_GetProcAddress = UINT_PTR(WINAPI*)(HINSTANCE module, const char* procName);
using ModLoader_DllEntry = BOOL(WINAPI*)(HINSTANCE dll, DWORD reason, LPVOID reserved);
struct ModLoader_ManualMapping_Data
{
ModLoader_LoadLibrary ML_LoadLibrary; //Function pointer to the windows load library function
ModLoader_GetProcAddress ML_ProcAddress; //Function pointer to a function to be called
HINSTANCE ML_Module; //dll instance
};
Injector.cpp : Shellcode function that'll run alongside the target executable
void __stdcall Shellcode(ModLoader_ManualMapping_Data* data)
{
if (!data)
return;
BYTE* pData = reinterpret_cast<BYTE*>(data);
IMAGE_OPTIONAL_HEADER& optHeader = reinterpret_cast<IMAGE_NT_HEADERS*>(pData + reinterpret_cast<IMAGE_DOS_HEADER*>(pData)->e_lfanew)->OptionalHeader;
auto loadLibrary = data->ML_LoadLibrary;
auto procAddress = data->ML_ProcAddress;
auto dllLoad = reinterpret_cast<ModLoader_DllEntry>(pData + optHeader.AddressOfEntryPoint); //Loads entry point func from dll
BYTE* locationDelta = pData - optHeader.ImageBase; //pData = the new address | ImageBase = preferred address -> Get the difference between the two to add to every address in the relocation table
if (locationDelta) //THIS DOES NOT GET RAN
{
//Adds the delta value to all addresses within the base relocation table
}
//Import table
if (optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
{
IMAGE_IMPORT_DESCRIPTOR* imgImport = reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR*>(pData
+ optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while (imgImport->Name) //THIS DOES NOT GET RAN B\C imgImport is all zeros.
{
//Loops through import table
}
}
if (optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size) //THIS DOES NOT GET RAN
{
//Calls the callback functions within dll
}
dllLoad(reinterpret_cast<HINSTANCE>(pData), DLL_PROCESS_ATTACH, nullptr); //PROBLEM: ACCESS VIOLATION
}
Injector.cpp : bool ManualMapping(HANDLE process, const char* dllFilepath)
-- This function is called in main.cpp.
The srcData variable is just the binary contents of the dll
ModLoader_ManualMapping_Data loadData = { 0 };
loadData.ML_LoadLibrary = LoadLibraryA;
loadData.ML_ProcAddress = reinterpret_cast<ModLoader_GetProcAddress>(GetProcAddress);
memcpy(srcData, &loadData, sizeof(loadData));
WriteProcessMemory(process, locOfDll, srcData, 0x1000, nullptr);
void* shellCodeBase = VirtualAllocEx(process, nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); //Allocates 0x1000 bytes in the process memory for the shellcode
WriteProcessMemory(process, shellCodeBase, Shellcode, 0x1000, nullptr); //Injects the Shellcode function into the process
HANDLE thread = nullptr;
thread = CreateRemoteThread(process, nullptr, 0, reinterpret_cast<PTHREAD_START_ROUTINE>(shellCodeBase), locOfDll, 0, nullptr); //Runs
Finally the sample dll code
#include <Windows.h>
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD reason_for_call, LPVOID lpReserved)
{
switch (reason_for_call)
{
case DLL_PROCESS_ATTACH:
OutputDebugStringA("Injected!");
break;
}
return TRUE;
}
EDIT
After rewriting all the code and looking at it all day I finally figured it out. I just had to make sure that the parameters were right when I called dllLoad!

Related

Read the file version of a dll in C: The system cannot find the file specified

I am new in the forum but I have already found a lot of help for my other projects.
I am using Visual Studio 2019 and I have created a .rc file which contains the file version and a few other things. These information are displayed in the Properties window of the my dll correctly.
I have created a function
void PrintVersion(TCHAR* pszFilePath, void (*printFunc)(const char*, ...));
which receives the file path and a pointer to my logger function. Inside that function I want to read the file version and print it to the logger. But my logger returns Error in GetFileVersionInfoSize: The system cannot find the file specified.
My function call does look like this:
TCHAR* filename = L"mydll.dll";
PrintVersion(filename, gPrintFunc);
And the function is implemented as follows:
// Read the version of the dll and write it to the logger
void PrintVersion(TCHAR* pszFilePath, void (*printFunc)(const char*, ...))
{
DWORD dwSize = 0;
DWORD verHandle = 0;
BYTE* pbVersionInfo = NULL;
VS_FIXEDFILEINFO* pFileInfo = NULL;
UINT puLenFileInfo = 0;
// Get the size of the version information. This is done to check if the file is avaialbe
// If the size is zero then a error occured
dwSize = GetFileVersionInfoSize(pszFilePath, &verHandle);
if (dwSize == 0)
{
gPrintFunc("Error in GetFileVersionInfoSize: ");
PrintLastErrorString(gPrintFunc);
return;
}
// Create some memory for the file version info
pbVersionInfo = malloc(dwSize);
// Store the information into pbVersionInfo
#pragma warning(suppress : 6387)
if (!GetFileVersionInfo(pszFilePath, verHandle, dwSize, pbVersionInfo))
{
gPrintFunc("Error in GetFileVersionInfo: ");
PrintLastErrorString(gPrintFunc);
free(pbVersionInfo);
return;
}
// Make the information easier accessable in pFileInfo
#pragma warning(suppress : 6387)
if (!VerQueryValue(pbVersionInfo, TEXT("\\"), (LPVOID*)&pFileInfo, &puLenFileInfo))
{
gPrintFunc("Error in VerQueryValue: ");
PrintLastErrorString(gPrintFunc);
free(pbVersionInfo);
return;
}
// pFileInfo->dwFileVersionMS and pFileInfo->dwFileVersionLS contain the software version
// Major2B.Minor2B.Revision2B.Build2B
gPrintFunc("File Version of %s: %d.%d.%d.%d\n",
pszFilePath,
(pFileInfo->dwFileVersionMS >> 16) & 0xffff,
(pFileInfo->dwFileVersionMS >> 0) & 0xffff,
(pFileInfo->dwFileVersionLS >> 16) & 0xffff,
(pFileInfo->dwFileVersionLS >> 0) & 0xffff
);
// Free up the reserved memory
free(pbVersionInfo);
}
// Used for receiving the last WIN32 error and write it to the logger
void PrintLastErrorString(void (*printFunc)(const char*, ...))
{
// Get the error id of the last error
DWORD iLastError;
iLastError = GetLastError();
//Ask Win32 to give us the string version of that message ID.
//The parameters we pass in, tell Win32 to create the buffer that holds the message for us (because we don't yet know how long the message string will be).
LPSTR messageBuffer = NULL;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, iLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
gPrintFunc("%s\n", messageBuffer);
return;
}
I created that function by combining a few different C++ and C# examples from this forum. I am not familiar with the TCHAR* datatype. I assume that the problem has maybe something to do with the filename string. Further I am not able to print the filename to the logger with the %s format placeholder. In this case only the first letter of the filename is displayed.
One further info. Before I copied that code to the dll. I created a small console application. And in this case it was possible to read the file version of the exe. I also tried to specify the complete path of the dll. The dll and the exe, which uses the dll are in the same directory.
Maybe someone can help me :)
BR
Thank you for your answers.
I changed now the character set to: Use Unicode Character Set and now it works as expected.

Loading a 64-bit Windows PE file from memory

I wanted to load a Windows PE file (a.k.a. EXE) from a memory buffer in C++ so I found this code. Using a simple hello world example, it works fine. However, when loading a more sophisticated EXE with static dependencies the code crashes instead of loading the PE file successfully. My updated PE loader code is the following:
#include <Windows.h>
#include <stdexcept>
inline auto fix_image_iat(PIMAGE_DOS_HEADER dos_header, PIMAGE_NT_HEADERS nt_header)
{
auto import_table = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
VirtualAddress + reinterpret_cast<UINT_PTR>(dos_header));
const DWORD iat_loc = nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress ?
IMAGE_DIRECTORY_ENTRY_IAT : IMAGE_DIRECTORY_ENTRY_IMPORT;
const DWORD iat_rva = nt_header->OptionalHeader.DataDirectory[iat_loc].VirtualAddress;
const SIZE_T iat_size = nt_header->OptionalHeader.DataDirectory[iat_loc].Size;
const auto iat = reinterpret_cast<LPVOID>(iat_rva + reinterpret_cast<UINT_PTR>(dos_header));
DWORD op;
VirtualProtect(iat, iat_size, PAGE_READWRITE, &op);
PIMAGE_THUNK_DATA thunk;
while (import_table->Name)
{
const auto import_base = LoadLibraryA(
reinterpret_cast<LPCSTR>(import_table->Name + reinterpret_cast<UINT_PTR>(dos_header)));
auto fix_up = reinterpret_cast<PIMAGE_THUNK_DATA>(import_table->FirstThunk + reinterpret_cast<UINT_PTR>(
dos_header));
if (import_table->OriginalFirstThunk)
{
thunk = reinterpret_cast<PIMAGE_THUNK_DATA>(import_table->OriginalFirstThunk + reinterpret_cast<UINT_PTR>(dos_header));
}
else
{
thunk = reinterpret_cast<PIMAGE_THUNK_DATA>(import_table->FirstThunk + reinterpret_cast<UINT_PTR>(dos_header));
}
while (thunk->u1.Function)
{
if (thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
{
fix_up->u1.Function =
reinterpret_cast<UINT_PTR>(GetProcAddress(import_base, reinterpret_cast<LPCSTR>(thunk->u1.Ordinal & 0xFFFF)));
}
else
{
const PCHAR func_name = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(thunk->u1.AddressOfData)->Name + reinterpret_cast<
UINT_PTR>(dos_header);
fix_up->u1.Function = reinterpret_cast<UINT_PTR>(GetProcAddress(import_base, func_name));
}
fix_up++;
thunk++;
}
import_table++;
}
}
inline auto map_image_to_memory(const char* pe_buffer)
{
auto raw_image_base = PIMAGE_DOS_HEADER(pe_buffer);
if (IMAGE_DOS_SIGNATURE != raw_image_base->e_magic)
{
throw std::runtime_error(("Invalid DOS signature"));
}
auto nt_header = reinterpret_cast<PIMAGE_NT_HEADERS>(raw_image_base->e_lfanew + reinterpret_cast<UINT_PTR>(raw_image_base));
if (IMAGE_NT_SIGNATURE != nt_header->Signature)
{
throw std::runtime_error(("Invalid NT header"));
}
if (IMAGE_FILE_MACHINE_AMD64 != nt_header->FileHeader.Machine)
{
throw std::runtime_error(("Not a 64-bit module"));
}
if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress)
{
throw std::runtime_error((".NET is not supported"));
}
auto section_header = reinterpret_cast<PIMAGE_SECTION_HEADER>(raw_image_base->e_lfanew + sizeof * nt_header
+ reinterpret_cast<UINT_PTR>(raw_image_base));
auto mem_image_base = VirtualAlloc(reinterpret_cast<LPVOID>(nt_header->OptionalHeader.ImageBase),
nt_header->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (mem_image_base == nullptr)
{
throw std::runtime_error(("VirtualAlloc() failed"));
}
memcpy(mem_image_base, raw_image_base, nt_header->OptionalHeader.SizeOfHeaders);
for (WORD section_index = 0; section_index < nt_header->FileHeader.NumberOfSections; section_index++)
{
memcpy(reinterpret_cast<LPVOID>(section_header->VirtualAddress + reinterpret_cast<UINT_PTR>(mem_image_base)),
reinterpret_cast<LPVOID>(section_header->PointerToRawData + reinterpret_cast<UINT_PTR>(raw_image_base)),
section_header->SizeOfRawData);
section_header++;
}
return static_cast<PIMAGE_DOS_HEADER>(mem_image_base);
}
//works with manually mapped files
HANDLE GetImageActCtx(HMODULE module)
{
WCHAR temp_path[MAX_PATH];
WCHAR temp_filename[MAX_PATH];
for (int i = 1; i <= 3; i++) {
HRSRC resource_info = FindResource(module, MAKEINTRESOURCE(i), RT_MANIFEST);
if (resource_info) {
HGLOBAL resource = LoadResource(module, resource_info);
DWORD resource_size = SizeofResource(module, resource_info);
const PBYTE resource_data = (const PBYTE)LockResource(resource);
if (resource_data && resource_size) {
FILE* fp;
errno_t err;
DWORD ret_val = GetTempPath(MAX_PATH, temp_path);
if (0 == GetTempFileName(temp_path, L"manifest.tmp", 0, temp_filename))
return NULL;
err = _wfopen_s(&fp, temp_filename, L"w");
if (errno)
return NULL;
fprintf(fp, (const char *)resource_data);
fclose(fp);
break;
}
else {
return NULL;
}
}
}
ACTCTXW act = { sizeof(act) };
act.lpSource = temp_filename;
return CreateActCtx(&act);
}
BOOL FixImageRelocations(PIMAGE_DOS_HEADER dos_header, PIMAGE_NT_HEADERS nt_header, ULONG_PTR delta)
{
ULONG_PTR size;
PULONG_PTR intruction;
PIMAGE_BASE_RELOCATION reloc_block =
(PIMAGE_BASE_RELOCATION)(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress +
(UINT_PTR)dos_header);
while (reloc_block->VirtualAddress) {
size = (reloc_block->SizeOfBlock - sizeof(reloc_block)) / sizeof(WORD);
PWORD fixup = (PWORD)((ULONG_PTR)reloc_block + sizeof(reloc_block));
for (int i = 0; i < size; i++, fixup++) {
if (IMAGE_REL_BASED_DIR64 == *fixup >> 12) {
intruction = (PULONG_PTR)(reloc_block->VirtualAddress + (ULONG_PTR)dos_header + (*fixup & 0xfff));
*intruction += delta;
}
}
reloc_block = (PIMAGE_BASE_RELOCATION)(reloc_block->SizeOfBlock + (ULONG_PTR)reloc_block);
}
return TRUE;
}
void load_portable_executable(const char* pe_buffer)
{
const auto dos_header = map_image_to_memory(pe_buffer);
auto nt_header = reinterpret_cast<PIMAGE_NT_HEADERS>(dos_header->e_lfanew + reinterpret_cast<UINT_PTR>(dos_header));
HANDLE actctx = NULL;
UINT_PTR cookie = 0;
BOOL changed_ctx = FALSE;
if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) {
actctx = GetImageActCtx(reinterpret_cast<HMODULE>(dos_header));
if (actctx)
changed_ctx = ActivateActCtx(actctx, &cookie);
}
fix_image_iat(dos_header, nt_header);
if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) {
ptrdiff_t delta = (ptrdiff_t)((PBYTE)dos_header - (PBYTE)nt_header->OptionalHeader.ImageBase);
if (delta)
FixImageRelocations(dos_header, nt_header, delta);
}
// Calculate the absolute entry point address
const auto entry_point_address = reinterpret_cast<LPVOID>(nt_header->OptionalHeader.AddressOfEntryPoint + reinterpret_cast<UINT_PTR>(dos_header));
// Launch the PE file
static_cast<void(*)()>(entry_point_address)(); // TODO Crashes here
}
Note that C++20 is required to successfully compile.
Any idea why it crashes at the last line of code when passing control to the entry point address? Is there any library or clean reference implementation for PE loading (on Windows)?
I am doing a similar thing, loading an exe file (with LoadLibraryEx flag LOAD_IGNORE_CODE_AUTHZ_LEVEL) into the address space of the loading application. In this way I can observe all the activities of the program from its inception.
The steps are:
LoadLibrary, and if successful then
Patch the IAT
Get the address of entry-point of the loaded program
CreateThread, CREATE_SUSPENDED with the thread-start-address being the address of entry-point.
ResumeThread and off she goes.
So far there are 2 types of files that can be loaded, those with relocation table and those without. The ones with the relocation table are the modern ones compiled with /DynamicBase and the older ones do not have this information.
I compiled the loader to have fixed-base address way above the default 0x140000000 for x64 to ensure that there is ample space below it for loaded exes that have no relocation and have to be loaded at the default address.
The OS loader applies relocation fixups but does not fix import addresses which we have to do manually.
Any dll we load to fix the imports need no further cooking as the OS loader takes care of that.
Now just like the experience BullyWiiPlaza had I found some programs can be loaded and run perfectly yet many others crash on startup. And the annoying feature that when you exit your loaded program it tends to take with it the loading application on its way out.
To fix this I intercepted the CRT functions abort, _cexit, _c_exit and the kernel ExitProcess
and just the sheer virtue of using these functions enables the loaded program to go out alone but I use the opportunity to UnregisterClass in case I have to re-load the previous not so well written app.
Remember the RegisterClass function can fail with an error message ERROR_CLASS_ALREADY_EXISTS which isn't a sufficient reason to abort the application.
Another important function to intercept is GetModuleHandle because when the loaded app uses this function as GetModuleHandle(0) to query its base address then without intercepting it and returning its hModule the OS will give it the Loader's base address which will cause a crash.
What I find confusing is that some lost versions of my applications could load apps that have no relocation info and run successfully but after ceaseless tweaking I could no longer run them.
The problem appears to be write access violation.
So I checked the protection parameters given to VirtualProtect and found from this following code that the iat_size is small and does not include the thunk I wish modify.
DWORD iat_loc = (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress)
? IMAGE_DIRECTORY_ENTRY_IAT : IMAGE_DIRECTORY_ENTRY_IMPORT;
UINT_PTR iat_rva = nt_header->OptionalHeader.DataDirectory[iat_loc].VirtualAddress;
SIZE_T iat_size = nt_header->OptionalHeader.DataDirectory[iat_loc].Size;
LPVOID iat = (LPVOID)(iat_rva + (UINT_PTR)dos_header);
DWORD op;
VirtualProtect(iat, iat_size, PAGE_READWRITE, &op);
If anyone wants to recreate the problem then the specimen I used was Celemony Melodyne 5.
It does not have a relocation table and loads at address 0x140000000.
What is confusing is that other x64 applications such as DarkWave Studio run normally except it takes out the loader when it exits.
And by the way Microsoft has made a fine mess of the pragmas data_seg and data_section with respect to x64 altho they claim it works in the documentation.

Access violation error with injected dll C++

So recently I made my own dll injector to be able to debug my other app by injecting a debug dll in it; Using c++/cli for the interface and c++ for the code.
I tested the same code I used on this project on a C++ console app project and it worked without any problems.
The injection occurs inside the Init.cpp file, which essentially gets the provided dll path under the form of C:\\user\\documents\\debug.dll and checks if it exists. After that it gets the process id by passing the name, in this case myotherapp.exe, as a parameter. If successful it then get's the Handle to the process and store's it in g.h_process, it continues by allocating readable/writable memory in the process and then writing to this memory the path of the dll and finally use's LoadLibraryA to load the dll inside the process.
Init.cpp:
void Injector::Init(void)
{
Inject::Checks((char*)g.dll_path, g.procName);//checking for dll validity
}
bool Injector::Inject::Checks(char* dll_path, PCSTR procName)
{
if (!Utils::file_exists(dll_path))
return Utils::error("File does not exist.");
Utils::successInput("Prepared DLL for injection");
Utils::getProcId(procName, g.proc_id);
if (!g.proc_id) {
return Utils::error("Could not find specified process.");
}
g.h_process = OpenProcess(PROCESS_ALL_ACCESS, NULL, g.proc_id);
if (!g.h_process) {
return Utils::error("Failed to open a handle to process");
}
g.allocatedMemory = VirtualAllocEx(g.h_process, nullptr, MAX_PATH, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);//mem_reserver reserve memory then commit memory to be able to write to that memory
Allocate(g.allocatedMemory, dll_path);
Llib();
Release(dll_path, g.allocatedMemory);
return 0;
}
bool Injector::Inject::Allocate(void* allocatedMemory, char* dll_path)
{
if (!allocatedMemory)
return Utils::error("Failed to allocate memory");
if (!WriteProcessMemory(g.h_process, g.allocatedMemory, g.dll_path, MAX_PATH, nullptr))
return Utils::error("Failed to write process");
return true;
}
bool Injector::Inject::Llib() {
HANDLE h_thread = CreateRemoteThread(g.h_process, nullptr, NULL, LPTHREAD_START_ROUTINE(LoadLibraryA), g.allocatedMemory, NULL, nullptr);
if (!h_thread)
return Utils::error("Failed to create remote thread");
return true;
}
bool Injector::Inject::Release(PCSTR dll_path, void* allocatedMemory)
{
CloseHandle(g.h_process);
VirtualFreeEx(g.h_process, allocatedMemory, NULL, MEM_RELEASE);
return true;
}
The g.debug is just a flag which tells us if the console is enabled or not. found in the globals.hpp which just contains global variables.
You can also check the Utils namespace here.
The error:
The problem I'm experiencing here is whenever I inject my DLL into the process, my injector works fine with no errors but when I attach vs to the process I want to inject to I get an Access Violation error with the process exiting with an error code.
I don't understand, I can't see where I am accessing invalid memory.
Thanks in advance.

Deleting Shadow copy dll from temp directory

Many of our exe's dynamically load B.dll. B.dll makes a copy of itself in a temp file and reloads %TMP%\B-.dll. I'm trying to use this code to mark B-.dll for delete, but it fails with "access is denied", no doubt because of the LoadLibrary call:
char ourDllPath[MAX_PATH];
// ... set ourDllPath to absolute path...
char tempPath[MAX_PATH];
DWORD dwRetVal = GetTempPath(MAX_PATH, tempPath);
char shadowPath[MAX_PATH];
UINT uRetVal = GetTempFileNameA(tempPath, "FOO_", 0, shadowPath);
BOOL ok = CopyFileA(ourDllPath, shadowPath, false);
HMODULE hShadowDll = LoadLibraryA(shadowPath);
typedef int (WINAPI *PRESUMEFOO)();
PRESUMEFOO onload2 = (PRESUMEFOO)GetProcAddress(hShadowDll,"_Resume_Foo#0");
BOOL ok2 = DeleteFileA(shadowPath); // Fails with "Access is denied"
However, according to here (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363915(v=vs.85).aspx) this should be possible:
"The DeleteFile function marks a file for deletion on close. Therefore, the file deletion does not occur until the last handle to the file is closed."
Any ideas on how I can mark a currently open file to be deleted-on-close on a Windows server OS?

EnumProcessModulesEx fails returning error code 299 (ERROR_PARTIAL_COPY)

I am calling the function EnumProcessModulesEx and it fails. I running on a 64-bit machine. Here is the code below:
wchar_t* dest = new wchar_t[100];
int index = SendMessage(processes, LB_GETCURSEL, 0, 0);
SendMessage(processes, LB_GETTEXT, index, (LPARAM)dest);
HMODULE module;
unsigned long cbneeded;
EnableTokenPrivilege(hWnd, SE_DEBUG_NAME);
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, _wtoi(dest));
int errorcode = GetLastError();
BOOL ret = EnumProcessModulesEx(h, &module, sizeof module, &cbneeded, LIST_MODULES_ALL);
int err = GetLastError();
wchar_t* name = new wchar_t[MAX_PATH];
GetModuleBaseName(h, module, name, sizeof name);
MessageBox(hWnd, name, L"Process Name", 0);
delete dest;
delete name;
Most probably you are trying to open 32bit process from 64bit application or vice versa. You can only work with processes of the same kind.
BOOL ret = EnumProcessModulesEx(h, &module, sizeof module, &cbneeded, LIST_MODULES_ALL);
The 3rd argument is supposed to be the size of the array of HMODULES you pass in the 2nd argument. You only pass 1, not big enough. Note the lpcbNeeded, it tells you how large the array needs to be to not get the error.
If the target platform is x86, then you can try to change it to x64.
You can read the document: https://learn.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-enumprocessmodules
If this function is called from a 32-bit application running on WOW64, it can only enumerate the modules of a 32-bit process. If the process is a 64-bit process, this function fails and the last error code is ERROR_PARTIAL_COPY (299).
Well, what does GetLastError return? EDIT: my bad, I failed hard..
Do error-checking and make sure it's not SendMessage, EnableTokenPrivilege, or OpenProcess that's giving you the error.