EnumProcessModules returns 998 - windows

I am trying to run this code in Rust (2021 version):
let module_list_size: PDWORD = ptr::null_mut();
res = winapi::um::psapi::EnumProcessModules(remote_handle, ptr::null_mut(), 0, module_list_size);
Res is well defined and the handle is valid (I checked it before) yet I'm still getting windows error 998 which is invalid access (I'm running this code as admin).
(The function exists and I imported it correctly).
Thank you in advance!

The last parameter is a pointer that indicates where to write how many bytes are needed to store all the module handles. But you're pointing at null, so it'll fail with an invalid access error when it tries to give you the result.
Instead, make a DWORD variable and pass a pointer to it:
let module_list_size: DWORD = 0;
res = winapi::um::psapi::EnumProcessModules(remote_handle, ptr::null_mut(), 0, &mut module_list_size);

Related

Why function GetLastError returns 2?

Today, I decided to practice by creating a simple program that creates a new file. But I got a problem that the file is not being created. How to solve this?
Firstly, I'm importing the required crate, then creating the err() function for printing errors after creating the file, if they will.
Secondly, I'm creating a function to_u16(), because LPCWSTR type needs *const u16.
Thirdly, I'm calling the CreateFileW() function for creating file.rs, and passing all necessary arguments (according to this and this).
createfile.rs
use winapi::shared::minwindef::DWORD;
use winapi::um::winnt;
use std::ffi::CString;
use winapi::um::errhandlingapi;
use winapi::ctypes::*;
use winapi::um::minwinbase::*;
use winapi::um::fileapi;
use std::io;
fn err(){//print the last error
unsafe{
let xui =errhandlingapi::GetLastError();
print!("{:?}",xui) ;// 2
}
}
fn to_u16(s: &str) ->*const u16 {
let c_str = CString::new(s).unwrap();
c_str.as_ptr() as *const u16
}
fn main() {
unsafe{
let name:winnt::LPCWSTR =to_u16("file.rs") ; //lpFileName
let acces:DWORD = winnt::GENERIC_WRITE; //dwDesiredAccess
let share = winnt::FILE_SHARE_DELETE|winnt::FILE_SHARE_READ|winnt::FILE_SHARE_WRITE;//dwShareMode
let security = 0 as *mut SECURITY_ATTRIBUTES ;//lpSecurityAttributes
let disposition = fileapi::OPEN_EXISTING; //dwCreationDisposition
let atr = winnt::FILE_ATTRIBUTE_NORMAL;//dwFlagsAndAttributes
let handle = 0 as *mut c_void;//hTemplateFile
fileapi::CreateFileW(name,acces,share,security,disposition,atr,handle);
err();
}
}
cargo.toml
[package]
name = "createfile"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
kernel32-sys = "0.2.2"
winapi = "0.3.9"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = ["winuser", "fileapi", "errhandlingapi"] }
Error 2 is ERROR_FILE_NOT_FOUND.
You say you want to create a new file, but you are setting the disposition argument to OPEN_EXISTING, so if file.rs does not already exist then CreateFileW() will fail with this error.
Try using CREATE_ALWAYS, CREATE_NEW, or OPEN_ALWAYS, per the documentation:
[in] dwCreationDisposition
An action to take on a file or device that exists or does not exist.
For devices other than files, this parameter is usually set to OPEN_EXISTING.
For more information, see the Remarks section.
This parameter must be one of the following values, which cannot be combined:
Value
Meaning
CREATE_ALWAYS2
Creates a new file, always.If the specified file exists and is writable, the function overwrites the file, the function succeeds, and last-error code is set to ERROR_ALREADY_EXISTS (183).If the specified file does not exist and is a valid path, a new file is created, the function succeeds, and the last-error code is set to zero.For more information, see the Remarks section of this topic.
CREATE_NEW1
Creates a new file, only if it does not already exist.If the specified file exists, the function fails and the last-error code is set to ERROR_FILE_EXISTS (80).If the specified file does not exist and is a valid path to a writable location, a new file is created.
OPEN_ALWAYS4
Opens a file, always.If the specified file exists, the function succeeds and the last-error code is set to ERROR_ALREADY_EXISTS (183).If the specified file does not exist and is a valid path to a writable location, the function creates a file and the last-error code is set to zero.
OPEN_EXISTING3
Opens a file or device, only if it exists.If the specified file or device does not exist, the function fails and the last-error code is set to ERROR_FILE_NOT_FOUND (2).For more information about devices, see the Remarks section.
TRUNCATE_EXISTING5
Opens a file and truncates it so that its size is zero bytes, only if it exists.If the specified file does not exist, the function fails and the last-error code is set to ERROR_FILE_NOT_FOUND (2).The calling process must open the file with the GENERIC_WRITE bit set as part of the dwDesiredAccess parameter.

GetProcessIoCounters errors out with code 998 [duplicate]

