EnumProcessModulesEx fails returning error code 299 (ERROR_PARTIAL_COPY) - c++

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.

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.

C++ Win32 - Getting App Name using PID and Executable Path

I'd like to get the name of an application on Windows.
Currently I'm using EnumProcesses() to enumerate all processes and receive a list of PIDs.
Then I'm looping through all PIDs, each iteration looks like this, when aProcess[i] is the current PID:
HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, aProcesses[i]);
std::string processName = get_process_name(proc);
My get_process_name(proc) function uses GetModuleFileNameEx to get the executable path and GetProcessImageFileName in order to retrieve the name of the executable file.
What I want to retrieve is basically the App Name, as it is displayed in the Windows Task Manager.
I've looked throughout Win32 API's documentation and could not find a clue on how to achieve this.
I've tried looking for other ways such as Windows Shell tasklist but it outputs different things, for example- Google Chrome:
Image Name: chrome.exe PID: 84 Session Name: Console
I'd really appreciate any thought on the matter, whether it be the Win32 API or some other way I can implement through C++ code.
You can do this with GetFileVersionInfoA and VerQueryValueA.
You just need to follow the example given in the VerQueryValueA document.
Here is my sample:
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
int main()
{
HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION , FALSE, 2140); //Modify pid to the pid of your application
if (!handle) return 0;
wchar_t pszFile[MAX_PATH] = L"";
DWORD len = MAX_PATH;
QueryFullProcessImageName(handle, 0, pszFile, &len);
UINT dwBytes, cbTranslate;
DWORD dwSize = GetFileVersionInfoSize(pszFile, (DWORD*)&dwBytes);
if (dwSize == 0) return 0;
LPVOID lpData = (LPVOID)malloc(dwSize);
ZeroMemory(lpData, dwSize);
if (GetFileVersionInfo(pszFile, 0, dwSize, lpData))
{
VerQueryValue(lpData,
L"\\VarFileInfo\\Translation",
(LPVOID*)&lpTranslate,
&cbTranslate);
wchar_t strSubBlock[MAX_PATH] = { 0 };
wchar_t* lpBuffer;
for (int i = 0; i < (cbTranslate / sizeof(struct LANGANDCODEPAGE)); i++)
{
StringCchPrintf(strSubBlock,50,
L"\\StringFileInfo\\%04x%04x\\FileDescription",
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage);
VerQueryValue(lpData,
strSubBlock,
(void**)&lpBuffer,
&dwBytes);
std::wcout << lpBuffer << std::endl;
}
}
if(lpData) free(lpData);
if (handle) CloseHandle(handle);
return 0;
}
And it works for me:
I think what you want are the "version" resources embedded in the PE file (the executables.)
You seem to be familiar with using Win32 API, so I'm just going to give you some hints.
You have to use LoadLibraryEx to load the EXE file (the Ex suffix is to enable passing the LOAD_LIBRARY_AS_DATAFILE flag,) and then call EnumResourceTypes (also see EnumResourceNames) to enumerate all the resource types/resources in the file, and find what you are looking for and then extract the data with LoadResource. The resource type you want is RT_VERSION.
I'm sure I'm omitting a lot of details (as per usual for Win32 programming,) and there might not be a need for enumeration at all; in which case you may want to call FindResource or FindResourceEx directly (if there is a fixed name for this particular resource.)
As further clarification, this gives you the date you see if you right-click on the EXE file (not the shortcut) in Windows Explorer and select "Properties", then go to the "Details" tab. If that information is indeed what you want (e.g. the "File description" field) then the above method should give you the data.

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

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!

sending a struct with MapViewOfFile and reading an unknown value

