Is there a way to extract information from VS_VERSION_INFO (e.g. FILEVERSION) inside the same application?
I know, you probably thinking in a path of:
1. GetModuleFileName(...)
2. GetFileVersionInfoSize(...)
3. GetFileVersionInfo(...)
4. VerQueryValue(...)
BUT! There is a "twist": I need to make activex control to extract it's own version. So GetModuleFileName would not return the correct filename, it will be parent application name, so the version info will be from parent application too, not the activex control.
Any ideas?
Here is the code which eventiuly worked for me (and Yes, it is for MFC ActiveX control):
CString modFilename;
if(GetModuleFileName(AfxGetInstanceHandle(), modFilename.GetBuffer(MAX_PATH), MAX_PATH) > 0)
{
modFilename.ReleaseBuffer(MAX_PATH);
DWORD dwHandle = 0;
DWORD dwSize = GetFileVersionInfoSize(modFilename, &dwHandle);
if(dwSize > 0)
{
LPBYTE lpInfo = new BYTE[dwSize];
ZeroMemory(lpInfo, dwSize);
if(GetFileVersionInfo(modFilename, 0, dwSize, lpInfo))
{
//// Use the version information block to obtain the FILEVERSION.
//// This will extract language specific part of versio resources. 040904E4 is English(US) locale,
//// it should match to your project
//UINT valLen = MAX_PATH;
//LPVOID valPtr = NULL;
//if(::VerQueryValue(lpInfo,
// TEXT("\\StringFileInfo\\040904E4\\FileVersion"),
// &valPtr,
// &valLen))
//{
// CString valStr((LPCTSTR)valPtr);
// AfxMessageBox(valStr);
//}
//// This will extract so called FIXED portion of the version info
UINT valLen = MAX_PATH;
LPVOID valPtr = NULL;
if(::VerQueryValue(lpInfo,
TEXT("\\"),
&valPtr,
&valLen))
{
VS_FIXEDFILEINFO* pFinfo = (VS_FIXEDFILEINFO*)valPtr;
// convert to text
CString valStr;
valStr.Format(_T("%d.%d.%d.%d"),
(pFinfo->dwFileVersionMS >> 16) & 0xFFFF,
(pFinfo->dwFileVersionMS) & 0xFFFF,
(pFinfo->dwFileVersionLS >> 16) & 0xFFFF,
(pFinfo->dwFileVersionLS) & 0xFFFF
);
AfxMessageBox(valStr);
}
}
delete[] lpInfo;
}
}
At step 1 you can call GetModuleFileName and pass in the hModule of your DLL. You get the hModule in DllMain():
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DWORD length = ::GetModuleFileName(hInstance, fullFilename, MAX_PATH);
// ...
}
}
Related
I'm writing a Windows application in C++ reading images from an external USB cam and displaying them (which works nicely). I like to monitor the used USB bandwidth at the same time. I know that there exists a USB_BANDWIDTH_INFO structure (https://learn.microsoft.com/en-us/windows/win32/api/usbuser/ns-usbuser-usb_bandwidth_info), but I have no clue how to use it. More precisely: The structure itself is pretty clear, but how do I get/read it (didn't find any example code explaining that)?
According to the MSDN:
The USB_BANDWIDTH_INFO structure is used with the IOCTL_USB_USER_REQUEST I/O control request to retrieve information about the allocated bandwidth.
So you need to call DeviceIoControl with IOCTL_USB_USER_REQUEST.
Refer to the official example, you can find:
GetHostControllerInfo(
HANDLE hHCDev,
PUSBHOSTCONTROLLERINFO hcInfo)
{
USBUSER_CONTROLLER_INFO_0 UsbControllerInfo;
DWORD dwError = 0;
DWORD dwBytes = 0;
BOOL bSuccess = FALSE;
memset(&UsbControllerInfo, 0, sizeof(UsbControllerInfo));
// set the header and request sizes
UsbControllerInfo.Header.UsbUserRequest = USBUSER_GET_CONTROLLER_INFO_0;
UsbControllerInfo.Header.RequestBufferLength = sizeof(UsbControllerInfo);
//
// Query for the USB_CONTROLLER_INFO_0 structure
//
bSuccess = DeviceIoControl(hHCDev,
IOCTL_USB_USER_REQUEST,
&UsbControllerInfo,
sizeof(UsbControllerInfo),
&UsbControllerInfo,
sizeof(UsbControllerInfo),
&dwBytes,
NULL);
if (!bSuccess)
{
dwError = GetLastError();
OOPS();
}
else
{
hcInfo->ControllerInfo = (PUSB_CONTROLLER_INFO_0) ALLOC(sizeof(USB_CONTROLLER_INFO_0));
if(NULL == hcInfo->ControllerInfo)
{
dwError = GetLastError();
OOPS();
}
else
{
// copy the data into our USB Host Controller's info structure
memcpy(hcInfo->ControllerInfo, &UsbControllerInfo.Info0, sizeof(USB_CONTROLLER_INFO_0));
}
}
return dwError;
}
You can modify it like:
USBUSER_CONTROLLER_INFO_0 UsbControllerInfo;
UsbControllerInfo.Header.UsbUserRequest = USBUSER_GET_BANDWIDTH_INFORMATION;
UsbControllerInfo.Header.RequestBufferLength = sizeof(UsbControllerInfo);
USB_BANDWIDTH_INFO UsbBandInfo{};
DWORD dwError = 0;
DWORD dwBytes = 0;
BOOL bSuccess = FALSE;
bSuccess = DeviceIoControl(hHCDev,
IOCTL_USB_USER_REQUEST,
&UsbControllerInfo,
sizeof(UsbControllerInfo),
&UsbBandInfo,
sizeof(USB_BANDWIDTH_INFO),
&dwBytes,
NULL);
trying to call a process function using fastcall convention from my program, but got a crash everytime trying to. Have passed so much time on it and can't solve that... need some help please...
Here's all needed informations and my trying:
The picture shows the instruction context after a breakpoint when the function's program is running...
And here's my code source:
typedef void (__fastcall * MyFoo)(void * client,DWORD trash, DWORD ConstantD, DWORD objBattid, DWORD zeroParam, DWORD thousParam, float fVal,DWORD targetID);
MyFoo launchMe;
DWORD getProcessBaseAdress(DWORD ProcessID);
char *flyffServer = "insanity flyff\0";
HWND neuzWindow = NULL;
DWORD neuzProcessID = NULL;
DWORD neuzRamAdress = NULL;
HANDLE neuzHandle = NULL;
DWORD clientAdr = NULL;
int main(){
neuzWindow = FindWindowA(0,flyffServer);
//--------------------------------------
if(neuzWindow){
GetWindowThreadProcessId(neuzWindow,&neuzProcessID);
if(neuzProcessID){
neuzHandle = OpenProcess(PROCESS_ALL_ACCESS,false,neuzProcessID);
if(neuzHandle){
neuzRamAdress = getProcessBaseAdress(neuzProcessID); // Extracting Neuz's base address
if(neuzRamAdress){
launchMe = (MyFoo)((DWORD)neuzRamAdress + 0x5C400);
clientAdr = (DWORD)neuzRamAdress + 0x8D0DC0;
printf("Instruction: 0x%08X\n",launchMe);
printf("Client ADR: 0x%08X\n",clientAdr);
for(;;Sleep(100)){
//------------ init params ------------
void * client = (void*)clientAdr;
DWORD trashDX = (DWORD)0x0000000B;
DWORD msge = (DWORD)0x0000001D;
DWORD selectedBattID = 0x04D4A929;
DWORD zeroParam = (DWORD) 0x00000000;
DWORD milleParam = 0x00010000;
float speedAtt = 0.07f;
DWORD targetID = 0x0089B964;
printf("0x%08X\n0x%08X\n0x%08X\n0x%08X\n0x%08X\n0x%08X\n%f\n0x%08X\n",
client,
trashDX,
msge,
selectedBattID,
zeroParam,
thousParam,
speedAtt,
targetID
);
launchMe(client,trashDX,msge,selectedBattID,zeroParam,milleParam,speedAtt,targetID); // -> Error
scanf("%d",&trashDX); // for blocking the program
return 0;
}
}
else printf("Unable to access to Neuz's Ram Adress\n");
}
else printf("Unable to obtain neuz's handle\n");
}
else printf("Unable to detect neuz's process ID\n");
}
else printf("Unable to detect neuz's window\n");
return 0;
}
DWORD getProcessBaseAdress(DWORD ProcessID){
HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID);
MODULEENTRY32 me32;
me32.dwSize = sizeof(MODULEENTRY32);
Module32First(hModuleSnap,&me32);
return (DWORD) me32.modBaseAddr;
}
Thanks in advance :) ...
As said IInspectable in his comment, the problem came from accessing virtual space of another process.
Checking Windows memory management and DLL injection have solved the problem for me ... maybe anyone would face that in the futur.
I'm trying to get the RVA of specific functions in kernel32.dll so I can use the RVA as an offset from the base address of kernel32.dll in a specified process to get the VA of the functions I need to inject my dll. I already wasn't able to find LoadLibrary but I did find LoadLibraryExA and used that instead for my dll injector however I now can't find GetProcAddress which I was going to use to locate the VA of functions in my ThreadProc function. So if I can't find it that means I'm going to have to calculate and store the VA of every function I need and put it into a structure to pass to the LPVOID lpParam parameter of ThreadProc which isn't ideal.
Here's all related functions:
void* GetFileImage(char path[])
{
HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);//Get a handle to the dll with read rights
if(hFile == INVALID_HANDLE_VALUE){printf("Error getting file handle: %d", (int)GetLastError());return NULL;} //Check whether or not CreateFile succeeded
HANDLE file_map = CreateFileMapping(hFile, NULL, PAGE_READONLY|SEC_IMAGE, 0, 0, "KernelMap"); //Create file map
if(file_map == INVALID_HANDLE_VALUE){printf("Error mapping file: %d", (int)GetLastError());return NULL;} //Did it succeed
LPVOID file_image = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 0); //Map it into the virtual address space of my program
if(file_image == 0){printf("Error getting mapped view: %d", (int)GetLastError());return NULL;} //Did it succeed
return file_image; //return the base address of the image
}
DWORD RVAddress(char* image, const char* proc_name)
{
DWORD address = 0xFFFFFFFF;
PIMAGE_DOS_HEADER pDos_hdr = (PIMAGE_DOS_HEADER)image; //Get dos header
PIMAGE_NT_HEADERS pNt_hdr = (PIMAGE_NT_HEADERS)(image+pDos_hdr->e_lfanew); //Get PE header by using the offset in dos header + the base address of the file image
IMAGE_OPTIONAL_HEADER opt_hdr = pNt_hdr->OptionalHeader; //Get the optional header
IMAGE_DATA_DIRECTORY exp_entry = opt_hdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
PIMAGE_EXPORT_DIRECTORY pExp_dir = (PIMAGE_EXPORT_DIRECTORY)(image+exp_entry.VirtualAddress); //Get a pointer to the export directory
void** func_table = (void**)(image+pExp_dir->AddressOfFunctions); //Get an array of pointers to the functions
WORD* ord_table = (WORD*)(image+pExp_dir->AddressOfNameOrdinals); //Get an array of ordinals
BYTE** name_table = (BYTE**)(image+pExp_dir->AddressOfNames); //Get an array of function names
for(int i=0;i<pExp_dir->NumberOfNames;i++) //until i is 1 less than how many names there are to iterate through elements
{
printf("%s ", (BYTE*)image+(DWORD)(intptr_t)name_table[i]); //print the name of each function iterated through, I went back and read through these names and didn't see GetProcAddress anywhere
if(strcmp(proc_name, (const char*)(BYTE*)image+(DWORD)(intptr_t)name_table[i]) == 0) //Is it the function we're looking for?
{
address = (DWORD)(intptr_t)func_table[ord_table[i]];//If so convert the address of the function into a DWORD(hexadecimal)
system("CLS"); //Clear the screen
return address; //return the address of the function
}
}
return (DWORD)0; //Other wise return 0
}
DWORD GetRemoteFunctionAddress(DWORD dwPid, char* kernel_path, char* function_name)
{
HANDLE hSnapshot = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
me32.dwSize = sizeof(MODULEENTRY32);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE|TH32CS_SNAPMODULE32, dwPid); //Get a snapshot of all the modules in the program(64 and 32 bit, 32 since kernel is 32)
if(hSnapshot == INVALID_HANDLE_VALUE){printf("Snapshot failed");return 0;} //Snapshot not created
if(!(Module32First(hSnapshot, &me32))) //Don't care about it because it will be the exe of the process
{
printf("Mod32First failed");
return 0;
}
while(Module32Next(hSnapshot, &me32)) //Iterate through until...
{
if(me32.szModule == "kernel32.dll"||me32.szModule == "KERNEL32.DLL") //we find kernel32.dll
{
CloseHandle(hSnapshot);
break;
}
}
printf("\nBase address: 0x%08X\n", (DWORD)(intptr_t)me32.modBaseAddr); //Used this for CheatEngine
DWORD RVA = (DWORD_PTR)RVAddress((char*)GetFileImage(kernel_path), function_name); //Get the relative virtual address of the function
DWORD Load = (DWORD_PTR)me32.modBaseAddr+(DWORD_PTR)RVA; //Add the base address of kernel32.dll and the RVA of the function to get a DWORD representation of the address of the function in the remote process
return Load; //return the address of the function in the remote process
}
Any help would be much appreciated.
if(me32.szModule == "kernel32.dll"||me32.szModule == "KERNEL32.DLL")
You can't use == on char arrays, you have to use stricmp
Instead of all this you can just use:
GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "LoadLibraryA")
This will give you the absolute address at runtime
I want to get Drive Letter and Name.
I used "DeviceIoControl" and "IOCTL_DISK_GET_DRIVE_LAYOUT_EX" for this reason. I am using Microsoft Visual C++ ultimate Edition.
#define wszDrive L"\\\\.\\PhysicalDrive0"
BOOL GetDriveParition(LPWSTR wszPath, DRIVE_LAYOUT_INFORMATION_EX *pdg)
{
HANDLE hDevice = INVALID_HANDLE_VALUE; // handle to the drive to be examined
BOOL bResult = FALSE; // results flag
DWORD junk = 0; // discard results
hDevice = CreateFileW(wszPath, // drive to open
0, // no access to the drive
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
return (FALSE);
}
bResult = DeviceIoControl(hDevice, // device to be queried
IOCTL_DISK_GET_DRIVE_LAYOUT_EX, // operation to perform
NULL,
0, // no input buffer
pdg,
sizeof(*pdg), // output buffer
&junk, // # bytes returned
NULL); // synchronous I/O
CloseHandle(hDevice);
return (bResult);
}
int wmain(int argc, wchar_t *argv[])
{
DRIVE_LAYOUT_INFORMATION_EX pdg; // disk drive partition structure
BOOL bResult = FALSE; // generic results flag
bResult = GetDriveParition (wszDrive, &pdg);
if (bResult)
{
wprintf(L"Drive path = %ws\n", wszDrive);
wprintf(L"Partition Style = %I64d\n", pdg.PartitionStyle);
wprintf(L"Partition Count = %ld\n", pdg.PartitionCount);
}
else
{
wprintf (L"GetDrivePartition failed. Error %ld.\n", GetLastError ());
}
getch();
}
but when I was performing I confronted to an error which was "error 122".
I think that you meant to say error code 122 rather than 22. That error is ERROR_INSUFFICIENT_BUFFER. As documented, you will need to allocate a larger buffer and try again.
The point here is that the struct is a variable sized struct. You need to allocate dynamic memory large enough to hold information for all the partitions.
Something like this should get you going in the right direction:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define wszDrive L"\\\\.\\PhysicalDrive0"
BOOL GetDriveParition(LPWSTR wszPath, DRIVE_LAYOUT_INFORMATION_EX *pdg, size_t size)
{
HANDLE hDevice = INVALID_HANDLE_VALUE; // handle to the drive to be examined
BOOL bResult = FALSE; // results flag
DWORD junk = 0; // discard results
hDevice = CreateFileW(wszPath, // drive to open
0, // no access to the drive
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
return (FALSE);
}
bResult = DeviceIoControl(hDevice, // device to be queried
IOCTL_DISK_GET_DRIVE_LAYOUT_EX, // operation to perform
NULL,
0, // no input buffer
pdg,
size, // output buffer
&junk, // # bytes returned
NULL); // synchronous I/O
CloseHandle(hDevice);
return (bResult);
}
int wmain(int argc, wchar_t *argv[])
{
DRIVE_LAYOUT_INFORMATION_EX* pdg; // disk drive partition structure
BOOL bResult = FALSE; // generic results flag
size_t size = sizeof(DRIVE_LAYOUT_INFORMATION_EX) + 10*sizeof(PARTITION_INFORMATION_EX);
pdg = (DRIVE_LAYOUT_INFORMATION_EX*) malloc(size);
bResult = GetDriveParition (wszDrive, pdg, size);
if (bResult)
{
wprintf(L"Drive path = %ws\n", wszDrive);
wprintf(L"Partition Style = %I64d\n", pdg->PartitionStyle);
wprintf(L"Partition Count = %ld\n", pdg->PartitionCount);
}
else
{
wprintf (L"GetDrivePartition failed. Error %ld.\n", GetLastError ());
}
free(pdg);
}
I've cast the return value of malloc since you state that you are using a C++ compiler.
(Sorry for my crazy English)
I want to get all the text in Rich Edit with RTF format, not plain text to a variable. I tried SendMessage() with EM_STREAMOUT to write directly Rich Edit to file, but I can't save the content to specific variables, for example LPWSTR. Please remember, only Win API, not MFC. Thanks for you help!
You can pass your variable to the EM_STREAMOUT callback so it can be updated as needed, eg:
DWORD CALLBACK EditStreamOutCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
std::stringstream *rtf = (std::stringstream*) dwCookie;
rtf->write((char*)pbBuff, cb);
*pcb = cb;
return 0;
}
.
std::stringstream rtf;
EDITSTREAM es = {0};
es.dwCookie = (DWORD_PTR) &rtf;
es.pfnCallback = &EditStreamOutCallback;
SendMessage(hRichEditWnd, EM_STREAMOUT, SF_RTF, (LPARAM)&es);
// use rtf.str() as needed...
Update: to load RTF data into the RichEdit control, use EM_STREAMIN, eg:
DWORD CALLBACK EditStreamInCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
std::stringstream *rtf = (std::stringstream*) dwCookie;
*pcb = rtf->readsome((char*)pbBuff, cb);
return 0;
}
.
std::stringstream rtf("...");
EDITSTREAM es = {0};
es.dwCookie = (DWORD_PTR) &rtf;
es.pfnCallback = &EditStreamInCallback;
SendMessage(hRichEditWnd, EM_STREAMIN, SF_RTF, (LPARAM)&es);
Using the EM_STREAMOUT message is the answer.
Here is the simplest example that I can construct to demonstrate. This will save the contents of a rich edit control to a file.
DWORD CALLBACK EditStreamOutCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
HANDLE hFile = (HANDLE)dwCookie;
DWORD NumberOfBytesWritten;
if (!WriteFile(hFile, pbBuff, cb, &NumberOfBytesWritten, NULL))
{
//handle errors
return 1;
// or perhaps return GetLastError();
}
*pcb = NumberOfBytesWritten;
return 0;
}
void SaveRichTextToFile(HWND hWnd, LPCWSTR filename)
{
HANDLE hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
//handle errors
}
EDITSTREAM es = { 0 };
es.dwCookie = (DWORD_PTR) hFile;
es.pfnCallback = EditStreamOutCallback;
SendMessage(hWnd, EM_STREAMOUT, SF_RTF, (LPARAM)&es);
CloseHandle(hFile);
if (es.dwError != 0)
{
//handle errors
}
}