Not enough memory WinAPI - winapi

I would like some help because i am lock on this problem during few days.
I looking for on google and try to understand what is dwMaximumSizeHigh and dwMaximumSizeLow.
I read some documentation about this parameters but i don't really understand what is it.
I wrote a code
#include <windows.h>
#include <stdio.h>
void MappingOpen(PCWSTR lpFileName)
{
HANDLE hFile = CreateFileW(lpFileName, FILE_GENERIC_READ, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
FILE_STANDARD_INFO fsi;
if (GetFileInformationByHandleEx(hFile, FileStandardInfo, &fsi, sizeof(fsi)))
{
HANDLE hSection = CreateFileMappingW(hFile, 0, PAGE_READONLY, 0, 1, 0);
if (hSection == NULL)
{
DWORD error_code = GetLastError();
printf("The error code is %lu",error_code);
}
else
{
printf("The create file mapping work ");
CloseHandle(hSection);
}
}
CloseHandle(hFile);
}else
{
printf("Cannot be open");
}
}
Even if i add 0 to dwMaximumSizeHigh and 0 dwMaximumSizeHigh i got another error (ERROR_FILE_INVALID).
Thanks you very much

dwMaximumSizeHigh and dwMaxsimumSizeLow are parts of the same Value ...
its a 64-Bit value in 32-Bit parts.. the High and Low-parts..
| 32bit (high) | 32bit (low) |
Maybe that helps to understand.
it is explained here:
https://learn.microsoft.com/en-gb/windows/win32/api/memoryapi/nf-memoryapi-createfilemappingw?redirectedfrom=MSDN (4th and 5th Parameter)

Related

Why I get ERROR_INVALID_FUNCTION ( winapi error 1 ), when I execute GetFileSizeEx?

I would like to get file size of my external hard disk.
handle = CreateFile(L"\\\\.\\PhysicalDrive5", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL , NULL);
if (handle == INVALID_HANDLE_VALUE) {
std::cout<<"ERROR!"<<std::endl;
return -1;
}
LARGE_INTEGER size;
if(!GetFileSizeEx(handle, &size))
{
auto lastError = GetLastError();
std::cout<<"Last Error: "<<lastError<<std::endl;
CloseHandle(handle);
return -1;
}
When I execute my application with admin rights ( it is necessary for CreateFile ), I get Last Error: 1.
OS: Windows 10,
Compiler: MinGW 7.3.0
AFAIK, GetFileSizeEx() is the wrong function to use for a "physical disk" object.
Use DeviceIoControl() with IOCTL_DISK_GET_DRIVE_GEOMETRY instead.

How to get Audio Formats supported by physical device (WinAPI, Windows)