This question already has answers here:
Error 998 (Invalid access to memory location) for when calling GetPointerFrameTouchInfo [duplicate]
(1 answer)
WriteConsole access violation in function call but not from main()
(2 answers)
VirtualProtectEx fails with ERROR_NOACCESS (error code 998)
(1 answer)
Invalid access to memory location with ReadFile
(2 answers)
Closed 2 years ago.
I am trying to get the PIO_COUNTERS for the current process by doing:
DWORD pid = GetCurrentProcessId();
auto handle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
PIO_COUNTERS ctr = nullptr;
if (!GetProcessIoCounters(handle, ctr)) {
DWORD dw = GetLastError();
}
I get value of dw as 998 which is "Invalid access of the memory location". This essentially means that the handle I am using does not have enough privileges, but this is the flag with the max access control privileges. I also tried using the handle given by "GetCurrentProcess" (which is different from the one I got above) but that also gave error code 998 after passing it to GetProcessIoCounters.
Can somebody please help me out here?
Thanks in advance.
The 'invalid access' error is occurring because you are passing a nullptr value for the address of the IO_COUNTERS structure into which to write the information you are retrieving. You need to give the address of an actual structure for this:
DWORD pid = GetCurrentProcessId();
auto handle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
IO_COUNTERS info;
if (!GetProcessIoCounters(handle, &info)) { // Pass the address of your structure!
DWORD dw = GetLastError();
}
You can then access the various members of the info structure to get the information you want.

behavior different when run outside of visual studio

I was surprised about the behavior of the following code:
if(RegQueryValueEx(....)!=ERROR_SUCCESS){
...
}
when it was run from visual studio it didn't enter this if block, because the key did exist. when ran outside of the visual studio environment it evaluated true and hence entered the block, even though the queried key existed. After some testing i found out that when i first save it to a variable it runs always fine. With the following code:
HKEY hSoftwareKey,hAppKey;
DWORD dwLength;
int iStatus=1;
char szBuffer[MAX_PATH];
if(iStatus&&RegOpenKeyA(HKEY_CURRENT_USER,"Software",&hSoftwareKey)!=ERROR_SUCCESS)
iStatus = 0;
if(iStatus&&RegCreateKeyA(hSoftwareKey,"Amine",&hAppKey)!=ERROR_SUCCESS){
iStatus = 0;
}
ZeroMemory(szBuffer,MAX_PATH);
LONG lRet;
lRet = RegQueryValueExA(hAppKey,"One",0,0,reinterpret_cast<LPBYTE>(szBuffer),&dwLength);
Does this bevavior have anything to do with the __stdcall/WINAPI calling convention? If so could somebody please explain why
You need to initialize dwLength to MAX_PATH before calling RegQueryValueEx(), otherwise it's value is undefined.
from MSDN RegQueryValueEx:
lpcbData is a pointer to a variable that specifies the size of the buffer pointed to by the lpData parameter, in bytes. When the function returns, this variable contains the size of the data copied to lpData

OpenFile API returns error while opening file having name length above 127 characters

I am trying to open file which reside in a directory.
It is always return error code 13 if length is above or equal 127.
char name[200]="E:\\suri_temp\\abc85\\tool\\src1111\\turi_temp\\abc85\\tool\\src1111\\puri_temp\\abc85\\tool\\src\\nuri_temp\\abc85\\to\\abcd.tmp\\suri1111.log";
int len = strlen(name); //len=127
HFILE handle ;
WORD temp;
OFSTRUCT ofstruct;
if( (handle = OpenFile(name, &ofstruct, OF_EXIST)) == HFILE_ERROR )
{
temp = GetLastError(); // if length 127 or above(it comes here temp = 13)
}
else
_lclose(handle); // if length is below 127 it comes here
Anyone faced this problem?
You are just finding out the hard way what's well documented in the MSDN article for OpenFile:
Note This function has limited capabilities and is not recommended. For new application development, use the CreateFile function.
The OFSTRUCT structure contains a path string member with a length that is limited to OFS_MAXPATHNAME characters, which is 128 characters. Because of this, you cannot use the OpenFile function to open a file with a path length that exceeds 128 characters. The CreateFile function does not have this path length limitation.
As indicated, use CreateFile() instead.
Using
OpenFile(name, &ofstruct, OF_EXIST))
is ok in debug mode, but fails in release mode.
Use
if(GetFileAttributes("filename") == -1)

WriteProcessMemory/ReadProcessMemory fail

I tried using both ReadProcessMemory() and WriteProcessMemory() in my application,but in both cases I get one result - Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
Has anyone met that error code before? I'm using Vista SP2,I tried to run as admistrator,but I till get that erorcode.
Make sure you call VirtualProtectEx to set the correct protection level on the memory you want to read/write.
After thinking about it, it's probably not the problem since most memory has read access enabled, but to set the protection level do something like this (in C++)
(no error checking and just using a random memory address, but you should get the idea)
char buffer[256];
DWORD oldProtect = 0;
DWORD numRead = 0;
VirtualProtectEx( hProc, (LPVOID)0x77810F34, 256, PAGE_EXECUTE_READWRITE, &oldProtect );
ReadProcessMemory( hProc, (LPVOID)0x77810F34, buffer, 256, &numRead );
VirtualProtectEx( hProc, (LPVOID)0x77810F34, 256, oldProtect, NULL ); //restore the original protection when you're done

Resources