ReadProcessMemory invalid handle - python-3.x

I'm trying to read a value from another process using Python.
I came across this answer, though it doesn't seem to work.
My code:
from ctypes import *
from ctypes.wintypes import *
OpenProcess = windll.kernel32.OpenProcess
ReadProcessMemory = windll.kernel32.ReadProcessMemory
CloseHandle = windll.kernel32.CloseHandle
PROCESS_ALL_ACCESS = 0x1F0FFF
pid = 4580
address = 0x04782FF8
buffer = c_uint()
bufferSize = sizeof(buffer)
bytesRead = c_ulong(0)
processHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
if ReadProcessMemory(processHandle, address, buffer, bufferSize, byref(bytesRead)):
print("Success:", buffer)
else:
print("Failed.")
CloseHandle(processHandle)
GetLastError() seems to return 6, which means the handle is invalid.
Though, OpenProcess() returns a nonzero value, and GetLastError() doesn't show anything about it.
I've tried editing the first argument passed in OpenProcess() (which I made 0x0010), but still no results.

The process ID was dec, and not hex, which broke a few things.
I also had to replace c_uint() with create_string_buffer(4) for the buffer.
Seems to work fine now!

Related

vkCreateWin32SurfaceKHR not writing to surface

I'm trying to get a simple test of Vulkan working. I've been following the LunarG tutorials, but ran into the problem that vkCreateWin32SurfaceKHR seems to do nothing. Namely, surface is not being written to. The function vkCreateWin32SurfaceKHR returns 0, so it isn't reporting a failure. Any help is appreciated.
// create window
sdlWindow = SDL_CreateWindow(APP_SHORT_NAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0);
struct SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(sdlWindow, &wmInfo);
hWnd = wmInfo.info.win.window;
hInstance = GetModuleHandle(NULL);
// create a surface attached to the window
VkWin32SurfaceCreateInfoKHR surface_info = {};
surface_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
surface_info.pNext = NULL;
surface_info.hinstance = hInstance;
surface_info.hwnd = hWnd;
sanity(!vkCreateWin32SurfaceKHR(inst, &surface_info, NULL, &surface));
Sascha Willems correctly identified that I was not requesting the extensions necessary to create a surface. I changed my code to request extensions as shown below, and now everything works as expected.
// create an instance
vector<char*> enabledInstanceExtensions;
enabledInstanceExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
enabledInstanceExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
#ifdef VALIDATE_VULKAN
enabledInstanceExtensions.push_back("VK_EXT_debug_report");
#endif
vector<char*> enabledInstanceLayers;
#ifdef VALIDATE_VULKAN
enabledInstanceLayers.push_back("VK_LAYER_LUNARG_standard_validation");
#endif
VkInstanceCreateInfo inst_info = {};
inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
inst_info.pNext = NULL;
inst_info.flags = 0;
inst_info.pApplicationInfo = &app_info;
inst_info.enabledExtensionCount = (uint32_t)enabledInstanceExtensions.size();
inst_info.ppEnabledExtensionNames = enabledInstanceExtensions.data();
inst_info.enabledLayerCount = (uint32_t)enabledInstanceLayers.size();
inst_info.ppEnabledLayerNames = enabledInstanceLayers.data();
sanity(!vkCreateInstance(&inst_info, NULL, &instance));
Beside what Joe added in his answer, I will also say that the call to vkCreateWin32SurfaceKHR() if provided invalid arguments does not fail and return VK_SUCCESS. I`m not sure about other platforms if this is still the case.
When I say invalid arguments I am referring to the two most important hinstance and hwnd of the vulkan structure VkWin32SurfaceCreateInfoKHR.
So pay close attention to those two arguments, it tricked me few times.
Not sure tough why is returning VK_SUCCESS while providing invalid arguments, there may be some internal related things that god know why.

issue with copy_from_user in kernel

I'm trying to use this function to copy a buffer from the user to one in kernel.
both buffers were allocated. I'm using while in case not all the bytes were copied on the first try. but for some reason, nothing is copied and the program is stuck in the while loop.
what can be the reasons for that?
void my_copy_from_user(const char* source_buff, char* dest_buff, int size_to_copy){
int not_copied = size_to_copy
int left = size_to_copy;
while( not_copied ){
not_copied = copy_from_user(dest_buff, source_buff, left);
dest_buff += (left - not_copied);
source_buff += (left - not_copied);
left = not_copied;
}
}
It is possible that it is legitimately failing for reasons that you cannot recover from.
Please look at: http://lxr.free-electrons.com/source/arch/x86/lib/usercopy_32.c#L681
unsigned long _copy_from_user(void *to, const void __user *from, unsigned n)
{
if (access_ok(VERIFY_READ, from, n))
n = __copy_from_user(to, from, n);
else
memset(to, 0, n);
return n;
}
This is the underlying implementation for copy_from_user for Linux on x86 processors. It first checks access_ok. If access is not allowed, it will fail and return with n (the number of bytes you requested to copy) immediately. This would cause an infinite loop.
Two points:
I do not think you should invoke copy_from_user in a loop like that. If it fails to copy in kernel mode, there is a reason why. This is a different beast from read() functions when reading from sockets, etc, where you are encouraged to read() in a loop.
Are you sure that you are passing in the correct dest_buff to copy_from_user?
Tips:
Printk all the values and see what's happening. Is left being changed or not? It is likely not.

How can I get the value of a registry key in c++ without an access violation?

Hey I'm new to C++ and I am trying to find out if a specified registry index exists. I have to check multiple locations due to the possibility of the software being run on a 64bit machine and being under the WOW6432Node key instead of the usual position. When RegQueryValueExA (using visual c++ 6.0 on xp so I can't use a newer function) is run it should return a Boolean of true if the key exists, (I'll deal with getting the value of the key later). However on run it generates access violation 0xc00005. Any ideas whats gone wrong?
bool FindAndRemoveUninstall(string path){
bool result;
result = RegQueryValueExA(HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ABC"), NULL, NULL, NULL, (unsigned long *)MAX_PATH);
if (result= ERROR_SUCCESS){
cout <<" is a 32 bit program\n";
//path= Value in key
}
result = RegQueryValueEx(HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ABC"), NULL, NULL, NULL, (unsigned long *)MAX_PATH);
if (result= ERROR_SUCCESS){
cout << " is 64 bit program\n";
//path= Value in key
}
return true;
}
You have multiple problems.
The last parameter to RegQueryValueExA is documented as
lpcbData [in, out, optional]
A pointer to a variable that specifies the size of the buffer pointed to by the lpData parameter,
But you are not passing a pointer to a variable. You are passing (unsigned long *)MAX_PATH, which is a garbage pointer. When the operating system tries to store the result into the pointer, it takes an access violation. You need to pass a pointer to a variable, like the documentation says.
The next problem is that you are calling the A function (explicit ANSI) but using the TEXT macro (adaptive character set). Make up your mind which model you are using (ANSI or adaptive) and choose one model or the other. Let's assume you explicit ANSI.
The next problem is that you didn't specify an output buffer, so you don't actually retrieve the path.
Another problem is that the RegQueryValueExA function does not return a bool; it returns an error code.
Yet another problem is that your if test contains an assignment, so it does not actually test anything.
Another problem is that you didn't specify a way for the function to return the path to the caller. Let's assume you want the result to be returned in the path parameter.
Yet another problem is that you have the 32-bit and 64-bit cases reversed.
Also, you are using '\n' instead of std::endl.
The eight problem is that your function returns true even if it didn't do anything.
And the ninth problem is that the function says FindAndRemove, and it finds, but doesn't remove.
bool FindUninstall(string& path){ // parameter passed by reference, fix function name
LONG result; // change variable type
char buffer[MAX_PATH]; // provide an output buffer
DWORD bufferSize = MAX_PATH; // and a variable to specify the buffer size / receive the data size
result = RegQueryValueExA(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ABC", NULL, NULL, (LPBYTE)buffer, &bufferSize); // remove TEXT macro, pass the buffer and buffer size
if (result== ERROR_SUCCESS){ // fix comparison
cout <<" is a 64 bit program" << std::endl; // fix message
path = buffer;
return true; // stop once we have an answer
}
buffersize = MAX_PATH; // reset for next query
result = RegQueryValueEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ABC", NULL, NULL, (LPBYTE)buffer, &bufferSize); // remove TEXT macro, pass the buffer and buffer size
if (result== ERROR_SUCCESS){ // fix comparison
cout << " is 32 bit program" << std::endl; // fix message
path = buffer;
return true; // stop once we have an answer
}
return false; // nothing found
}
Since you are new to C++, I would recommend that you get some experience with C++ doing simpler projects before diving into more complicated things like this.

Making a WCHAR null terminated

I've got this
WCHAR fileName[1];
as a returned value from a function (it's a sys 32 function so I am not able to change the returned type). I need to make fileName to be null terminated so I am trying to append '\0' to it, but nothing seems to work.
Once I get a null terminated WCHAR I will need to pass it to another sys 32 function so I need it to stay as WCHAR.
Could anyone give me any suggestion please?
================================================
Thanks a lot for all your help. Looks like my problem has to do with more than missing a null terminated string.
//This works:
WCHAR szPath1[50] = L"\\Invalid2.txt.txt";
dwResult = FbwfCommitFile(szDrive, pPath1); //Successful
//This does not:
std::wstring l_fn(L"\\");
//Because Cache_detail->fileName is \Invalid2.txt.txt and I need two
l_fn.append(Cache_detail->fileName);
l_fn += L""; //To ensure null terminated
fprintf(output, "l_fn.c_str: %ls\n", l_fn.c_str()); //Prints "\\Invalid2.txt.txt"
iCommitErr = FbwfCommitFile(L"C:", (WCHAR*)l_fn.c_str()); //Unsuccessful
//Then when I do a comparison on these two they are unequal.
int iCompareResult = l_fn.compare(pPath1); // returns -1
So I need to figure out how these two ended up to be different.
Thanks a lot!
Since you mentioned fbwffindfirst/fbwffindnext in a comment, you're talking about the file name returned in FbwfCacheDetail. So from the fileNameLength field you know length for the fileName in bytes. The length of fileName in WCHAR's is fileNameLength/sizeof(WCHAR). So the simple answer is that you can set
fileName[fileNameLength/sizeof(WCHAR)+1] = L'\0'
Now this is important you need to make sure that the buffer you send for the cacheDetail parameter into fbwffindfirst/fbwffindnext is sizeof(WCHAR) bytes larger than you need, the above code snippet may run outside the bounds of your array. So for the size parameter of fbwffindfirst/fbwffindnext pass in the buffer size - sizeof(WCHAR).
For example this:
// *** Caution: This example has no error checking, nor has it been compiled ***
ULONG error;
ULONG size;
FbwfCacheDetail *cacheDetail;
// Make an intial call to find how big of a buffer we need
size = 0;
error = FbwfFindFirst(volume, NULL, &size);
if (error == ERROR_MORE_DATA) {
// Allocate more than we need
cacheDetail = (FbwfCacheDetail*)malloc(size + sizeof(WCHAR));
// Don't tell this call about the bytes we allocated for the null
error = FbwfFindFirstFile(volume, cacheDetail, &size);
cacheDetail->fileName[cacheDetail->fileNameLength/sizeof(WCHAR)+1] = L"\0";
// ... Use fileName as a null terminated string ...
// Have to free what we allocate
free(cacheDetail);
}
Of course you'll have to change a good bit to fit in with your code (plus you'll have to call fbwffindnext as well)
If you are interested in why the FbwfCacheDetail struct ends with a WCHAR[1] field, see this blog post. It's a pretty common pattern in the Windows API.
Use L'\0', not '\0'.
As each character of a WCHAR is 16-bit in size, you should perhaps append \0\0 to it, but I'm not sure if this works. By the way, WCHAR fileName[1]; is creating a WCHAR of length 1, perhaps you want something like WCHAR fileName[1024]; instead.
WCHAR fileName[1]; is an array of 1 character, so if null terminated it will contain only the null terminator L'\0'.
Which API function are you calling?
Edited
The fileName member in FbwfCacheDetail is only 1 character which is a common technique used when the length of the array is unknown and the member is the last member in a structure. As you have likely already noticed if your allocated buffer is is only sizeof (FbwfCacheDetail) long then FbwfFindFirst returns ERROR_NOT_ENOUGH_MEMORY.
So if I understand, what you desire to do it output the non NULL terminated filename using fprintf. This can be done as follows
fprintf (outputfile, L"%.*ls", cacheDetail.fileNameLength, cacheDetail.fileName);
This will print only the first fileNameLength characters of fileName.
An alternative approach would be to append a NULL terminator to the end of fileName. First you'll need to ensure that the buffer is long enough which can be done by subtracting sizeof (WCHAR) from the size argument you pass to FbwfFindFirst. So if you allocate a buffer of 1000 bytes, you'll pass 998 to FbwfFindFirst, reserving the last two bytes in the buffer for your own use. Then to add the NULL terminator and output the file name use
cacheDetail.fileName[cacheDetail.fileNameLength] = L'\0';
fprintf (outputfile, L"%ls", cacheDetail.fileName);

Linux Terminal Problem with Non-Canonical Terminal I/O app

I have a small app written in C designed to run on Linux. Part of the app accepts user-input from the keyboard, and it uses non-canonical terminal mode so that it can respond to each keystroke.
The section of code that accepts input is a simple function which is called repeatedly in a loop:
char get_input()
{
char c = 0;
int res = read(input_terminal, &c, 1);
if (res == 0) return 0;
if (res == -1) { /* snip error handling */ }
return c;
}
This reads a single character from the terminal. If no input is received within a certain timeframe, (specified by the c_cc[VTIME] value in the termios struct), read() returns 0, and get_input() is called again.
This all works great, except I recently discovered that if you run this app in a terminal window, and then close the terminal window without terminating the app, the app does not exit but launches into a CPU intensive infinite loop, where read() continuously returns 0 without waiting.
So how can I have the app exit gracefully if it is run from a terminal window, and then the terminal window is closed? The problem is that read() never returns -1, so the error condition is indistinguishable from a normal case where read() returns 0. So the only solution I see is to put in a timer, and assume there is an error condition if read returns 0 faster than the time specified in c_cc[V_TIME]. But that solution seems hacky at best, and I was hoping there is some better way to handle this situation.
Any ideas or suggestions?
Are you catching signals and resetting things before your program exits? I think SIGHUP is the one you need to focus on. Possibly set a switch in the signal handler, if switch is on when returning from read() clean up and exit.
You should handle timeout with select rather than with terminal settings. If the terminal is configured without timeout, then it will never return 0 on a read except on EOF.
Select gives you the timeout, and read gives you the 0 on close.
rc = select(...);
if(rc > 0) {
char c = 0;
int res = read(input_terminal, &c, 1);
if (res == 0) {/* EOF detected, close your app ?*/}
if (res == -1) { /* snip error handling */ }
return c;
} else if (rc == 0) {
/* timeout */
return 0;
} else {
/* handle select error */
}
Read should return 0 on EOF. I.e. it will read nothing successfully.
Your function will return 0 in that case!
What you should do is compare value returned from read with 1 and process exception.
I.e. you asked for one, but did you get one?
You will probably want to handle errno==EINTR if -1 is returned.
char get_input()
{
char c = 0;
int res = read(input_terminal, &c, 1);
switch(res) {
case 1:
return c;
case 0:
/* EOF */
case -1:
/* error */
}
}

Resources