I have an audio device (a USB microphone) and I want to find out what audio formats it supports natively (bit depth & sample rate), on OS X there is a nice kAudioStreamPropertyAvailablePhysicalFormats Core Audio property, but I fail to find something similar on Windows.
I know there is this question Windows Core Audio Api get all supported formats on capture device but
The answer is bad... and I'm not limited with windows Core Audio APIs, I need any way.
Windows itself somehow knows it, so most likely there should be a way, via IOCTL for example, DirectShow or WMI or something else.
Probably there is a way to Spy on Windows to find out what it uses to enumerate the formats, but I don't know how to do this.
Hokay, here is some sample code for you. The information is out there, scattered around the web, but you have to search for it. Google the functions I call below and some of the weirdo manifest constants to learn more. Code written in Notepad, might not compile.
The code below queries the default input / output device. To get device_id's for all the devices installed on any particular system, call waveInGetNumDevs or waveOutGetNumDevs and count up from 0.
#define INITGUID
#include "Ks.h"
#include "KsMedia.h"
#include "mmdeviceapi.h"
// Open a query handle for the default input or output device
// Call Closehandle when done.
static HANDLE QueryOpen (bool input)
{
DWORD device_id, device_status;
DWORD err = (input) ?
waveInMessage ((HWAVEIN) (INT_PTR) WAVE_MAPPER,
DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR) &device_id, (DWORD_PTR) &device_status) :
waveOutMessage ((HWAVEOUT) (INT_PTR) WAVE_MAPPER,
DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR) &device_id, (DWORD_PTR) &device_status);
if (err)
return INVALID_HANDLE_VALUE;
DWORD devicePathSize;
DWORD mm_result = (input) ?
waveInMessage ((HWAVEIN) (INT_PTR) device_id, DRV_QUERYDEVICEINTERFACESIZE,
(DWORD_PTR) &devicePathSize, 0) :
waveOutMessage ((HWAVEOUT) (INT_PTR) device_id, DRV_QUERYDEVICEINTERFACESIZE,
(DWORD_PTR) &devicePathSize, 0);
if (mm_result != 0)
return INVALID_HANDLE_VALUE;
/* apparently DRV_QUERYDEVICEINTERFACE returns a unicode interface path, although this is undocumented */
WCHAR *devicePath = (WCHAR *) malloc (devicePathSize);
mm_result = (input) ?
waveInMessage ((HWAVEIN) (INT_PTR) device_id, DRV_QUERYDEVICEINTERFACE,
(DWORD_PTR) devicePath, devicePathSize) :
waveOutMessage ((HWAVEOUT) (INT_PTR) device_id, DRV_QUERYDEVICEINTERFACE,
(DWORD_PTR) devicePath, devicePathSize);
HANDLE result = (mm_result == 0) ? CreateFileW (devicePath, FILE_SHARE_READ | FILE_SHARE_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL) : INVALID_HANDLE_VALUE;
free (devicePath);
return result;
}
// Interrogate the default input / output device (demo code)
void InterrogateDefaultDevice (bool input)
{
HANDLE hQuery = QueryOpen (input);
if (hQuery == INVALID_HANDLE_VALUE)
return;
int pin_count = GetKSFilterPinCount (hQuery);
for (int pinId = 0; pinId < pin_count; ++pinId)
{
KSPIN_COMMUNICATION communication = GetKSFilterPinPropertyCommunication (hQuery, pinId);
KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow (h, pinId);
if ((communication == KSPIN_COMMUNICATION_SINK || communication == KSPIN_COMMUNICATION_BOTH) &&
(KSFilterPinPropertyIdentifiersInclude (hQuery, pinId, KSPROPERTY_PIN_INTERFACES,
&KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING) ||
KSFilterPinPropertyIdentifiersInclude (hQuery, pinId, KSPROPERTY_PIN_INTERFACES,
&KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING)) &&
KSFilterPinPropertyIdentifiersInclude (hQuery, pinId, KSPROPERTY_PIN_MEDIUMS,
&KSMEDIUMSETID_Standard, KSMEDIUM_STANDARD_DEVIO))
{
KSMULTIPLE_ITEM *item = NULL;
if (WdmGetPinPropertyMulti (hQuery, pinId, KSPROPERTY_PIN_DATARANGES, &item))
{
KSDATARANGE_AUDIO *dr = (KSDATARANGE_AUDIO *) (item + 1);
for (ULONG i = 0; i < item->Count; ++i )
{
printf ("%ul - %ul Hz (%ul - %ul bits per sample, upto %ul channels)\n",
dr->MinimumSampleFrequency, dr->MaximumSampleFrequency,
dr->MinimumBitsPerSample, dr->MaximumBitsPerSample, dr->MaximumChannels);
dr = (KSDATARANGE_AUDIO *) ((BYTE *) dr + dr->DataRange.FormatSize);
}
free (item);
}
}
}
CloseHandle (hQuery);
}

How to read a file using readfile on Winapi

I'm learning how to use in Winapi
And I'm trying to read a file from My Computer
But for some reason it doesn't work ...
HANDLE hFile;
//PVOID First_Bytes[2048];
char First_Bytes[2048];
DWORD dbr = 0;
hFile = CreateFile(L"d:\\My-File",GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL , NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("Error %x", GetLastError());
return 1;
}
if (ReadFile(hFile, &First_Bytes, 512, &dbr, NULL) == 0) {
printf("ReadFile error: %x", GetLastError());
return 1;
}
printf("%s", First_Bytes);
CloseHandle(hFile);
The console doesn't print anything.
What am I doing wrong?
I edited the code and add that errors checks.
But still consul does not print anything
The logical conclusion is that the first byte in your file is a zero. You treat the buffer as a null-terminated string, and so nothing is printed.
Do note that there is no guarantee that your buffer is null terminated so you potentially have undefined behaviour.

C CreateFileMapping error 5 Access Denied ALWAYS

I would like to ask for help with WINAPI function CreateFileMapping (), which returns constantly NULL. After GetLastError() I get 5 - "ERROR_ACCESS_DENIED 5 (0x5) Access is denied". The file has been created after CreateFile with no problem, but following CreateFileMapping never has bee succesful.
int MapDestFile(LPCWSTR fPath)
{
hDestFile = CreateFile(
fPath,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hSourceFile == NULL)
{
printf("%d\n", GetLastError());
}
hDestMapFile = CreateFileMapping(
hDestFile,
NULL,
PAGE_READWRITE,
0,
10,
NULL
);
if (hDestMapFile == NULL)
{
// here always tell error number 5
printf("%d\n", GetLastError());
}
lpMapAddressDestFile = MapViewOfFile(
hDestMapFile,
FILE_MAP_WRITE,
0,
0,
0);
if (lpMapAddressDestFile == NULL)
{
printf("%d\n", GetLastError());
}
return 1;
}
I would appreciate any suggestions.
Thanks
You need to create the file with GENERIC_WRITE | GENERIC_READ to match PAGE_READWRITE.
That seems self-evident when you think about it. How can you have memory that you can read from backed by a file that you cannot read from? The documentation does call this out explicitly in any case:
PAGE_READWRITE
The file handle that the hFile parameter specifies must be created with the GENERIC_READ and GENERIC_WRITE access rights.
On top of that your error checking on the call to CreateFile is wrong. Take another look at the documentations. Error is indicated by a return value of INVALID_FILE_HANDLE.