I am basically trying to cast or copy my struct to my other process section view but I keep getting an error
C2760: syntax error: unexpected token 'identifier', expected 'declaration'
This is what I am doing:
type RPM(UINT_PTR ReadAddress)
{
if (hDriver == INVALID_HANDLE_VALUE) {
return {};
}
DWORD64 Bytes;
KM_READ_REQUEST ReadRequest{};
type response{};
ReadRequest.ProcessId = PID;
ReadRequest.Address = ReadAddress;
ReadRequest.Size = sizeof(type);
ReadRequest.Output = &response;
The problem is here:
auto pBuf = (ReadRequest)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 4096);
if (!pBuf)
{
printf("OpenFileMappingA(write) fail! Error: %u\n", GetLastError());
system("pause");
}
printf("MapViewOfFile(write) created ! \n");
I am having another problem trying to read an unknown value from my kernel driver. It basically reads memory and then changes that value to another thing based on what I am reading from if its int, float, etc..
PKM_READ_REQUEST ReadInput = (PKM_READ_REQUEST)SharedSection; // cast readRequest to our struct which is in SharedSection.
void* ReadOutput = ReadInput->Output;
Status = ReadKernelMemory(Process, ReadInput->Address, ReadOutput, ReadInput->Size);
I am trying to copy it to my shared section so I can read it from user mode, but idk how to cast it or what the value would be.
memcpy(SharedSection, &ReadOutput, sizeof(ReadOutput));
This is how I want to try to read it, but cast it as the same way because I don't want to read it as void, I want to read it as the value that was given from my kernel mode.
auto pBuf = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 4096);
if (!pBuf)
{
printf("OpenFileMappingA(write) fail! Error: %u\n", GetLastError());
system("pause");
}
printf("MapViewOfFile(write) created ! \n");
BTW, I am using the un-documented function mmcopyvirtualmemory in my kernel driver.
1.
auto pBuf = (ReadRequest)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 4096);
The ReadRequest is not a type but an object, If you want to write the file map address as the struct KM_READ_REQUEST, you should convert the return pointer to the type of PKM_READ_REQUEST, and also take the control of the size of file map:
auto pBuf = (PKM_READ_REQUEST)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, sizeof(KM_READ_REQUEST));
So that you can set the PID,Address,Size and Output for it.
2.
memcpy(SharedSection, &ReadOutput, sizeof(ReadOutput));
ReadOutput is already the address of output value, So you don't
need the operation &.
Sizeof(a pointer) is always equal to 4(in 32-bit) and 8(in
64-bit);
You'd better use a new variable to store copied values, Instead of overwriting previous data。
So
type new_var;
memcpy(&new_var, ReadOutput, sizeof(KM_READ_REQUEST));
EDIT: Answer your comments,
You can set a single Event to communicate between driver and UM.
App:
hDevice = CreateFile(Device);
hEvent = CreateEvent(...);
DeviceIoControl(hDevice, IOCTL_SET_EVENT, &hEvent,...);
WaitForSingleObject(hEvent, INFINITE);
Driver:
case IOCTL_SET_EVENT:
{
HANDLE hUserEvent = *(HANDLE *)pIrp->AssociatedIrp.SystemBuffer;
status = ObReferenceObjectByHandle(hUserEvent, EVENT_MODIFY_STATE,*ExEventObjectType, KernelMode, (PVOID*)&pDevExt->pEvent, NULL);
ObDereferenceObject(pDevExt->pEvent);
break;
}
Then set event:
KeSetEvent(pdx->pEvent,...);

Bad counter path, pdhAddCounter; performance monitor in windows

I'm trying to count the number of processes on windoes 2008 server using pdh.h.
CONST PWSTR COUNTER_PATH = L"\\System\\Processes";
HQUERY hQuery = NULL;
HCOUNTER hCounter;
PDH_STATUS pdhStatus = ERROR_SUCCESS;
pdhStatus = PdhOpenQuery(NULL, 0, &hQuery);
pdhStatus = PdhAddCounter(hQuery, (LPCSTR)COUNTER_PATH, 0, &hCounter);
I got the COUNTER_PATH name from here, and the example can be found in here. But somehow I'm getting 0xC0000BC0 (PDH_CSTATUS_BAD_COUNTERNAME) error message at PdhAddCounter. Can anybody pick up any mistake I made? I'm not sure what I'm missing here. Is there anything wrong with COUNTER_PATH?
You're casting COUNTER_PATH to a LPCSTR in PdhAddCounter which you shouldn't be doing.
PdhAddCounter's second parameter is a LPCTSTR which is the same as CONST PWSTR.