CreateRemoteThread returning ERROR_ACCESS_DENIED - Windows 7 DLL Injection

I'm trying to write a program that uses CreateRemoteThread to inject a dll.
The problem is that CreateRemoteThread is refusing to work. GetLastError() is returning 5 which is ERROR_ACCESS_DENIED. I cant figure why!
I am working from this video http://www.youtube.com/watch?v=H3O3hmXkt1I .
#include <iostream>
#include <direct.h>
#include <Windows.h>
#include <TlHelp32.h>
using namespace std;
char* GetCurrentDir()
{
char* szRet = (char*)malloc(MAX_PATH);
_getcwd(szRet, MAX_PATH);
return szRet;
}
LPCTSTR SzToLPCTSTR(char* szString)
{
LPTSTR lpszRet;
size_t size = strlen(szString)+1;
lpszRet = (LPTSTR)malloc(MAX_PATH);
mbstowcs_s(NULL, lpszRet, size, szString, _TRUNCATE);
return lpszRet;
}
void WaitForProcessToAppear(LPCTSTR lpcszProc, DWORD dwDelay)
{
HANDLE hSnap;
PROCESSENTRY32 peProc;
BOOL bAppeared = FALSE;
while(!bAppeared)
{
if((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
peProc.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hSnap, &peProc))
while(Process32Next(hSnap, &peProc) && !bAppeared)
if(!lstrcmp(lpcszProc, peProc.szExeFile))
bAppeared = TRUE;
}
CloseHandle(hSnap);
Sleep(dwDelay);
}
}
DWORD GetProcessIdByName(LPCTSTR lpcszProc)
{
HANDLE hSnap;
PROCESSENTRY32 peProc;
DWORD dwRet = -1;
if((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
peProc.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hSnap, &peProc))
while(Process32Next(hSnap, &peProc))
if(!lstrcmp(lpcszProc, peProc.szExeFile))
dwRet = peProc.th32ProcessID;
}
CloseHandle(hSnap);
return dwRet;
}
BOOL InjectDll(DWORD dwPid, char* szDllPath)
{
DWORD dwMemSize;
HANDLE hProc;
LPVOID lpRemoteMem, lpLoadLibrary;
BOOL bRet = FALSE;
if((hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid)) != NULL)
{
dwMemSize = strlen(szDllPath);
if((lpRemoteMem = VirtualAllocEx(hProc, NULL, dwMemSize, MEM_COMMIT, PAGE_READWRITE)) != NULL)
if(WriteProcessMemory(hProc, lpRemoteMem, szDllPath, dwMemSize, NULL))
{
lpLoadLibrary = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
if(CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibrary, lpRemoteMem, 0, NULL) != NULL)
{
bRet = TRUE;
}
cout << GetLastError();
}
}
CloseHandle(hProc);
return bRet;
}
int main()
{
char szProc[MAX_PATH], szDll[MAX_PATH];
char* szDllPath = (char*)malloc(MAX_PATH);
LPTSTR lpszProc = NULL;
for(;;)
{
cout << "Process: ";
cin >> szProc;
cout << "DLL: ";
cin >> szDll;
szDllPath = GetCurrentDir();
strcat_s(szDllPath, MAX_PATH, "\\");
strcat_s(szDllPath, MAX_PATH, szDll);
cout << "Waiting for process.. ." << szDllPath << " " << szDll << endl;
WaitForProcessToAppear(SzToLPCTSTR(szProc), 100);
if(InjectDll(GetProcessIdByName(SzToLPCTSTR(szProc)), szDllPath))
cout << "Injection Succeeded!" << endl;
else
cout << "Injection Failed!" << endl;
cout << "\n";
}
return 0;
After a fair amount of googling I cant find a reason why this should not be working.
Does CreateRemoteThread not work under Windows 7 ?
If it does, have I made any obvious mistakes ?
The reason it fails is because your code is 32-bit and your target process is 64-bit.
It doesn't matter how many privileges you own. Windows won't let that happen.
I had the same problem. Either you spawn a system 32-bit exe and inject that or port your code to 64-bit (which means it won't work on 32-bit systems).
EDIT
A long time ago, I found a nice way of injecting code into and from any processor mode-target. It involves dynamically switching the processor mode to that of (any)the target. Dubbed "heaven's gate". To do this you have to use inline assembly. So basically, you can have both 64-bit and 32-bit code in a 32-bit exe, detect if the machine is 64-bit, then jump into 64-bit mode and run the 64-bit code. You'd then walk the imports to find ntdll and load 64-bit kernel.dll and other libraries.
Link: https://www.google.com/search?q=heaven's+gate+windows
Immediate problems I see are that you are not getting the access token which should be done as so:
HANDLE hToken;
TOKEN_PRIVILEGES tp;
HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() );
tp.PrivilegeCount = 1;
LookupPrivilegeValue( NULL, _T("SeDebugPrivilege"), &tp.Privileges[0].Luid );
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
OpenProcessToken( hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken );
AdjustTokenPrivileges( hToken, FALSE, &tp, NULL, NULL, NULL );
CloseHandle( hToken );
I don't have time to look through all your code right now, but here is something I ripped out of one of my previous projects:
// returns open process handle
HANDLE InjectDLL( DWORD dwPID, LPCWSTR szDLLPath, HMODULE* lphInjected ) {
int cszDLL;
LPVOID lpAddress;
HMODULE hMod;
HANDLE hThread;
HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD |
PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION |
PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwPID );
if( hProcess == NULL ) {
return NULL;
}
cszDLL = ( wcslen( szDLLPath ) + 1 ) * sizeof( WCHAR );
// Injection
lpAddress = VirtualAllocEx( hProcess, NULL, cszDLL, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if( lpAddress == NULL ) {
return NULL;
}
WriteProcessMemory( hProcess, lpAddress, szDLLPath, cszDLL, NULL );
hMod = GetModuleHandle( L"kernel32.dll" );
if( hMod == NULL ) {
return NULL;
}
hThread = CreateRemoteThread( hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)( GetProcAddress( hMod,
"LoadLibraryW" ) ), lpAddress, 0, NULL );
// Locate address our payload was loaded
if( hThread != 0 ) {
WaitForSingleObject( hThread, INFINITE );
GetExitCodeThread( hThread, ( LPDWORD )lphInjected );
VirtualFreeEx( hProcess, lpAddress, 0, MEM_RELEASE );
CloseHandle( hThread );
}
return hThread != 0 ? hProcess : NULL;
}
See if it helps. Will look again later.
OK, your code is likely to fail in windows 7 and Vista because of "Protected processes", that is, processes which only can be manipulated by other Protected Processes, like explorer.exe, etc... In Windows 7 x32 there is a way: since you are able to load unsigned drivers,... well, you are done (search for Alex Ionescu in google). In Windows 7 x64, though, you can't (duh!)
"The fourth parameter of the CreateRemoteThread() is an address. In your case it is the LoadLibraryA address. However, in windows 7, Kernel32.dll/LoadLibraryA base address will various in different process;"
Well, that's not remotely true, because DLLs are shared at the same addresses in every process, despite ASLR. DLLs can be rebased, though, but you can call GetProcAddress before calling CreateRemoteThread, so it is very unlikely that the DLL will get rebased meanwhile.
I think CreateRemoteThread() dll injection method can not work in windows 7.
The fourth parameter of the CreateRemoteThread() is an address. In your case it is the LoadLibraryA address. However, in windows 7, Kernel32.dll/LoadLibraryA base address will various in different process; Therefore, the CreateRemoteThread() will not work since the address is not what u expected. This is my own opinion, hope it will help. :)
CreateRemoteThread function does not work in Win Vista/7. You have to use NTCreateThread function,which is undocumented, for that.
TLDR : your code is okey , change the Visual Studio debug/compile target to x64.
I've faced the same problem before, your code is Okey, The problem is , the Visual Studio(or any sane person) execute its programs in x86 mode (32bit) by default, because it would be nice to compile your program in a way that runs in both x86 or x64 architecture but not in the process injection scenario! because of its system calls.
In the code injection case, you should change the build and debug setting of the VS to compile/debug for x64 processor in properties of your project in the project explorer,
or if you cross compiling your program, you should use x64 compiler.
If you are looking for global process injection method, there was a method called Heaven’s Gate or The 0x33 Segment Selector, which was used in Vawtrak banking malware.
You could see this link about Heaven’s Gate method, which says:
In other words, it gives one the ability to create “naked” 64-bit
code, which will be able to run covertly, including issuing system
calls, without the majority of products able to intercept and/or
introspect its execution

Resources